forked from Plemya-x/ALR
		
	feat: migrate to system cache with changing core logic
This commit is contained in:
		
							
								
								
									
										152
									
								
								internal/logger/hclog.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										152
									
								
								internal/logger/hclog.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,152 @@
 | 
			
		||||
// ALR - Any Linux Repository
 | 
			
		||||
// Copyright (C) 2025 Евгений Храмов
 | 
			
		||||
//
 | 
			
		||||
// This program is free software: you can redistribute it and/or modify
 | 
			
		||||
// it under the terms of the GNU General Public License as published by
 | 
			
		||||
// the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
// (at your option) any later version.
 | 
			
		||||
//
 | 
			
		||||
// This program is distributed in the hope that it will be useful,
 | 
			
		||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
// GNU General Public License for more details.
 | 
			
		||||
//
 | 
			
		||||
// You should have received a copy of the GNU General Public License
 | 
			
		||||
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 | 
			
		||||
package logger
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"io"
 | 
			
		||||
	"log"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	chLog "github.com/charmbracelet/log"
 | 
			
		||||
	"github.com/hashicorp/go-hclog"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type HCLoggerAdapter struct {
 | 
			
		||||
	logger *Logger
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func hclogLevelTochLog(level hclog.Level) chLog.Level {
 | 
			
		||||
	switch level {
 | 
			
		||||
	case hclog.Debug:
 | 
			
		||||
		return chLog.DebugLevel
 | 
			
		||||
	case hclog.Info:
 | 
			
		||||
		return chLog.InfoLevel
 | 
			
		||||
	case hclog.Warn:
 | 
			
		||||
		return chLog.WarnLevel
 | 
			
		||||
	case hclog.Error:
 | 
			
		||||
		return chLog.ErrorLevel
 | 
			
		||||
	}
 | 
			
		||||
	return chLog.FatalLevel
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (a *HCLoggerAdapter) Log(level hclog.Level, msg string, args ...interface{}) {
 | 
			
		||||
	filteredArgs := make([]interface{}, 0, len(args))
 | 
			
		||||
	for i := 0; i < len(args); i += 2 {
 | 
			
		||||
		if i+1 >= len(args) {
 | 
			
		||||
			filteredArgs = append(filteredArgs, args[i])
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		key, ok := args[i].(string)
 | 
			
		||||
		if !ok || key != "timestamp" {
 | 
			
		||||
			filteredArgs = append(filteredArgs, args[i], args[i+1])
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Start ugly hacks
 | 
			
		||||
	// Ignore exit messages
 | 
			
		||||
	// - https://github.com/hashicorp/go-plugin/issues/331
 | 
			
		||||
	// - https://github.com/hashicorp/go-plugin/issues/203
 | 
			
		||||
	// - https://github.com/hashicorp/go-plugin/issues/192
 | 
			
		||||
	var chLogLevel chLog.Level
 | 
			
		||||
	if msg == "plugin process exited" ||
 | 
			
		||||
		strings.HasPrefix(msg, "[ERR] plugin: stream copy 'stderr' error") ||
 | 
			
		||||
		strings.HasPrefix(msg, "[DEBUG] plugin") {
 | 
			
		||||
		chLogLevel = chLog.DebugLevel
 | 
			
		||||
	} else {
 | 
			
		||||
		chLogLevel = hclogLevelTochLog(level)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	a.logger.l.Log(chLogLevel, msg, filteredArgs...)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (a *HCLoggerAdapter) Trace(msg string, args ...interface{}) {
 | 
			
		||||
	a.Log(hclog.Trace, msg, args...)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (a *HCLoggerAdapter) Debug(msg string, args ...interface{}) {
 | 
			
		||||
	a.Log(hclog.Debug, msg, args...)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (a *HCLoggerAdapter) Info(msg string, args ...interface{}) {
 | 
			
		||||
	a.Log(hclog.Info, msg, args...)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (a *HCLoggerAdapter) Warn(msg string, args ...interface{}) {
 | 
			
		||||
	a.Log(hclog.Warn, msg, args...)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (a *HCLoggerAdapter) Error(msg string, args ...interface{}) {
 | 
			
		||||
	a.Log(hclog.Error, msg, args...)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (a *HCLoggerAdapter) IsTrace() bool {
 | 
			
		||||
	return a.logger.l.GetLevel() <= chLog.DebugLevel
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (a *HCLoggerAdapter) IsDebug() bool {
 | 
			
		||||
	return a.logger.l.GetLevel() <= chLog.DebugLevel
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (a *HCLoggerAdapter) IsInfo() bool {
 | 
			
		||||
	return a.logger.l.GetLevel() <= chLog.InfoLevel
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (a *HCLoggerAdapter) IsWarn() bool {
 | 
			
		||||
	return a.logger.l.GetLevel() <= chLog.WarnLevel
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (a *HCLoggerAdapter) IsError() bool {
 | 
			
		||||
	return a.logger.l.GetLevel() <= chLog.ErrorLevel
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (a *HCLoggerAdapter) ImpliedArgs() []interface{} {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (a *HCLoggerAdapter) With(args ...interface{}) hclog.Logger {
 | 
			
		||||
	return a
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (a *HCLoggerAdapter) Name() string {
 | 
			
		||||
	return ""
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (a *HCLoggerAdapter) Named(name string) hclog.Logger {
 | 
			
		||||
	return a
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (a *HCLoggerAdapter) ResetNamed(name string) hclog.Logger {
 | 
			
		||||
	return a
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (a *HCLoggerAdapter) SetLevel(level hclog.Level) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (a *HCLoggerAdapter) StandardLogger(opts *hclog.StandardLoggerOptions) *log.Logger {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (a *HCLoggerAdapter) StandardWriter(opts *hclog.StandardLoggerOptions) io.Writer {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GetHCLoggerAdapter() *HCLoggerAdapter {
 | 
			
		||||
	return &HCLoggerAdapter{
 | 
			
		||||
		logger: logger,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -22,96 +22,90 @@ import (
 | 
			
		||||
	"os"
 | 
			
		||||
 | 
			
		||||
	"github.com/charmbracelet/lipgloss"
 | 
			
		||||
	"github.com/charmbracelet/log"
 | 
			
		||||
 | 
			
		||||
	chLog "github.com/charmbracelet/log"
 | 
			
		||||
	"github.com/leonelquinteros/gotext"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type Logger struct {
 | 
			
		||||
	lOut slog.Handler
 | 
			
		||||
	lErr slog.Handler
 | 
			
		||||
	l *chLog.Logger
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func setupOutLogger() *log.Logger {
 | 
			
		||||
	styles := log.DefaultStyles()
 | 
			
		||||
	logger := log.New(os.Stdout)
 | 
			
		||||
	styles.Levels[log.InfoLevel] = lipgloss.NewStyle().
 | 
			
		||||
func setupLogger() *chLog.Logger {
 | 
			
		||||
	styles := chLog.DefaultStyles()
 | 
			
		||||
	logger := chLog.New(os.Stderr)
 | 
			
		||||
	styles.Levels[chLog.InfoLevel] = lipgloss.NewStyle().
 | 
			
		||||
		SetString("-->").
 | 
			
		||||
		Foreground(lipgloss.Color("35"))
 | 
			
		||||
	logger.SetStyles(styles)
 | 
			
		||||
	return logger
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func setupErrorLogger() *log.Logger {
 | 
			
		||||
	styles := log.DefaultStyles()
 | 
			
		||||
	styles.Levels[log.ErrorLevel] = lipgloss.NewStyle().
 | 
			
		||||
	styles.Levels[chLog.ErrorLevel] = lipgloss.NewStyle().
 | 
			
		||||
		SetString(gotext.Get("ERROR")).
 | 
			
		||||
		Padding(0, 1, 0, 1).
 | 
			
		||||
		Background(lipgloss.Color("204")).
 | 
			
		||||
		Foreground(lipgloss.Color("0"))
 | 
			
		||||
	logger := log.New(os.Stderr)
 | 
			
		||||
	logger.SetStyles(styles)
 | 
			
		||||
	return logger
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func New() *Logger {
 | 
			
		||||
	standardLogger := setupOutLogger()
 | 
			
		||||
	errLogger := setupErrorLogger()
 | 
			
		||||
	return &Logger{
 | 
			
		||||
		lOut: standardLogger,
 | 
			
		||||
		lErr: errLogger,
 | 
			
		||||
		l: setupLogger(),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func slogLevelToLog(level slog.Level) log.Level {
 | 
			
		||||
func slogLevelToLog(level slog.Level) chLog.Level {
 | 
			
		||||
	switch level {
 | 
			
		||||
	case slog.LevelDebug:
 | 
			
		||||
		return log.DebugLevel
 | 
			
		||||
		return chLog.DebugLevel
 | 
			
		||||
	case slog.LevelInfo:
 | 
			
		||||
		return log.InfoLevel
 | 
			
		||||
		return chLog.InfoLevel
 | 
			
		||||
	case slog.LevelWarn:
 | 
			
		||||
		return log.WarnLevel
 | 
			
		||||
		return chLog.WarnLevel
 | 
			
		||||
	case slog.LevelError:
 | 
			
		||||
		return log.ErrorLevel
 | 
			
		||||
		return chLog.ErrorLevel
 | 
			
		||||
	}
 | 
			
		||||
	return log.FatalLevel
 | 
			
		||||
	return chLog.FatalLevel
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (l *Logger) SetLevel(level slog.Level) {
 | 
			
		||||
	l.lOut.(*log.Logger).SetLevel(slogLevelToLog(level))
 | 
			
		||||
	l.lErr.(*log.Logger).SetLevel(slogLevelToLog(level))
 | 
			
		||||
	l.l.SetLevel(slogLevelToLog(level))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (l *Logger) Enabled(ctx context.Context, level slog.Level) bool {
 | 
			
		||||
	if level <= slog.LevelInfo {
 | 
			
		||||
		return l.lOut.Enabled(ctx, level)
 | 
			
		||||
	}
 | 
			
		||||
	return l.lErr.Enabled(ctx, level)
 | 
			
		||||
	return l.l.Enabled(ctx, level)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (l *Logger) Handle(ctx context.Context, rec slog.Record) error {
 | 
			
		||||
	if rec.Level <= slog.LevelInfo {
 | 
			
		||||
		return l.lOut.Handle(ctx, rec)
 | 
			
		||||
	}
 | 
			
		||||
	return l.lErr.Handle(ctx, rec)
 | 
			
		||||
	return l.l.Handle(ctx, rec)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (l *Logger) WithAttrs(attrs []slog.Attr) slog.Handler {
 | 
			
		||||
	sl := *l
 | 
			
		||||
	sl.lOut = l.lOut.WithAttrs(attrs)
 | 
			
		||||
	sl.lErr = l.lErr.WithAttrs(attrs)
 | 
			
		||||
	sl.l = l.l.WithAttrs(attrs).(*chLog.Logger)
 | 
			
		||||
	return &sl
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (l *Logger) WithGroup(name string) slog.Handler {
 | 
			
		||||
	sl := *l
 | 
			
		||||
	sl.lOut = l.lOut.WithGroup(name)
 | 
			
		||||
	sl.lErr = l.lErr.WithGroup(name)
 | 
			
		||||
	sl.l = l.l.WithGroup(name).(*chLog.Logger)
 | 
			
		||||
	return &sl
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var logger *Logger
 | 
			
		||||
 | 
			
		||||
func SetupDefault() *Logger {
 | 
			
		||||
	l := New()
 | 
			
		||||
	logger := slog.New(l)
 | 
			
		||||
	slog.SetDefault(logger)
 | 
			
		||||
	return l
 | 
			
		||||
	logger = New()
 | 
			
		||||
	slogLogger := slog.New(logger)
 | 
			
		||||
	slog.SetDefault(slogLogger)
 | 
			
		||||
	return logger
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func SetupForGoPlugin() {
 | 
			
		||||
	logger.l.SetFormatter(chLog.JSONFormatter)
 | 
			
		||||
	chLog.TimestampKey = "@timestamp"
 | 
			
		||||
	chLog.MessageKey = "@message"
 | 
			
		||||
	chLog.LevelKey = "@level"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GetLogger() *Logger {
 | 
			
		||||
	return logger
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user