package logging import ( `path` `github.com/google/uuid` `r00t2.io/sysutils/paths` ) /* GetMultiLogger returns a MultiLogger. If you call GetLogger, you will only get a single ("best") logger your system supports. If you want to log to multiple Logger destinations at once (or want to log to an explicit Logger type), use GetMultiLogger. Remember to add at least one Logger (e.g. MultiLogger.AddStdLogger), otherwise no entries will actually be logged. If you want to modify e.g. if debug is enabled for a specific Logger, reference the Logger directly (e.g. MultiLogger.Loggers[identifier].SetDebug(false)). */ func GetMultiLogger(enableDebug bool, prefix string) (m *MultiLogger) { m = &MultiLogger{ EnableDebug: enableDebug, Prefix: logPrefix, Loggers: make(map[string]Logger), } if prefix != "\x00" { m.Prefix = prefix } return } /* AddStdLogger adds a StdLogger to a MultiLogger. identifier is a string to use to identify the added StdLogger in MultiLogger.Loggers. If empty, one will be automatically generated. enableStdOut indicates that messages should be logged to STDOUT; it is *strongly encouraged* to set at least one of enableStdOut or enableStdErr to true. enableStdErr indicates that messages should be logged to STDERR; it is *strongly encouraged* to set at least one of enableStdErr or enableStdOut to true. See GetLogger's logConfigFlags argument and StdLogger.LogFlags for details on logFlags. */ func (m *MultiLogger) AddStdLogger(identifier string, enableStdOut, enableStdErr bool, logFlags int) (err error) { var exists bool var prefix string if identifier == "" { identifier = uuid.New().String() } if _, exists = m.Loggers[identifier]; exists { err = ErrExistingLogger return } m.Loggers[identifier] = &StdLogger{ Logger: nil, EnableDebug: m.EnableDebug, Prefix: m.Prefix, LogFlags: logFlags, EnableStdOut: enableStdOut, EnableStdErr: enableStdErr, } if err = m.Loggers[identifier].Setup(); err != nil { return } if prefix, err = m.Loggers[identifier].GetPrefix(); err != nil { return } m.Loggers[identifier].Debug("logger initialized of type %T with prefix %v", m.Loggers[identifier], prefix) return } /* AddFileLogger adds a FileLogger to a MultiLogger. identifier is a string to use to identify the added FileLogger in MultiLogger.Loggers. If empty, one will be automatically generated. logfilePath is a string for the path to the desired logfile. */ func (m *MultiLogger) AddFileLogger(identifier string, logFlags int, logfilePath string) (err error) { var exists bool var success bool var dirPath string var prefix string if identifier == "" { identifier = uuid.New().String() } if _, exists = m.Loggers[identifier]; exists { err = ErrExistingLogger return } if exists, err = paths.RealPathExists(&logfilePath); err != nil { return } else if !exists { if success, err = testOpen(logfilePath); err != nil { return } else if !success { dirPath = path.Dir(logfilePath) if err = paths.MakeDirIfNotExist(dirPath); err != nil { return } if success, err = testOpen(dirPath); err != nil { return } else if !success { err = ErrInvalidFile return } } } m.Loggers[identifier] = &FileLogger{ StdLogger: StdLogger{ Logger: nil, EnableDebug: m.EnableDebug, Prefix: m.Prefix, LogFlags: logFlags, }, Path: logfilePath, } if err = m.Loggers[identifier].Setup(); err != nil { return } if prefix, err = m.Loggers[identifier].GetPrefix(); err != nil { return } m.Loggers[identifier].Debug("logger initialized of type %T with prefix %v", m.Loggers[identifier], prefix) return } // RemoveLogger will let you remove a Logger from MultiLogger.Loggers. func (m *MultiLogger) RemoveLogger(identifier string) (err error) { var exists bool if _, exists = m.Loggers[identifier]; !exists { err = ErrNoEntry return } delete(m.Loggers, identifier) return }