Files
TrollSSH/internal/logx/logx.go
T

90 lines
1.8 KiB
Go

package logx
import (
"encoding/json"
"fmt"
"os"
"strings"
"time"
)
type Level int
const (
LevelDebug Level = 10
LevelInfo Level = 20
LevelWarn Level = 30
LevelError Level = 40
)
var threshold = ResolveThreshold()
func ResolveThreshold() Level {
switch strings.ToLower(strings.TrimSpace(os.Getenv("LOG_LEVEL"))) {
case "debug":
return LevelDebug
case "warn":
return LevelWarn
case "error":
return LevelError
default:
return LevelInfo
}
}
func SetThreshold(level Level) { threshold = level }
func Sanitize(value any) string {
return SanitizeN(value, 200)
}
func SanitizeN(value any, maxLength int) string {
var str string
switch v := value.(type) {
case nil:
str = ""
case string:
str = v
default:
str = fmt.Sprint(v)
}
var b strings.Builder
count := 0
for _, r := range str {
if count >= maxLength {
b.WriteRune('…')
return b.String()
}
if r < 0x20 || (r >= 0x7f && r <= 0x9f) {
b.WriteRune('')
} else {
b.WriteRune(r)
}
count++
}
return b.String()
}
func emit(level Level, name string, stream *os.File, args []any) {
if level < threshold {
return
}
parts := make([]string, len(args))
for i, a := range args {
if s, ok := a.(string); ok {
parts[i] = s
} else if b, err := json.Marshal(a); err == nil {
parts[i] = string(b)
} else {
parts[i] = fmt.Sprint(a)
}
}
ts := time.Now().UTC().Format("2006-01-02T15:04:05.000Z")
_, _ = fmt.Fprintf(stream, "[%s] %-5s %s\n", ts, strings.ToUpper(name), strings.Join(parts, " "))
}
func Debug(args ...any) { emit(LevelDebug, "debug", os.Stdout, args) }
func Info(args ...any) { emit(LevelInfo, "info", os.Stdout, args) }
func Warn(args ...any) { emit(LevelWarn, "warn", os.Stderr, args) }
func Error(args ...any) { emit(LevelError, "error", os.Stderr, args) }