diff options
author | 2024-08-02 11:46:41 +0000 | |
---|---|---|
committer | 2024-08-02 12:46:41 +0100 | |
commit | 94e87610c4ce9bbb1c614a61bab29c1422fed11b (patch) | |
tree | 2e06b8ce64212140e796f6077ba841b6cc678501 /vendor/github.com/dsoprea/go-logging/log.go | |
parent | [feature] Allow import of following and blocks via CSV (#3150) (diff) | |
download | gotosocial-94e87610c4ce9bbb1c614a61bab29c1422fed11b.tar.xz |
[chore] add back exif-terminator and use only for jpeg,png,webp (#3161)
* add back exif-terminator and use only for jpeg,png,webp
* fix arguments passed to terminateExif()
* pull in latest exif-terminator
* fix test
* update processed img
---------
Co-authored-by: tobi <tobi.smethurst@protonmail.com>
Diffstat (limited to 'vendor/github.com/dsoprea/go-logging/log.go')
-rw-r--r-- | vendor/github.com/dsoprea/go-logging/log.go | 537 |
1 files changed, 537 insertions, 0 deletions
diff --git a/vendor/github.com/dsoprea/go-logging/log.go b/vendor/github.com/dsoprea/go-logging/log.go new file mode 100644 index 000000000..84117a92e --- /dev/null +++ b/vendor/github.com/dsoprea/go-logging/log.go @@ -0,0 +1,537 @@ +package log + +import ( + "bytes" + e "errors" + "fmt" + "strings" + "sync" + + "text/template" + + "github.com/go-errors/errors" + "golang.org/x/net/context" +) + +// TODO(dustin): Finish symbol documentation + +// Config severity integers. +const ( + LevelDebug = iota + LevelInfo = iota + LevelWarning = iota + LevelError = iota +) + +// Config severity names. +const ( + LevelNameDebug = "debug" + LevelNameInfo = "info" + LevelNameWarning = "warning" + LevelNameError = "error" +) + +// Seveirty name->integer map. +var ( + LevelNameMap = map[string]int{ + LevelNameDebug: LevelDebug, + LevelNameInfo: LevelInfo, + LevelNameWarning: LevelWarning, + LevelNameError: LevelError, + } + + LevelNameMapR = map[int]string{ + LevelDebug: LevelNameDebug, + LevelInfo: LevelNameInfo, + LevelWarning: LevelNameWarning, + LevelError: LevelNameError, + } +) + +// Errors +var ( + ErrAdapterAlreadyRegistered = e.New("adapter already registered") + ErrFormatEmpty = e.New("format is empty") + ErrExcludeLevelNameInvalid = e.New("exclude bypass-level is invalid") + ErrNoAdapterConfigured = e.New("no default adapter configured") + ErrAdapterIsNil = e.New("adapter is nil") + ErrConfigurationNotLoaded = e.New("can not configure because configuration is not loaded") +) + +// Other +var ( + includeFilters = make(map[string]bool) + useIncludeFilters = false + excludeFilters = make(map[string]bool) + useExcludeFilters = false + + adapters = make(map[string]LogAdapter) + + // TODO(dustin): !! Finish implementing this. + excludeBypassLevel = -1 +) + +// Add global include filter. +func AddIncludeFilter(noun string) { + includeFilters[noun] = true + useIncludeFilters = true +} + +// Remove global include filter. +func RemoveIncludeFilter(noun string) { + delete(includeFilters, noun) + if len(includeFilters) == 0 { + useIncludeFilters = false + } +} + +// Add global exclude filter. +func AddExcludeFilter(noun string) { + excludeFilters[noun] = true + useExcludeFilters = true +} + +// Remove global exclude filter. +func RemoveExcludeFilter(noun string) { + delete(excludeFilters, noun) + if len(excludeFilters) == 0 { + useExcludeFilters = false + } +} + +func AddAdapter(name string, la LogAdapter) { + if _, found := adapters[name]; found == true { + Panic(ErrAdapterAlreadyRegistered) + } + + if la == nil { + Panic(ErrAdapterIsNil) + } + + adapters[name] = la + + if GetDefaultAdapterName() == "" { + SetDefaultAdapterName(name) + } +} + +func ClearAdapters() { + adapters = make(map[string]LogAdapter) + SetDefaultAdapterName("") +} + +type LogAdapter interface { + Debugf(lc *LogContext, message *string) error + Infof(lc *LogContext, message *string) error + Warningf(lc *LogContext, message *string) error + Errorf(lc *LogContext, message *string) error +} + +// TODO(dustin): !! Also populate whether we've bypassed an exception so that +// we can add a template macro to prefix an exclamation of +// some sort. +type MessageContext struct { + Level *string + Noun *string + Message *string + ExcludeBypass bool +} + +type LogContext struct { + Logger *Logger + Ctx context.Context +} + +type Logger struct { + isConfigured bool + an string + la LogAdapter + t *template.Template + systemLevel int + noun string +} + +func NewLoggerWithAdapterName(noun string, adapterName string) (l *Logger) { + l = &Logger{ + noun: noun, + an: adapterName, + } + + return l +} + +func NewLogger(noun string) (l *Logger) { + l = NewLoggerWithAdapterName(noun, "") + + return l +} + +func (l *Logger) Noun() string { + return l.noun +} + +func (l *Logger) Adapter() LogAdapter { + return l.la +} + +var ( + configureMutex sync.Mutex +) + +func (l *Logger) doConfigure(force bool) { + configureMutex.Lock() + defer configureMutex.Unlock() + + if l.isConfigured == true && force == false { + return + } + + if IsConfigurationLoaded() == false { + Panic(ErrConfigurationNotLoaded) + } + + if l.an == "" { + l.an = GetDefaultAdapterName() + } + + // If this is empty, then no specific adapter was given or no system + // default was configured (which implies that no adapters were registered). + // All of our logging will be skipped. + if l.an != "" { + la, found := adapters[l.an] + if found == false { + Panic(fmt.Errorf("adapter is not valid: %s", l.an)) + } + + l.la = la + } + + // Set the level. + + systemLevel, found := LevelNameMap[levelName] + if found == false { + Panic(fmt.Errorf("log-level not valid: [%s]", levelName)) + } + + l.systemLevel = systemLevel + + // Set the form. + + if format == "" { + Panic(ErrFormatEmpty) + } + + if t, err := template.New("logItem").Parse(format); err != nil { + Panic(err) + } else { + l.t = t + } + + l.isConfigured = true +} + +func (l *Logger) flattenMessage(lc *MessageContext, format *string, args []interface{}) (string, error) { + m := fmt.Sprintf(*format, args...) + + lc.Message = &m + + var b bytes.Buffer + if err := l.t.Execute(&b, *lc); err != nil { + return "", err + } + + return b.String(), nil +} + +func (l *Logger) allowMessage(noun string, level int) bool { + if _, found := includeFilters[noun]; found == true { + return true + } + + // If we didn't hit an include filter and we *had* include filters, filter + // it out. + if useIncludeFilters == true { + return false + } + + if _, found := excludeFilters[noun]; found == true { + return false + } + + return true +} + +func (l *Logger) makeLogContext(ctx context.Context) *LogContext { + return &LogContext{ + Ctx: ctx, + Logger: l, + } +} + +type LogMethod func(lc *LogContext, message *string) error + +func (l *Logger) log(ctx context.Context, level int, lm LogMethod, format string, args []interface{}) error { + if l.systemLevel > level { + return nil + } + + // Preempt the normal filter checks if we can unconditionally allow at a + // certain level and we've hit that level. + // + // Notice that this is only relevant if the system-log level is letting + // *anything* show logs at the level we came in with. + canExcludeBypass := level >= excludeBypassLevel && excludeBypassLevel != -1 + didExcludeBypass := false + + n := l.Noun() + + if l.allowMessage(n, level) == false { + if canExcludeBypass == false { + return nil + } else { + didExcludeBypass = true + } + } + + levelName, found := LevelNameMapR[level] + if found == false { + Panic(fmt.Errorf("level not valid: (%d)", level)) + } + + levelName = strings.ToUpper(levelName) + + lc := &MessageContext{ + Level: &levelName, + Noun: &n, + ExcludeBypass: didExcludeBypass, + } + + if s, err := l.flattenMessage(lc, &format, args); err != nil { + return err + } else { + lc := l.makeLogContext(ctx) + if err := lm(lc, &s); err != nil { + panic(err) + } + + return e.New(s) + } +} + +func (l *Logger) Debugf(ctx context.Context, format string, args ...interface{}) { + l.doConfigure(false) + + if l.la != nil { + l.log(ctx, LevelDebug, l.la.Debugf, format, args) + } +} + +func (l *Logger) Infof(ctx context.Context, format string, args ...interface{}) { + l.doConfigure(false) + + if l.la != nil { + l.log(ctx, LevelInfo, l.la.Infof, format, args) + } +} + +func (l *Logger) Warningf(ctx context.Context, format string, args ...interface{}) { + l.doConfigure(false) + + if l.la != nil { + l.log(ctx, LevelWarning, l.la.Warningf, format, args) + } +} + +func (l *Logger) mergeStack(err interface{}, format string, args []interface{}) (string, []interface{}) { + if format != "" { + format += "\n%s" + } else { + format = "%s" + } + + var stackified *errors.Error + stackified, ok := err.(*errors.Error) + if ok == false { + stackified = errors.Wrap(err, 2) + } + + args = append(args, stackified.ErrorStack()) + + return format, args +} + +func (l *Logger) Errorf(ctx context.Context, errRaw interface{}, format string, args ...interface{}) { + l.doConfigure(false) + + var err interface{} + + if errRaw != nil { + _, ok := errRaw.(*errors.Error) + if ok == true { + err = errRaw + } else { + err = errors.Wrap(errRaw, 1) + } + } + + if l.la != nil { + if errRaw != nil { + format, args = l.mergeStack(err, format, args) + } + + l.log(ctx, LevelError, l.la.Errorf, format, args) + } +} + +func (l *Logger) ErrorIff(ctx context.Context, errRaw interface{}, format string, args ...interface{}) { + if errRaw == nil { + return + } + + var err interface{} + + _, ok := errRaw.(*errors.Error) + if ok == true { + err = errRaw + } else { + err = errors.Wrap(errRaw, 1) + } + + l.Errorf(ctx, err, format, args...) +} + +func (l *Logger) Panicf(ctx context.Context, errRaw interface{}, format string, args ...interface{}) { + l.doConfigure(false) + + var err interface{} + + _, ok := errRaw.(*errors.Error) + if ok == true { + err = errRaw + } else { + err = errors.Wrap(errRaw, 1) + } + + if l.la != nil { + format, args = l.mergeStack(err, format, args) + err = l.log(ctx, LevelError, l.la.Errorf, format, args) + } + + Panic(err.(error)) +} + +func (l *Logger) PanicIff(ctx context.Context, errRaw interface{}, format string, args ...interface{}) { + if errRaw == nil { + return + } + + var err interface{} + + _, ok := errRaw.(*errors.Error) + if ok == true { + err = errRaw + } else { + err = errors.Wrap(errRaw, 1) + } + + l.Panicf(ctx, err.(error), format, args...) +} + +func Wrap(err interface{}) *errors.Error { + es, ok := err.(*errors.Error) + if ok == true { + return es + } else { + return errors.Wrap(err, 1) + } +} + +func Errorf(message string, args ...interface{}) *errors.Error { + err := fmt.Errorf(message, args...) + return errors.Wrap(err, 1) +} + +func Panic(err interface{}) { + _, ok := err.(*errors.Error) + if ok == true { + panic(err) + } else { + panic(errors.Wrap(err, 1)) + } +} + +func Panicf(message string, args ...interface{}) { + err := Errorf(message, args...) + Panic(err) +} + +func PanicIf(err interface{}) { + if err == nil { + return + } + + _, ok := err.(*errors.Error) + if ok == true { + panic(err) + } else { + panic(errors.Wrap(err, 1)) + } +} + +// Is checks if the left ("actual") error equals the right ("against") error. +// The right must be an unwrapped error (the kind that you'd initialize as a +// global variable). The left can be a wrapped or unwrapped error. +func Is(actual, against error) bool { + // If it's an unwrapped error. + if _, ok := actual.(*errors.Error); ok == false { + return actual == against + } + + return errors.Is(actual, against) +} + +// Print is a utility function to prevent the caller from having to import the +// third-party library. +func PrintError(err error) { + wrapped := Wrap(err) + fmt.Printf("Stack:\n\n%s\n", wrapped.ErrorStack()) +} + +// PrintErrorf is a utility function to prevent the caller from having to +// import the third-party library. +func PrintErrorf(err error, format string, args ...interface{}) { + wrapped := Wrap(err) + + fmt.Printf(format, args...) + fmt.Printf("\n") + fmt.Printf("Stack:\n\n%s\n", wrapped.ErrorStack()) +} + +func init() { + if format == "" { + format = defaultFormat + } + + if levelName == "" { + levelName = defaultLevelName + } + + if includeNouns != "" { + for _, noun := range strings.Split(includeNouns, ",") { + AddIncludeFilter(noun) + } + } + + if excludeNouns != "" { + for _, noun := range strings.Split(excludeNouns, ",") { + AddExcludeFilter(noun) + } + } + + if excludeBypassLevelName != "" { + var found bool + if excludeBypassLevel, found = LevelNameMap[excludeBypassLevelName]; found == false { + panic(ErrExcludeLevelNameInvalid) + } + } +} |