mirror of
https://github.com/PrivateCaptcha/PrivateCaptcha.git
synced 2026-02-11 00:08:47 -06:00
153 lines
3.2 KiB
Go
153 lines
3.2 KiB
Go
package common
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"log/slog"
|
|
"os"
|
|
"strings"
|
|
)
|
|
|
|
const (
|
|
LevelTrace = slog.Level(-8)
|
|
)
|
|
|
|
type contextHandler struct {
|
|
slog.Handler
|
|
}
|
|
|
|
func (h *contextHandler) Handle(ctx context.Context, r slog.Record) error {
|
|
if ctx != nil {
|
|
if tid, ok := ctx.Value(TraceIDContextKey).(string); ok && (len(tid) > 0) {
|
|
r.AddAttrs(TraceIDAttr(tid))
|
|
}
|
|
|
|
if sid, ok := ctx.Value(SessionIDContextKey).(string); ok && (len(sid) > 0) {
|
|
r.AddAttrs(SessionIDAttr(sid))
|
|
}
|
|
|
|
if svc, ok := ctx.Value(ServiceContextKey).(string); ok && (len(svc) > 0) {
|
|
r.AddAttrs(ServiceAttr(svc))
|
|
}
|
|
}
|
|
|
|
return h.Handler.Handle(ctx, r)
|
|
}
|
|
|
|
func (h *contextHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
|
|
return &contextHandler{h.Handler.WithAttrs(attrs)}
|
|
}
|
|
|
|
func (h *contextHandler) Enabled(ctx context.Context, level slog.Level) bool {
|
|
return h.Handler.Enabled(ctx, level)
|
|
}
|
|
|
|
func (h *contextHandler) WithGroup(name string) slog.Handler {
|
|
return &contextHandler{h.Handler.WithGroup(name)}
|
|
}
|
|
|
|
func TraceContextFunc(ctx context.Context, traceID func() string) (context.Context, string) {
|
|
tid, ok := ctx.Value(TraceIDContextKey).(string)
|
|
if !ok || (len(tid) == 0) {
|
|
tid = traceID()
|
|
}
|
|
|
|
return context.WithValue(ctx, TraceIDContextKey, tid), tid
|
|
}
|
|
|
|
func TraceContext(ctx context.Context, traceID string) context.Context {
|
|
if tid, ok := ctx.Value(TraceIDContextKey).(string); !ok || (len(tid) == 0) {
|
|
ctx = context.WithValue(ctx, TraceIDContextKey, traceID)
|
|
}
|
|
|
|
return ctx
|
|
}
|
|
|
|
func CopyTraceID(from context.Context, to context.Context) context.Context {
|
|
if tid, ok := from.Value(TraceIDContextKey).(string); ok && (len(tid) > 0) {
|
|
return context.WithValue(to, TraceIDContextKey, tid)
|
|
}
|
|
|
|
return to
|
|
}
|
|
|
|
func SetLogLevel(levelVar *slog.LevelVar, verbose bool) {
|
|
level := slog.LevelDebug
|
|
if verbose {
|
|
level = LevelTrace
|
|
}
|
|
|
|
levelVar.Set(level)
|
|
}
|
|
|
|
func SetupLogs(stage string, verbose bool) *slog.LevelVar {
|
|
levelVar := &slog.LevelVar{}
|
|
SetLogLevel(levelVar, verbose)
|
|
|
|
opts := &slog.HandlerOptions{
|
|
Level: levelVar,
|
|
}
|
|
handler := slog.NewJSONHandler(os.Stdout, opts)
|
|
ctxHandler := &contextHandler{handler}
|
|
logger := slog.New(ctxHandler)
|
|
slog.SetDefault(logger)
|
|
return levelVar
|
|
}
|
|
|
|
func SetupTraceLogs() {
|
|
opts := &slog.HandlerOptions{
|
|
Level: LevelTrace,
|
|
}
|
|
logger := slog.New(slog.NewJSONHandler(os.Stdout, opts))
|
|
slog.SetDefault(logger)
|
|
}
|
|
|
|
func FindHeader(headers map[string]string, header string) (string, bool) {
|
|
requestID, ok := headers[header]
|
|
if ok {
|
|
return requestID, ok
|
|
}
|
|
|
|
requestID, ok = headers[strings.ToLower(header)]
|
|
if ok {
|
|
return requestID, ok
|
|
}
|
|
|
|
return "", false
|
|
}
|
|
|
|
func ErrAttr(err error) slog.Attr {
|
|
return slog.Any("error", err)
|
|
}
|
|
|
|
func TraceIDAttr(tid string) slog.Attr {
|
|
return slog.Attr{
|
|
Key: "traceID",
|
|
Value: slog.StringValue(tid),
|
|
}
|
|
}
|
|
|
|
func SessionIDAttr(sid string) slog.Attr {
|
|
return slog.Attr{
|
|
Key: "sessID",
|
|
Value: slog.StringValue(sid),
|
|
}
|
|
}
|
|
|
|
func ServiceAttr(svc string) slog.Attr {
|
|
return slog.Attr{
|
|
Key: "service",
|
|
Value: slog.StringValue(svc),
|
|
}
|
|
}
|
|
|
|
type FmtLogger struct {
|
|
Ctx context.Context
|
|
Level slog.Level
|
|
}
|
|
|
|
func (l *FmtLogger) Printf(s string, args ...interface{}) {
|
|
msg := fmt.Sprintf(s, args...)
|
|
slog.Log(l.Ctx, l.Level, msg)
|
|
}
|