mirror of
https://github.com/safing/portbase
synced 2025-09-01 18:19:57 +00:00
223 lines
4.8 KiB
Go
223 lines
4.8 KiB
Go
package log
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"runtime"
|
|
"sync"
|
|
"sync/atomic"
|
|
"time"
|
|
)
|
|
|
|
// Key for context value
|
|
type ContextTracerKey struct{}
|
|
|
|
type ContextTracer struct {
|
|
sync.Mutex
|
|
actions []*Action
|
|
}
|
|
|
|
type Action struct {
|
|
timestamp time.Time
|
|
level severity
|
|
msg string
|
|
file string
|
|
line int
|
|
}
|
|
|
|
var (
|
|
key = ContextTracerKey{}
|
|
nilTracer *ContextTracer
|
|
)
|
|
|
|
func AddTracer(ctx context.Context) context.Context {
|
|
if ctx != nil && fastcheckLevel(TraceLevel) {
|
|
_, ok := ctx.Value(key).(*ContextTracer)
|
|
if !ok {
|
|
return context.WithValue(ctx, key, &ContextTracer{})
|
|
}
|
|
}
|
|
return ctx
|
|
}
|
|
|
|
func Tracer(ctx context.Context) *ContextTracer {
|
|
if ctx != nil {
|
|
tracer, ok := ctx.Value(key).(*ContextTracer)
|
|
if ok {
|
|
return tracer
|
|
}
|
|
}
|
|
return nilTracer
|
|
}
|
|
|
|
func (ct *ContextTracer) logTrace(level severity, msg string) {
|
|
// get file and line
|
|
_, file, line, ok := runtime.Caller(2)
|
|
if !ok {
|
|
file = ""
|
|
line = 0
|
|
} else {
|
|
if len(file) > 3 {
|
|
file = file[:len(file)-3]
|
|
} else {
|
|
file = ""
|
|
}
|
|
}
|
|
|
|
ct.Lock()
|
|
defer ct.Unlock()
|
|
ct.actions = append(ct.actions, &Action{
|
|
timestamp: time.Now(),
|
|
level: level,
|
|
msg: msg,
|
|
file: file,
|
|
line: line,
|
|
})
|
|
}
|
|
|
|
func (ct *ContextTracer) Tracef(things ...interface{}) (ok bool) {
|
|
if ct != nil {
|
|
if fastcheckLevel(TraceLevel) {
|
|
ct.logTrace(TraceLevel, fmt.Sprintf(things[0].(string), things[1:]...))
|
|
}
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
func (ct *ContextTracer) Trace(msg string) (ok bool) {
|
|
if ct != nil {
|
|
if fastcheckLevel(TraceLevel) {
|
|
ct.logTrace(TraceLevel, msg)
|
|
}
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
func (ct *ContextTracer) Warningf(things ...interface{}) (ok bool) {
|
|
if ct != nil {
|
|
if fastcheckLevel(TraceLevel) {
|
|
ct.logTrace(WarningLevel, fmt.Sprintf(things[0].(string), things[1:]...))
|
|
}
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
func (ct *ContextTracer) Warning(msg string) (ok bool) {
|
|
if ct != nil {
|
|
if fastcheckLevel(TraceLevel) {
|
|
ct.logTrace(WarningLevel, msg)
|
|
}
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
func (ct *ContextTracer) Errorf(things ...interface{}) (ok bool) {
|
|
if ct != nil {
|
|
if fastcheckLevel(TraceLevel) {
|
|
ct.logTrace(ErrorLevel, fmt.Sprintf(things[0].(string), things[1:]...))
|
|
}
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
func (ct *ContextTracer) Error(msg string) (ok bool) {
|
|
if ct != nil {
|
|
if fastcheckLevel(TraceLevel) {
|
|
ct.logTrace(ErrorLevel, msg)
|
|
}
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
func DebugTrace(ctx context.Context, msg string) (ok bool) {
|
|
tracer, ok := ctx.Value(key).(*ContextTracer)
|
|
if ok && fastcheckLevel(TraceLevel) {
|
|
log(DebugLevel, msg, tracer)
|
|
return true
|
|
}
|
|
log(DebugLevel, msg, nil)
|
|
return false
|
|
}
|
|
|
|
func DebugTracef(ctx context.Context, things ...interface{}) (ok bool) {
|
|
tracer, ok := ctx.Value(key).(*ContextTracer)
|
|
if ok && fastcheckLevel(TraceLevel) {
|
|
log(DebugLevel, fmt.Sprintf(things[0].(string), things[1:]...), tracer)
|
|
return true
|
|
}
|
|
log(DebugLevel, fmt.Sprintf(things[0].(string), things[1:]...), nil)
|
|
return false
|
|
}
|
|
|
|
func InfoTrace(ctx context.Context, msg string) (ok bool) {
|
|
tracer, ok := ctx.Value(key).(*ContextTracer)
|
|
if ok && fastcheckLevel(TraceLevel) {
|
|
log(InfoLevel, msg, tracer)
|
|
return true
|
|
}
|
|
log(InfoLevel, msg, nil)
|
|
return false
|
|
}
|
|
|
|
func InfoTracef(ctx context.Context, things ...interface{}) (ok bool) {
|
|
tracer, ok := ctx.Value(key).(*ContextTracer)
|
|
if ok && fastcheckLevel(TraceLevel) {
|
|
log(InfoLevel, fmt.Sprintf(things[0].(string), things[1:]...), tracer)
|
|
return true
|
|
}
|
|
log(InfoLevel, fmt.Sprintf(things[0].(string), things[1:]...), nil)
|
|
return false
|
|
}
|
|
|
|
func WarningTrace(ctx context.Context, msg string) (ok bool) {
|
|
tracer, ok := ctx.Value(key).(*ContextTracer)
|
|
if ok && fastcheckLevel(TraceLevel) {
|
|
log(WarningLevel, msg, tracer)
|
|
return true
|
|
}
|
|
log(WarningLevel, msg, nil)
|
|
return false
|
|
}
|
|
|
|
func WarningTracef(ctx context.Context, things ...interface{}) (ok bool) {
|
|
tracer, ok := ctx.Value(key).(*ContextTracer)
|
|
if ok && fastcheckLevel(TraceLevel) {
|
|
log(WarningLevel, fmt.Sprintf(things[0].(string), things[1:]...), tracer)
|
|
return true
|
|
}
|
|
log(WarningLevel, fmt.Sprintf(things[0].(string), things[1:]...), nil)
|
|
return false
|
|
}
|
|
|
|
func ErrorTrace(ctx context.Context, msg string) (ok bool) {
|
|
tracer, ok := ctx.Value(key).(*ContextTracer)
|
|
if ok && fastcheckLevel(TraceLevel) {
|
|
log(ErrorLevel, msg, tracer)
|
|
return true
|
|
}
|
|
log(ErrorLevel, msg, nil)
|
|
return false
|
|
}
|
|
|
|
func ErrorTracef(ctx context.Context, things ...interface{}) (ok bool) {
|
|
tracer, ok := ctx.Value(key).(*ContextTracer)
|
|
if ok && fastcheckLevel(TraceLevel) {
|
|
log(ErrorLevel, fmt.Sprintf(things[0].(string), things[1:]...), tracer)
|
|
return true
|
|
}
|
|
log(ErrorLevel, fmt.Sprintf(things[0].(string), things[1:]...), nil)
|
|
return false
|
|
}
|
|
|
|
func fastcheckLevel(level severity) bool {
|
|
if uint32(level) < atomic.LoadUint32(logLevel) {
|
|
return false
|
|
}
|
|
return true
|
|
}
|