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: "", 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. */ func (m *MultiLogger) AddStdLogger(identifier string) (err error) { var exists bool 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, } m.Loggers[identifier].Setup() m.Loggers[identifier].Info("logger initialized of type %T with prefix %v", m.Loggers[identifier], m.Loggers[identifier].GetPrefix()) 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, logfilePath string) (err error) { var exists bool var success bool var dirPath string if identifier == "" { identifier = uuid.New().String() } if _, exists = m.Loggers[identifier]; exists { err = ErrExistingLogger return } if exists, _ = paths.RealPathExists(&logfilePath); !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, }, Path: logfilePath, } m.Loggers[identifier].Setup() m.Loggers[identifier].Info("logger initialized of type %T with prefix %v", m.Loggers[identifier], m.Loggers[identifier].GetPrefix()) 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 }