github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/worker/logger/logger.go (about)

     1  // Copyright 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package logger
     5  
     6  import (
     7  	"github.com/juju/errors"
     8  	"github.com/juju/loggo"
     9  	"gopkg.in/juju/names.v2"
    10  	"gopkg.in/juju/worker.v1"
    11  
    12  	"github.com/juju/juju/core/watcher"
    13  )
    14  
    15  var log = loggo.GetLogger("juju.worker.logger")
    16  
    17  // LoggerAPI represents the API calls the logger makes.
    18  type LoggerAPI interface {
    19  	LoggingConfig(agentTag names.Tag) (string, error)
    20  	WatchLoggingConfig(agentTag names.Tag) (watcher.NotifyWatcher, error)
    21  }
    22  
    23  // Logger is responsible for updating the loggo configuration when the
    24  // environment watcher tells the agent that the value has changed.
    25  type Logger struct {
    26  	api            LoggerAPI
    27  	tag            names.Tag
    28  	updateCallback func(string) error
    29  	lastConfig     string
    30  	configOverride string
    31  }
    32  
    33  // NewLogger returns a worker.Worker that uses the notify watcher returned
    34  // from the setup.
    35  func NewLogger(api LoggerAPI, tag names.Tag, loggingOverride string, updateCallback func(string) error) (worker.Worker, error) {
    36  	logger := &Logger{
    37  		api:            api,
    38  		tag:            tag,
    39  		updateCallback: updateCallback,
    40  		lastConfig:     loggo.LoggerInfo(),
    41  		configOverride: loggingOverride,
    42  	}
    43  	log.Debugf("initial log config: %q", logger.lastConfig)
    44  
    45  	w, err := watcher.NewNotifyWorker(watcher.NotifyConfig{
    46  		Handler: logger,
    47  	})
    48  	if err != nil {
    49  		return nil, errors.Trace(err)
    50  	}
    51  	return w, nil
    52  }
    53  
    54  func (logger *Logger) setLogging() {
    55  	loggingConfig := ""
    56  
    57  	if logger.configOverride != "" {
    58  		log.Debugf("overriding logging config with override from agent.conf %q", logger.configOverride)
    59  		loggingConfig = logger.configOverride
    60  	} else {
    61  		modelLoggingConfig, err := logger.api.LoggingConfig(logger.tag)
    62  		if err != nil {
    63  			log.Errorf("%v", err)
    64  			return
    65  		}
    66  		loggingConfig = modelLoggingConfig
    67  	}
    68  
    69  	if loggingConfig != logger.lastConfig {
    70  		log.Debugf("reconfiguring logging from %q to %q", logger.lastConfig, loggingConfig)
    71  		loggo.DefaultContext().ResetLoggerLevels()
    72  		if err := loggo.ConfigureLoggers(loggingConfig); err != nil {
    73  			// This shouldn't occur as the loggingConfig should be
    74  			// validated by the original Config before it gets here.
    75  			log.Warningf("configure loggers failed: %v", err)
    76  			// Try to reset to what we had before
    77  			loggo.ConfigureLoggers(logger.lastConfig)
    78  			return
    79  		}
    80  		logger.lastConfig = loggingConfig
    81  		// Save the logging config in the agent.conf file.
    82  		if logger.updateCallback != nil {
    83  			err := logger.updateCallback(loggingConfig)
    84  			if err != nil {
    85  				log.Errorf("%v", err)
    86  			}
    87  		}
    88  	}
    89  }
    90  
    91  func (logger *Logger) SetUp() (watcher.NotifyWatcher, error) {
    92  	log.Debugf("logger setup")
    93  	// We need to set this up initially as the NotifyWorker sucks up the first
    94  	// event.
    95  	logger.setLogging()
    96  	return logger.api.WatchLoggingConfig(logger.tag)
    97  }
    98  
    99  func (logger *Logger) Handle(_ <-chan struct{}) error {
   100  	logger.setLogging()
   101  	return nil
   102  }
   103  
   104  func (logger *Logger) TearDown() error {
   105  	// Nothing to cleanup, only state is the watcher
   106  	return nil
   107  }