-
Levente Pap authored
* Fix #355 Terminate GoShimmer without config file - `skip-config` flag to bypass check and supply values from cli * Remove empty line * Add some comments * change termination comment * lower case beginning of comments * Don't mount config file into docker container by default * Integration tests skip config file check * Add flags for logger config * Log at debug level for integration tests * Update hive.go to latest version * upgrade hive.go Signed-off-by:
Wolfgang Welz <welzwo@gmail.com> Co-authored-by:
Luca Moser <moser.luca@gmail.com> Co-authored-by:
jonastheis <mail@jonastheis.de> Co-authored-by:
Wolfgang Welz <welzwo@gmail.com>
Levente Pap authored* Fix #355 Terminate GoShimmer without config file - `skip-config` flag to bypass check and supply values from cli * Remove empty line * Add some comments * change termination comment * lower case beginning of comments * Don't mount config file into docker container by default * Integration tests skip config file check * Add flags for logger config * Log at debug level for integration tests * Update hive.go to latest version * upgrade hive.go Signed-off-by:
Wolfgang Welz <welzwo@gmail.com> Co-authored-by:
Luca Moser <moser.luca@gmail.com> Co-authored-by:
jonastheis <mail@jonastheis.de> Co-authored-by:
Wolfgang Welz <welzwo@gmail.com>
plugin.go 4.38 KiB
// Package remotelog is a plugin that enables log messages being sent via UDP to a central ELK stack for debugging.
// It is disabled by default and when enabled, additionally, logger.disableEvents=false in config.json needs to be set.
// The destination can be set via logger.remotelog.serverAddress.
// All events according to logger.level in config.json are sent.
package remotelog
import (
"encoding/hex"
"encoding/json"
"fmt"
"net"
"os"
"path/filepath"
"runtime"
"time"
"github.com/iotaledger/goshimmer/packages/shutdown"
"github.com/iotaledger/goshimmer/plugins/autopeering/local"
"github.com/iotaledger/goshimmer/plugins/banner"
"github.com/iotaledger/goshimmer/plugins/config"
"github.com/iotaledger/hive.go/daemon"
"github.com/iotaledger/hive.go/events"
"github.com/iotaledger/hive.go/logger"
"github.com/iotaledger/hive.go/node"
"github.com/iotaledger/hive.go/workerpool"
flag "github.com/spf13/pflag"
"gopkg.in/src-d/go-git.v4"
)
type logMessage struct {
Version string `json:"version"`
GitHead string `json:"gitHead,omitempty"`
GitBranch string `json:"gitBranch,omitempty"`
NodeID string `json:"nodeId"`
Level string `json:"level"`
Name string `json:"name"`
Msg string `json:"msg"`
Timestamp time.Time `json:"timestamp"`
}
const (
// CfgLoggerRemotelogServerAddress defines the config flag of the server address.
CfgLoggerRemotelogServerAddress = "logger.remotelog.serverAddress"
// CfgDisableEvents defines the config flag for disabling logger events.
CfgDisableEvents = "logger.disableEvents"
// PluginName is the name of the remote log plugin.
PluginName = "RemoteLog"
)
var (
// Plugin is the plugin instance of the remote plugin instance.
Plugin = node.NewPlugin(PluginName, node.Disabled, configure, run)
log *logger.Logger
conn net.Conn
myID string
myGitHead string
myGitBranch string
workerPool *workerpool.WorkerPool
)
func init() {
flag.String(CfgLoggerRemotelogServerAddress, "remotelog.goshimmer.iota.cafe:5213", "RemoteLog server address")
}
func configure(plugin *node.Plugin) {
log = logger.NewLogger(PluginName)
if config.Node.GetBool(CfgDisableEvents) {
log.Fatalf("%s in config.json needs to be false so that events can be captured!", CfgDisableEvents)
return
}
c, err := net.Dial("udp", config.Node.GetString(CfgLoggerRemotelogServerAddress))
if err != nil {
log.Fatalf("Could not create UDP socket to '%s'. %v", config.Node.GetString(CfgLoggerRemotelogServerAddress), err)
return
}
conn = c
if local.GetInstance() != nil {
myID = hex.EncodeToString(local.GetInstance().ID().Bytes())
}
getGitInfo()
workerPool = workerpool.New(func(task workerpool.Task) {
sendLogMsg(task.Param(0).(logger.Level), task.Param(1).(string), task.Param(2).(string))
task.Return(nil)
}, workerpool.WorkerCount(runtime.NumCPU()), workerpool.QueueSize(1000))
}
func run(plugin *node.Plugin) {
logEvent := events.NewClosure(func(level logger.Level, name string, msg string) {
workerPool.TrySubmit(level, name, msg)
})
daemon.BackgroundWorker(PluginName, func(shutdownSignal <-chan struct{}) {
logger.Events.AnyMsg.Attach(logEvent)
workerPool.Start()
<-shutdownSignal
log.Infof("Stopping %s ...", PluginName)
logger.Events.AnyMsg.Detach(logEvent)
workerPool.Stop()
log.Infof("Stopping %s ... done", PluginName)
}, shutdown.PriorityRemoteLog)
}
func sendLogMsg(level logger.Level, name string, msg string) {
m := logMessage{
banner.AppVersion,
myGitHead,
myGitBranch,
myID,
level.CapitalString(),
name,
msg,
time.Now(),
}
b, _ := json.Marshal(m)
fmt.Fprint(conn, string(b))
}
func getGitInfo() {
r, err := git.PlainOpen(getGitDir())
if err != nil {
log.Debug("Could not open Git repo.")
return
}
// extract git branch and head
if h, err := r.Head(); err == nil {
myGitBranch = h.Name().String()
myGitHead = h.Hash().String()
}
}
func getGitDir() string {
var gitDir string
// this is valid when running an executable, when using "go run" this is a temp path
if ex, err := os.Executable(); err == nil {
temp := filepath.Join(filepath.Dir(ex), ".git")
if _, err := os.Stat(temp); err == nil {
gitDir = temp
}
}
// when running "go run" from the same directory
if gitDir == "" {
if wd, err := os.Getwd(); err == nil {
temp := filepath.Join(wd, ".git")
if _, err := os.Stat(temp); err == nil {
gitDir = temp
}
}
}
return gitDir
}