Skip to content

Commit

Permalink
Merge pull request #483 from victorcoder/plugin_log
Browse files Browse the repository at this point in the history
Log plugin fix and improvements
  • Loading branch information
Victor Castell authored Jan 16, 2019
2 parents 13de353 + b7b739c commit 723c1e8
Show file tree
Hide file tree
Showing 6 changed files with 158 additions and 4 deletions.
16 changes: 16 additions & 0 deletions builtin/bins/dkron-processor-log/log_output.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package main

import (
"fmt"
"os"

log "github.com/sirupsen/logrus"
"github.com/victorcoder/dkron/dkron"
)
Expand All @@ -13,6 +16,19 @@ func (l *LogOutput) Process(args *dkron.ExecutionProcessorArgs) dkron.Execution
log.SetFormatter(&log.TextFormatter{FullTimestamp: true})

l.parseConfig(args.Config)

// Output to stdout in case of success or to stderr on failure
if args.Execution.Success {
fmt.Printf("----- BEGIN OUTPUT job=%s execution=%s -----\n", args.Execution.JobName, args.Execution.Key())
fmt.Print(string(args.Execution.Output))
fmt.Printf("----- END OUTPUT -----\n")
} else {
fmt.Fprintf(os.Stderr, "----- BEGIN OUTPUT job=%s execution=%s -----\n", args.Execution.JobName, args.Execution.Key())
fmt.Fprint(os.Stderr, string(args.Execution.Output))
fmt.Fprintf(os.Stderr, "----- END OUTPUT -----\n")
}

// Override output if not forwarding
if !l.forward {
args.Execution.Output = []byte("Output in dkron log")
}
Expand Down
5 changes: 4 additions & 1 deletion cmd/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,10 @@ func init() {

func agentRun(args ...string) error {
// Make sure we clean up any managed plugins at the end of this
p := &Plugins{}
p := &Plugins{
LogLevel: config.LogLevel,
NodeName: config.NodeName,
}
if err := p.DiscoverPlugins(); err != nil {
log.Fatal(err)
}
Expand Down
8 changes: 7 additions & 1 deletion cmd/plugins.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cmd

import (
"os"
"os/exec"
"path"
"path/filepath"
Expand All @@ -16,6 +17,8 @@ import (
type Plugins struct {
Processors map[string]dkron.ExecutionProcessor
Executors map[string]dkron.Executor
LogLevel string
NodeName string
}

// Discover plugins located on disk
Expand Down Expand Up @@ -104,13 +107,16 @@ func getPluginName(file string) (string, bool) {
return name, true
}

func (Plugins) pluginFactory(path string, pluginType string) (interface{}, error) {
func (p *Plugins) pluginFactory(path string, pluginType string) (interface{}, error) {
// Build the plugin client configuration and init the plugin
var config plugin.ClientConfig
config.Cmd = exec.Command(path)
config.HandshakeConfig = dkplugin.Handshake
config.Managed = true
config.Plugins = dkplugin.PluginMap
config.SyncStdout = os.Stdout
config.SyncStderr = os.Stderr
config.Logger = &dkron.HCLogAdapter{Log: dkron.InitLogger(p.LogLevel, p.NodeName), Name: "plugins"}

switch pluginType {
case dkplugin.ProcessorPluginName:
Expand Down
127 changes: 127 additions & 0 deletions dkron/hclog_adapter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
package dkron

import (
"bytes"
golog "log"

"github.com/hashicorp/go-hclog"
"github.com/sirupsen/logrus"
)

// HCLogAdapter implements the hclog interface, and wraps it
// around a Logrus entry
type HCLogAdapter struct {
Log logrus.FieldLogger
Name string
}

// HCLog has one more level than we do. As such, we will never
// set trace level.
func (*HCLogAdapter) Trace(_ string, _ ...interface{}) {
return
}

func (a *HCLogAdapter) Debug(msg string, args ...interface{}) {
a.CreateEntry(args).Debug(msg)
}

func (a *HCLogAdapter) Info(msg string, args ...interface{}) {
a.CreateEntry(args).Info(msg)
}

func (a *HCLogAdapter) Warn(msg string, args ...interface{}) {
a.CreateEntry(args).Warn(msg)
}

func (a *HCLogAdapter) Error(msg string, args ...interface{}) {
a.CreateEntry(args).Error(msg)
}

func (a *HCLogAdapter) IsTrace() bool {
return false
}

func (a *HCLogAdapter) IsDebug() bool {
return a.shouldEmit(logrus.DebugLevel)
}

func (a *HCLogAdapter) IsInfo() bool {
return a.shouldEmit(logrus.InfoLevel)
}

func (a *HCLogAdapter) IsWarn() bool {
return a.shouldEmit(logrus.WarnLevel)
}

func (a *HCLogAdapter) IsError() bool {
return a.shouldEmit(logrus.ErrorLevel)
}

func (a *HCLogAdapter) SetLevel(hclog.Level) {
// interface definition says it is ok for this to be a noop if
// implementations don't need/want to support dynamic level changing, which
// we don't currently.
}

func (a *HCLogAdapter) With(args ...interface{}) hclog.Logger {
e := a.CreateEntry(args)
return &HCLogAdapter{Log: e}
}

func (a *HCLogAdapter) Named(name string) hclog.Logger {
var newName bytes.Buffer
if a.Name != "" {
newName.WriteString(a.Name)
newName.WriteString(".")
}
newName.WriteString(name)

return a.ResetNamed(newName.String())
}

func (a *HCLogAdapter) ResetNamed(name string) hclog.Logger {
fields := []interface{}{"subsystem_name", name}
e := a.CreateEntry(fields)
return &HCLogAdapter{Log: e, Name: name}
}

// StandardLogger is meant to return a stldib Logger type which wraps around
// hclog. It does this by providing an io.Writer and instantiating a new
// Logger. It then tries to interpret the log level by parsing the message.
//
// Since we are not using `hclog` in a generic way, and I cannot find any
// calls to this method from go-plugin, we will poorly support this method.
// Rather than pull in all of hclog writer parsing logic, pass it a Logrus
// writer, and hardcode the level to INFO.
//
// Apologies to those who find themselves here.
func (a *HCLogAdapter) StandardLogger(opts *hclog.StandardLoggerOptions) *golog.Logger {
entry := a.Log.WithFields(logrus.Fields{})
return golog.New(entry.WriterLevel(logrus.InfoLevel), "", 0)
}

func (a *HCLogAdapter) shouldEmit(level logrus.Level) bool {
currentLevel := a.Log.WithFields(logrus.Fields{}).Level
if currentLevel >= level {
return true
}

return false
}

func (a *HCLogAdapter) CreateEntry(args []interface{}) *logrus.Entry {
if len(args)%2 != 0 {
args = append(args, "<unknown>")
}

fields := make(logrus.Fields)
for i := 0; i < len(args); i = i + 2 {
k, ok := args[i].(string)
if !ok {
}
v := args[i+1]
fields[k] = v
}

return a.Log.WithFields(fields)
}
4 changes: 3 additions & 1 deletion dkron/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
var log = logrus.NewEntry(logrus.New())

// InitLogger creates the logger instance
func InitLogger(logLevel string, node string) {
func InitLogger(logLevel string, node string) logrus.FieldLogger {
formattedLogger := logrus.New()
formattedLogger.Formatter = &logrus.TextFormatter{FullTimestamp: true}

Expand All @@ -30,4 +30,6 @@ func InitLogger(logLevel string, node string) {
gin.DefaultWriter = ioutil.Discard
gin.SetMode(gin.ReleaseMode)
}

return log
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ require (
github.com/hashicorp/consul v1.0.0 // indirect
github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce // indirect
github.com/hashicorp/go-cleanhttp v0.0.0-20170211013415-3573b8b52aa7 // indirect
github.com/hashicorp/go-hclog v0.0.0-20181001195459-61d530d6c27f // indirect
github.com/hashicorp/go-hclog v0.0.0-20181001195459-61d530d6c27f
github.com/hashicorp/go-immutable-radix v0.0.0-20170725221215-8aac27015308 // indirect
github.com/hashicorp/go-msgpack v0.0.0-20150518234257-fa3f63826f7c // indirect
github.com/hashicorp/go-multierror v0.0.0-20170622060955-83588e72410a // indirect
Expand Down

0 comments on commit 723c1e8

Please sign in to comment.