2024-08-11 21:45:11 +07:00
|
|
|
package log
|
|
|
|
|
|
|
|
import (
|
2024-08-27 09:29:42 +07:00
|
|
|
"io"
|
2024-08-11 21:45:11 +07:00
|
|
|
"log/slog"
|
|
|
|
"net/http"
|
|
|
|
"os"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/mattn/go-colorable"
|
|
|
|
"github.com/mattn/go-isatty"
|
|
|
|
slogmulti "github.com/samber/slog-multi"
|
|
|
|
"github.com/tigorlazuardi/bluemage/go/config"
|
2024-08-27 09:29:42 +07:00
|
|
|
"github.com/tigorlazuardi/bluemage/go/pkg/errs"
|
2024-08-11 21:45:11 +07:00
|
|
|
"github.com/tigorlazuardi/bluemage/go/pkg/telemetry"
|
|
|
|
"gopkg.in/natefinch/lumberjack.v2"
|
|
|
|
)
|
|
|
|
|
|
|
|
func NewHandler(cfg *config.Config) (slog.Handler, func() error) {
|
|
|
|
var handlers []slog.Handler
|
|
|
|
cleanup := func() error { return nil }
|
|
|
|
|
|
|
|
if cfg.Bool("log.enable") {
|
2024-08-27 09:29:42 +07:00
|
|
|
log := createStandardLogger(cfg)
|
|
|
|
if closer, ok := log.(io.Closer); ok {
|
|
|
|
cleanup = closer.Close
|
|
|
|
}
|
2024-08-11 21:45:11 +07:00
|
|
|
handlers = append(handlers, log)
|
|
|
|
}
|
|
|
|
|
|
|
|
if cfg.Bool("log.file.enable") {
|
|
|
|
log, clean := createFileLogger(cfg)
|
|
|
|
cl := cleanup
|
|
|
|
cleanup = func() error {
|
2024-08-27 09:29:42 +07:00
|
|
|
return errs.Join(cl(), clean())
|
2024-08-11 21:45:11 +07:00
|
|
|
}
|
|
|
|
handlers = append(handlers, log)
|
|
|
|
}
|
|
|
|
|
|
|
|
if cfg.Bool("telemetry.openobserve.enable") && cfg.Bool("telemetry.openobserve.log.enable") {
|
2024-08-11 21:57:36 +07:00
|
|
|
log, clean := createO2Logger(cfg)
|
|
|
|
cl := cleanup
|
|
|
|
handlers = append(handlers, log)
|
|
|
|
cleanup = func() error {
|
|
|
|
err := cl()
|
|
|
|
clean()
|
|
|
|
return err
|
|
|
|
}
|
2024-08-11 21:45:11 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
if len(handlers) == 0 {
|
|
|
|
return NullHandler{}, cleanup
|
|
|
|
}
|
|
|
|
|
|
|
|
return slogmulti.Fanout(handlers...), cleanup
|
|
|
|
}
|
|
|
|
|
|
|
|
func createFileLogger(cfg *config.Config) (slog.Handler, func() error) {
|
|
|
|
output := &lumberjack.Logger{
|
|
|
|
Filename: cfg.String("log.file.path"),
|
|
|
|
MaxSize: 15,
|
|
|
|
MaxAge: 30,
|
|
|
|
MaxBackups: 10,
|
|
|
|
LocalTime: true,
|
|
|
|
}
|
|
|
|
var lvl slog.Level
|
|
|
|
_ = lvl.UnmarshalText(cfg.Bytes("log.level"))
|
|
|
|
opts := &slog.HandlerOptions{
|
|
|
|
AddSource: cfg.Bool("log.source"),
|
|
|
|
Level: lvl,
|
|
|
|
}
|
2024-08-27 09:29:42 +07:00
|
|
|
return slog.NewJSONHandler(Lock(output), opts), output.Close
|
2024-08-11 21:45:11 +07:00
|
|
|
}
|
|
|
|
|
2024-08-27 09:29:42 +07:00
|
|
|
func createStandardLogger(cfg *config.Config) slog.Handler {
|
|
|
|
var output WriteLocker
|
2024-08-11 21:45:11 +07:00
|
|
|
|
|
|
|
if strings.ToLower(cfg.String("log.output")) == "stdout" {
|
2024-08-27 09:29:42 +07:00
|
|
|
output = Lock(colorable.NewColorableStdout())
|
2024-08-11 21:45:11 +07:00
|
|
|
} else {
|
2024-08-27 09:29:42 +07:00
|
|
|
output = Lock(colorable.NewColorableStderr())
|
2024-08-11 21:45:11 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
var lvl slog.Level
|
|
|
|
_ = lvl.UnmarshalText(cfg.Bytes("log.level"))
|
|
|
|
opts := &slog.HandlerOptions{
|
|
|
|
AddSource: cfg.Bool("log.source"),
|
|
|
|
Level: lvl,
|
|
|
|
}
|
|
|
|
|
|
|
|
if isatty.IsTerminal(os.Stdout.Fd()) {
|
2024-08-27 09:29:42 +07:00
|
|
|
return NewPrettyHandler(output, opts)
|
2024-08-11 21:45:11 +07:00
|
|
|
} else {
|
2024-08-27 09:29:42 +07:00
|
|
|
return slog.NewJSONHandler(output, opts)
|
2024-08-11 21:45:11 +07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-08-11 21:57:36 +07:00
|
|
|
func createO2Logger(cfg *config.Config) (slog.Handler, func()) {
|
2024-08-11 21:45:11 +07:00
|
|
|
var lvl slog.Level
|
|
|
|
_ = lvl.UnmarshalText(cfg.Bytes("telemetry.openobserve.log.level"))
|
|
|
|
opts := &slog.HandlerOptions{
|
|
|
|
AddSource: cfg.Bool("telemetry.openobserve.log.source"),
|
|
|
|
Level: lvl,
|
|
|
|
}
|
2024-08-11 21:57:36 +07:00
|
|
|
handler := telemetry.NewOpenObserveHandler(telemetry.OpenObserveHandlerOptions{
|
2024-08-11 21:45:11 +07:00
|
|
|
HandlerOptions: opts,
|
|
|
|
BufferSize: cfg.Int("telemetry.openobserve.log.buffer.size"),
|
|
|
|
BufferTimeout: cfg.Duration("telemetry.openobserve.log.buffer.timeout"),
|
|
|
|
Concurrency: cfg.Int("telemetry.openobserve.log.concurrency"),
|
|
|
|
Endpoint: cfg.String("telemetry.openobserve.log.endpoint"),
|
|
|
|
HTTPClient: http.DefaultClient,
|
|
|
|
Username: cfg.String("telemetry.openobserve.log.username"),
|
|
|
|
Password: cfg.String("telemetry.openobserve.log.password"),
|
|
|
|
})
|
2024-08-11 21:57:36 +07:00
|
|
|
return handler, handler.Flush
|
2024-08-11 21:45:11 +07:00
|
|
|
}
|