freeleaps-ops/apps/gitea-webhook-ambassador/internal/logger/logger.go
zhenyus db590f3f27 refactor: update gitea-webhook-ambassador Dockerfile and configuration
- Changed the build process to include a web UI build stage using Node.js.
- Updated Go build stage to copy web UI files to the correct location.
- Removed the main.go file as it is no longer needed.
- Added SQLite database configuration to example config.
- Updated dependencies in go.mod and go.sum, including new packages for JWT and SQLite.
- Modified .gitignore to include new database and configuration files.

Signed-off-by: zhenyus <zhenyus@mathmast.com>
2025-06-10 16:00:52 +08:00

164 lines
2.8 KiB
Go

package logger
import (
"encoding/json"
"fmt"
"io"
"log"
"os"
"strings"
"sync"
"time"
)
type Level int
const (
DEBUG Level = iota
INFO
WARN
ERROR
)
var levelStrings = map[Level]string{
DEBUG: "DEBUG",
INFO: "INFO",
WARN: "WARN",
ERROR: "ERROR",
}
var stringToLevel = map[string]Level{
"debug": DEBUG,
"info": INFO,
"warn": WARN,
"error": ERROR,
}
type Logger struct {
logger *log.Logger
level Level
format string
mu sync.RWMutex
jsonWriter *jsonLogWriter
}
type jsonLogWriter struct {
out io.Writer
}
type Config struct {
Level string
Format string
File string
}
var defaultLogger *Logger
func init() {
defaultLogger = New(Config{
Level: "info",
Format: "text",
})
}
func New(config Config) *Logger {
var output io.Writer = os.Stdout
if config.File != "" {
file, err := os.OpenFile(config.File, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
if err == nil {
output = io.MultiWriter(file, os.Stdout)
}
}
level := stringToLevel[strings.ToLower(config.Level)]
format := strings.ToLower(config.Format)
l := &Logger{
level: level,
format: format,
}
if format == "json" {
l.jsonWriter = &jsonLogWriter{out: output}
l.logger = log.New(l.jsonWriter, "", 0)
} else {
l.logger = log.New(output, "", log.LstdFlags|log.Lshortfile)
}
return l
}
func (w *jsonLogWriter) Write(p []byte) (n int, err error) {
entry := map[string]interface{}{
"timestamp": time.Now().Format(time.RFC3339),
"message": strings.TrimSpace(string(p)),
}
jsonData, err := json.Marshal(entry)
if err != nil {
return 0, err
}
return w.out.Write(append(jsonData, '\n'))
}
func (l *Logger) log(level Level, format string, v ...interface{}) {
l.mu.RLock()
defer l.mu.RUnlock()
if level < l.level {
return
}
msg := fmt.Sprintf(format, v...)
if l.format == "json" {
entry := map[string]interface{}{
"timestamp": time.Now().Format(time.RFC3339),
"level": levelStrings[level],
"message": msg,
}
jsonData, _ := json.Marshal(entry)
l.logger.Print(string(jsonData))
} else {
l.logger.Printf("[%s] %s", levelStrings[level], msg)
}
}
func (l *Logger) Debug(format string, v ...interface{}) {
l.log(DEBUG, format, v...)
}
func (l *Logger) Info(format string, v ...interface{}) {
l.log(INFO, format, v...)
}
func (l *Logger) Warn(format string, v ...interface{}) {
l.log(WARN, format, v...)
}
func (l *Logger) Error(format string, v ...interface{}) {
l.log(ERROR, format, v...)
}
// Global logger functions
func Debug(format string, v ...interface{}) {
defaultLogger.Debug(format, v...)
}
func Info(format string, v ...interface{}) {
defaultLogger.Info(format, v...)
}
func Warn(format string, v ...interface{}) {
defaultLogger.Warn(format, v...)
}
func Error(format string, v ...interface{}) {
defaultLogger.Error(format, v...)
}
func Configure(config Config) {
defaultLogger = New(config)
}