mirror of
https://github.com/superseriousbusiness/gotosocial
synced 2025-06-05 21:59:39 +02:00
Grand test fixup (#138)
* start fixing up tests * fix up tests + automate with drone * fiddle with linting * messing about with drone.yml * some more fiddling * hmmm * add cache * add vendor directory * verbose * ci updates * update some little things * update sig
This commit is contained in:
537
vendor/github.com/dsoprea/go-logging/log.go
generated
vendored
Normal file
537
vendor/github.com/dsoprea/go-logging/log.go
generated
vendored
Normal file
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user