mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2025-12-23 22:29:59 -05:00
146 lines
3.6 KiB
Go
146 lines
3.6 KiB
Go
package log
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"os"
|
|
"runtime"
|
|
"strings"
|
|
"time"
|
|
|
|
chimiddleware "github.com/go-chi/chi/v5/middleware"
|
|
mzlog "github.com/go-micro/plugins/v4/logger/zerolog"
|
|
"github.com/rs/zerolog"
|
|
"github.com/rs/zerolog/log"
|
|
"go-micro.dev/v4/logger"
|
|
)
|
|
|
|
var (
|
|
RequestIDString = "request-id"
|
|
)
|
|
|
|
func init() {
|
|
// this is ugly, but "logger.DefaultLogger" is a global variable, and we need to set it _before_ anybody uses it
|
|
setMicroLogger()
|
|
}
|
|
|
|
// for logging reasons we don't want the same logging level on both OpenCloud and micro. As a framework builder we do not
|
|
// want to expose to the end user the internal framework logs unless explicitly specified.
|
|
func setMicroLogger() {
|
|
if os.Getenv("MICRO_LOG_LEVEL") == "" {
|
|
_ = os.Setenv("MICRO_LOG_LEVEL", "error")
|
|
}
|
|
|
|
lev, err := zerolog.ParseLevel(os.Getenv("MICRO_LOG_LEVEL"))
|
|
if err != nil {
|
|
lev = zerolog.ErrorLevel
|
|
}
|
|
logger.DefaultLogger = mzlog.NewLogger(
|
|
logger.WithLevel(logger.Level(lev)),
|
|
logger.WithFields(map[string]interface{}{
|
|
"system": "go-micro",
|
|
}),
|
|
)
|
|
}
|
|
|
|
// Logger simply wraps the zerolog logger.
|
|
type Logger struct {
|
|
zerolog.Logger
|
|
}
|
|
|
|
// NopLogger initializes a no-operation logger.
|
|
func NopLogger() Logger {
|
|
return Logger{zerolog.Nop()}
|
|
}
|
|
|
|
type LineInfoHook struct{}
|
|
|
|
// Run is a hook to add line info to log messages.
|
|
// I found the zerolog example for this here:
|
|
// https://github.com/rs/zerolog/issues/22#issuecomment-1127295489
|
|
func (h LineInfoHook) Run(e *zerolog.Event, _ zerolog.Level, _ string) {
|
|
_, file, line, ok := runtime.Caller(3)
|
|
if ok {
|
|
e.Str("line", fmt.Sprintf("%s:%d", file, line))
|
|
}
|
|
}
|
|
|
|
// NewLogger initializes a new logger instance.
|
|
func NewLogger(opts ...Option) Logger {
|
|
options := newOptions(opts...)
|
|
|
|
// set GlobalLevel() to the minimum value -1 = TraceLevel, so that only the services' log level matter
|
|
zerolog.SetGlobalLevel(zerolog.TraceLevel)
|
|
|
|
var logLevel zerolog.Level
|
|
switch strings.ToLower(options.Level) {
|
|
case "panic":
|
|
logLevel = zerolog.PanicLevel
|
|
case "fatal":
|
|
logLevel = zerolog.FatalLevel
|
|
case "error":
|
|
logLevel = zerolog.ErrorLevel
|
|
case "warn":
|
|
logLevel = zerolog.WarnLevel
|
|
case "info":
|
|
logLevel = zerolog.InfoLevel
|
|
case "debug":
|
|
logLevel = zerolog.DebugLevel
|
|
case "trace":
|
|
logLevel = zerolog.TraceLevel
|
|
default:
|
|
logLevel = zerolog.ErrorLevel
|
|
}
|
|
|
|
var l zerolog.Logger
|
|
|
|
if options.Pretty {
|
|
l = log.Output(
|
|
zerolog.NewConsoleWriter(
|
|
func(w *zerolog.ConsoleWriter) {
|
|
w.TimeFormat = time.RFC3339
|
|
w.Out = os.Stderr
|
|
w.NoColor = !options.Color
|
|
},
|
|
),
|
|
)
|
|
} else if options.File != "" {
|
|
f, err := os.OpenFile(options.File, os.O_CREATE|os.O_APPEND|os.O_RDWR, 0644)
|
|
if err != nil {
|
|
print(fmt.Sprintf("file could not be opened for writing: %s. error: %v", options.File, err))
|
|
os.Exit(1)
|
|
}
|
|
l = l.Output(f)
|
|
} else {
|
|
l = zerolog.New(os.Stderr)
|
|
}
|
|
|
|
l = l.With().
|
|
Str("service", options.Name).
|
|
Timestamp().
|
|
Logger().Level(logLevel)
|
|
|
|
if logLevel <= zerolog.InfoLevel {
|
|
var lineInfoHook LineInfoHook
|
|
l = l.Hook(lineInfoHook)
|
|
}
|
|
|
|
return Logger{
|
|
l,
|
|
}
|
|
}
|
|
|
|
// SubloggerWithRequestID returns a sub-logger with the x-request-id added to all events
|
|
func (l Logger) SubloggerWithRequestID(c context.Context) Logger {
|
|
return Logger{
|
|
l.With().Str(RequestIDString, chimiddleware.GetReqID(c)).Logger(),
|
|
}
|
|
}
|
|
|
|
// Deprecation logs a deprecation message,
|
|
// it is used to inform the user that a certain feature is deprecated and will be removed in the future.
|
|
// Do not use a logger here because the message MUST be visible independent of the log level.
|
|
func Deprecation(a ...any) {
|
|
fmt.Printf("\033[1;31mDEPRECATION: %s\033[0m\n", a...)
|
|
}
|