github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/worker/uniter/runner/jujuc/juju-log.go (about) 1 // Copyright 2012, 2013 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package jujuc 5 6 import ( 7 "fmt" 8 "strings" 9 10 "github.com/juju/cmd" 11 "github.com/juju/errors" 12 "github.com/juju/gnuflag" 13 "github.com/juju/loggo" 14 15 jujucmd "github.com/juju/juju/cmd" 16 ) 17 18 // JujuLogCommandLogger provides a Logger interface for the juju-log command. 19 //go:generate mockgen -package jujuc -destination juju-log_mock_test.go github.com/juju/juju/worker/uniter/runner/jujuc JujuLogCommandLogger,JujuLogCommandLoggerFactory,JujuLogContext 20 type JujuLogCommandLogger interface { 21 Logf(level loggo.Level, message string, args ...interface{}) 22 Warningf(message string, args ...interface{}) 23 } 24 25 // JujuLogCommandLoggerFactory is used to create new loggers 26 // (stickupkid) We should derive this from the context itself. 27 type JujuLogCommandLoggerFactory interface { 28 GetLogger(name string) JujuLogCommandLogger 29 } 30 31 // JujuLogContext is the Context for the JujuLogCommand 32 type JujuLogContext interface { 33 UnitName() string 34 HookRelation() (ContextRelation, error) 35 } 36 37 // JujuLogCommand implements the juju-log command. 38 type JujuLogCommand struct { 39 cmd.CommandBase 40 ctx JujuLogContext 41 Message string 42 Debug bool 43 Level string 44 formatFlag string // deprecated 45 loggerFactory JujuLogCommandLoggerFactory 46 } 47 48 func NewJujuLogCommand(ctx Context) (cmd.Command, error) { 49 return &JujuLogCommand{ctx: ctx}, nil 50 } 51 52 func (c *JujuLogCommand) Info() *cmd.Info { 53 return jujucmd.Info(&cmd.Info{ 54 Name: "juju-log", 55 Args: "<message>", 56 Purpose: "write a message to the juju log", 57 }) 58 } 59 60 func (c *JujuLogCommand) SetFlags(f *gnuflag.FlagSet) { 61 f.BoolVar(&c.Debug, "debug", false, "log at debug level") 62 f.StringVar(&c.Level, "l", "INFO", "Send log message at the given level") 63 f.StringVar(&c.Level, "log-level", "INFO", "") 64 f.StringVar(&c.formatFlag, "format", "", "deprecated format flag") 65 } 66 67 func (c *JujuLogCommand) Init(args []string) error { 68 if args == nil { 69 return errors.New("no message specified") 70 } 71 c.Message = strings.Join(args, " ") 72 if c.loggerFactory == nil { 73 c.loggerFactory = loggoLoggerFactory{} 74 } 75 return nil 76 } 77 78 func (c *JujuLogCommand) Run(ctx *cmd.Context) error { 79 if c.formatFlag != "" { 80 fmt.Fprintf(ctx.Stderr, "--format flag deprecated for command %q", c.Info().Name) 81 } 82 logger := c.loggerFactory.GetLogger(fmt.Sprintf("unit.%s.juju-log", c.ctx.UnitName())) 83 84 logLevel := loggo.INFO 85 if c.Debug { 86 logLevel = loggo.DEBUG 87 } else if c.Level != "" { 88 var ok bool 89 logLevel, ok = loggo.ParseLevel(c.Level) 90 if !ok { 91 logger.Warningf("Specified log level of %q is not valid", c.Level) 92 logLevel = loggo.INFO 93 } 94 } 95 96 prefix := "" 97 if r, err := c.ctx.HookRelation(); err == nil { 98 prefix = r.FakeId() + ": " 99 } else if errors.IsNotImplemented(err) { 100 // if the hook relation is not implemented, then we want to continue 101 // without a FakeId 102 } else if !errors.IsNotFound(err) { 103 return errors.Trace(err) 104 } 105 106 logger.Logf(logLevel, "%s%s", prefix, c.Message) 107 return nil 108 } 109 110 type loggoLoggerFactory struct{} 111 112 func (l loggoLoggerFactory) GetLogger(name string) JujuLogCommandLogger { 113 return loggo.GetLogger(name) 114 }