github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/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/v3"
    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  // JujuLogContext is the Context for the JujuLogCommand
    19  //
    20  //go:generate go run go.uber.org/mock/mockgen -package mocks -destination mocks/juju-log_mock.go github.com/juju/juju/worker/uniter/runner/jujuc JujuLogContext
    21  type JujuLogContext interface {
    22  	UnitName() string
    23  	HookRelation() (ContextRelation, error)
    24  	GetLogger(module string) loggo.Logger
    25  }
    26  
    27  // JujuLogCommand implements the juju-log command.
    28  type JujuLogCommand struct {
    29  	cmd.CommandBase
    30  	ctx        JujuLogContext
    31  	Message    string
    32  	Debug      bool
    33  	Level      string
    34  	formatFlag string // deprecated
    35  }
    36  
    37  func NewJujuLogCommand(ctx Context) (cmd.Command, error) {
    38  	return &JujuLogCommand{ctx: ctx}, nil
    39  }
    40  
    41  func (c *JujuLogCommand) Info() *cmd.Info {
    42  	return jujucmd.Info(&cmd.Info{
    43  		Name:    "juju-log",
    44  		Args:    "<message>",
    45  		Purpose: "write a message to the juju log",
    46  	})
    47  }
    48  
    49  func (c *JujuLogCommand) SetFlags(f *gnuflag.FlagSet) {
    50  	f.BoolVar(&c.Debug, "debug", false, "log at debug level")
    51  	f.StringVar(&c.Level, "l", "INFO", "Send log message at the given level")
    52  	f.StringVar(&c.Level, "log-level", "INFO", "")
    53  	f.StringVar(&c.formatFlag, "format", "", "deprecated format flag")
    54  }
    55  
    56  func (c *JujuLogCommand) Init(args []string) error {
    57  	if args == nil {
    58  		return errors.New("no message specified")
    59  	}
    60  	c.Message = strings.Join(args, " ")
    61  	return nil
    62  }
    63  
    64  func (c *JujuLogCommand) Run(ctx *cmd.Context) error {
    65  	if c.formatFlag != "" {
    66  		fmt.Fprintf(ctx.Stderr, "--format flag deprecated for command %q", c.Info().Name)
    67  	}
    68  	logger := c.ctx.GetLogger(fmt.Sprintf("unit.%s.juju-log", c.ctx.UnitName()))
    69  
    70  	logLevel := loggo.INFO
    71  	if c.Debug {
    72  		logLevel = loggo.DEBUG
    73  	} else if c.Level != "" {
    74  		var ok bool
    75  		logLevel, ok = loggo.ParseLevel(c.Level)
    76  		if !ok {
    77  			logger.Warningf("Specified log level of %q is not valid", c.Level)
    78  			logLevel = loggo.INFO
    79  		}
    80  	}
    81  
    82  	prefix := ""
    83  	if r, err := c.ctx.HookRelation(); err == nil {
    84  		prefix = r.FakeId() + ": "
    85  	} else if errors.IsNotImplemented(err) {
    86  		// if the hook relation is not implemented, then we want to continue
    87  		// without a FakeId
    88  	} else if !errors.IsNotFound(err) {
    89  		return errors.Trace(err)
    90  	}
    91  
    92  	logger.Logf(logLevel, "%s%s", prefix, c.Message)
    93  	return nil
    94  }