mirror of
https://github.com/lukaszraczylo/graphql-monitoring-proxy.git
synced 2026-06-05 23:03:48 +00:00
61d7a45d00
Update cache library, Update logging library, use miniredis for testing, add additional benchmarks.
205 lines
3.4 KiB
Go
205 lines
3.4 KiB
Go
package libpack_logger
|
|
|
|
import (
|
|
"bytes"
|
|
"flag"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"path/filepath"
|
|
"runtime"
|
|
"strings"
|
|
"sync"
|
|
"time"
|
|
|
|
"github.com/goccy/go-json"
|
|
)
|
|
|
|
const (
|
|
_ = iota
|
|
LEVEL_DEBUG
|
|
LEVEL_INFO
|
|
LEVEL_WARN
|
|
LEVEL_ERROR
|
|
LEVEL_FATAL
|
|
)
|
|
|
|
var LevelNames = [...]string{
|
|
"none",
|
|
"debug",
|
|
"info",
|
|
"warn",
|
|
"error",
|
|
"fatal",
|
|
}
|
|
|
|
const (
|
|
defaultFormat = time.RFC3339
|
|
defaultMinLevel = LEVEL_INFO
|
|
defaultShowCaller = false
|
|
)
|
|
|
|
var defaultOutput = os.Stdout
|
|
|
|
type Logger struct {
|
|
format string
|
|
minLogLevel int
|
|
showCaller bool
|
|
output io.Writer
|
|
}
|
|
|
|
type LogMessage struct {
|
|
Message string
|
|
Pairs map[string]any
|
|
output io.Writer
|
|
}
|
|
|
|
func (m *LogMessage) String() string {
|
|
return m.Message
|
|
}
|
|
|
|
var fieldNames = map[string]string{
|
|
"timestamp": "timestamp",
|
|
"level": "level",
|
|
"message": "message",
|
|
}
|
|
|
|
func New() *Logger {
|
|
return &Logger{
|
|
format: defaultFormat,
|
|
minLogLevel: defaultMinLevel,
|
|
output: defaultOutput,
|
|
showCaller: defaultShowCaller,
|
|
}
|
|
}
|
|
|
|
func (l *Logger) SetOutput(output io.Writer) *Logger {
|
|
l.output = output
|
|
return l
|
|
}
|
|
|
|
var bufferPool = sync.Pool{
|
|
New: func() any {
|
|
return new(bytes.Buffer)
|
|
},
|
|
}
|
|
|
|
var defaultPairs = make(map[string]any)
|
|
|
|
func GetLogLevel(level string) int {
|
|
for i, name := range LevelNames {
|
|
if name == strings.ToLower(level) {
|
|
return i
|
|
}
|
|
}
|
|
return defaultMinLevel
|
|
}
|
|
|
|
func (l *Logger) log(level int, m *LogMessage) {
|
|
if m.Pairs == nil {
|
|
m.Pairs = defaultPairs
|
|
}
|
|
|
|
m.Pairs[fieldNames["timestamp"]] = time.Now().Format(l.format)
|
|
m.Pairs[fieldNames["level"]] = LevelNames[level]
|
|
m.Pairs[fieldNames["message"]] = m.Message
|
|
|
|
if l.showCaller {
|
|
m.Pairs["caller"] = getCaller()
|
|
}
|
|
|
|
buffer := bufferPool.Get().(*bytes.Buffer)
|
|
defer bufferPool.Put(buffer)
|
|
buffer.Reset()
|
|
|
|
var encoder = json.NewEncoder(buffer)
|
|
err := encoder.Encode(m.Pairs)
|
|
if err != nil {
|
|
fmt.Println("Error marshalling log message:", err)
|
|
return
|
|
}
|
|
|
|
// if not running in test - use stderr and stdout, otherwise - use logger's output setting
|
|
if flag.Lookup("test.v") != nil {
|
|
m.output = os.Stdout
|
|
if level >= LEVEL_ERROR {
|
|
m.output = os.Stderr
|
|
}
|
|
}
|
|
|
|
// Use logger's output setting instead of os.Stdout or os.Stderr
|
|
l.output.Write(buffer.Bytes())
|
|
}
|
|
|
|
func (l *Logger) Debug(m *LogMessage) {
|
|
if l.shouldLog(LEVEL_DEBUG) {
|
|
l.log(LEVEL_DEBUG, m)
|
|
}
|
|
}
|
|
|
|
func (l *Logger) Info(m *LogMessage) {
|
|
if l.shouldLog(LEVEL_INFO) {
|
|
l.log(LEVEL_INFO, m)
|
|
}
|
|
}
|
|
|
|
func (l *Logger) Warn(m *LogMessage) {
|
|
if l.shouldLog(LEVEL_WARN) {
|
|
l.log(LEVEL_WARN, m)
|
|
}
|
|
}
|
|
|
|
func (l *Logger) Warning(m *LogMessage) {
|
|
l.Warn(m)
|
|
}
|
|
|
|
func (l *Logger) Error(m *LogMessage) {
|
|
if l.shouldLog(LEVEL_ERROR) {
|
|
l.log(LEVEL_ERROR, m)
|
|
}
|
|
}
|
|
|
|
func (l *Logger) Fatal(m *LogMessage) {
|
|
if l.shouldLog(LEVEL_FATAL) {
|
|
l.log(LEVEL_FATAL, m)
|
|
}
|
|
}
|
|
|
|
func (l *Logger) Critical(m *LogMessage) {
|
|
l.Fatal(m)
|
|
os.Exit(1)
|
|
}
|
|
|
|
func (l *Logger) shouldLog(level int) bool {
|
|
return level >= l.minLogLevel
|
|
}
|
|
|
|
func (l *Logger) SetFormat(format string) *Logger {
|
|
l.format = format
|
|
return l
|
|
}
|
|
|
|
func (l *Logger) SetMinLogLevel(level int) *Logger {
|
|
l.minLogLevel = level
|
|
return l
|
|
}
|
|
|
|
func (l *Logger) SetFieldName(field, name string) *Logger {
|
|
fieldNames[field] = name
|
|
return l
|
|
}
|
|
|
|
func (l *Logger) SetShowCaller(show bool) *Logger {
|
|
l.showCaller = show
|
|
return l
|
|
}
|
|
|
|
func getCaller() string {
|
|
_, file, line, ok := runtime.Caller(3)
|
|
if !ok {
|
|
return "unknown:0"
|
|
}
|
|
file = filepath.Base(file)
|
|
return fmt.Sprintf("%s:%d", file, line)
|
|
}
|