mirror of
https://github.com/hanzoai/base.git
synced 2026-10-21 03:41:50 +00:00
core.App.Logger() now returns logger.Logger (the new shim interface) instead of *slog.Logger, so every consumer talks to the same backend-agnostic surface and stops pinning itself to log/slog. The raw *slog.Logger is still reachable as App.SlogLogger() for the in-app BatchHandler reload hook and the two tests that type-assert the underlying handler — that's the only sanctioned escape hatch. Plugins and network code that previously held *slog.Logger fields move to luxlog.Logger (kms, vault, zap-transport, base-network/transport_zap, network/archive_writer, tools/tasks/client). luxfi/zap's Logger field was a pure transit dependency; we drop it from base call sites since zaplib has its own default. Remaining "log/slog" imports — 11 files — are confined to the adapter/handler bridge (tools/logger and core/log_printer/base/app) and to two tests that exercise the slog.Handler contract directly. Those are the irreducible boundary where slog is the language of the interface.
126 lines
3.3 KiB
Go
126 lines
3.3 KiB
Go
package core
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"log/slog"
|
|
"os"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/hanzoai/dbx"
|
|
"github.com/hanzoai/base/tools/list"
|
|
"github.com/hanzoai/base/tools/logger"
|
|
)
|
|
|
|
func TestBaseAppLoggerLevelDevPrint(t *testing.T) {
|
|
testLogLevel := 4
|
|
|
|
scenarios := []struct {
|
|
name string
|
|
isDev bool
|
|
levels []int
|
|
printedLevels []int
|
|
persistedLevels []int
|
|
}{
|
|
{
|
|
"dev mode",
|
|
true,
|
|
[]int{testLogLevel - 1, testLogLevel, testLogLevel + 1},
|
|
[]int{testLogLevel - 1, testLogLevel, testLogLevel + 1},
|
|
[]int{testLogLevel, testLogLevel + 1},
|
|
},
|
|
{
|
|
"nondev mode",
|
|
false,
|
|
[]int{testLogLevel - 1, testLogLevel, testLogLevel + 1},
|
|
[]int{},
|
|
[]int{testLogLevel, testLogLevel + 1},
|
|
},
|
|
}
|
|
|
|
for _, s := range scenarios {
|
|
t.Run(s.name, func(t *testing.T) {
|
|
const testDataDir = "./hz_base_app_test_data_dir/"
|
|
defer os.RemoveAll(testDataDir)
|
|
|
|
app := NewBaseApp(BaseAppConfig{
|
|
DataDir: testDataDir,
|
|
IsDev: s.isDev,
|
|
})
|
|
defer app.ResetBootstrapState()
|
|
|
|
if err := app.Bootstrap(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// silence query logs
|
|
app.concurrentDB.(*dbx.DB).ExecLogFunc = func(ctx context.Context, t time.Duration, sql string, result sql.Result, err error) {}
|
|
app.concurrentDB.(*dbx.DB).QueryLogFunc = func(ctx context.Context, t time.Duration, sql string, rows *sql.Rows, err error) {}
|
|
app.nonconcurrentDB.(*dbx.DB).ExecLogFunc = func(ctx context.Context, t time.Duration, sql string, result sql.Result, err error) {}
|
|
app.nonconcurrentDB.(*dbx.DB).QueryLogFunc = func(ctx context.Context, t time.Duration, sql string, rows *sql.Rows, err error) {}
|
|
|
|
app.Settings().Logs.MinLevel = testLogLevel
|
|
if err := app.Save(app.Settings()); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
var printedLevels []int
|
|
var persistedLevels []int
|
|
|
|
ctx := context.Background()
|
|
|
|
// track printed logs
|
|
originalPrintLog := printLog
|
|
defer func() {
|
|
printLog = originalPrintLog
|
|
}()
|
|
printLog = func(log *logger.Log) {
|
|
printedLevels = append(printedLevels, int(log.Level))
|
|
}
|
|
|
|
// track persisted logs
|
|
app.OnModelAfterCreateSuccess("_logs").BindFunc(func(e *ModelEvent) error {
|
|
l, ok := e.Model.(*Log)
|
|
if ok {
|
|
persistedLevels = append(persistedLevels, l.Level)
|
|
}
|
|
return e.Next()
|
|
})
|
|
|
|
// write and persist logs
|
|
sl := app.SlogLogger()
|
|
for _, l := range s.levels {
|
|
sl.Log(ctx, slog.Level(l), "test")
|
|
}
|
|
handler, ok := sl.Handler().(*logger.BatchHandler)
|
|
if !ok {
|
|
t.Fatalf("Expected BatchHandler, got %v", sl.Handler())
|
|
}
|
|
if err := handler.WriteAll(ctx); err != nil {
|
|
t.Fatalf("Failed to write all logs: %v", err)
|
|
}
|
|
|
|
// check persisted log levels
|
|
if len(s.persistedLevels) != len(persistedLevels) {
|
|
t.Fatalf("Expected persisted levels \n%v\ngot\n%v", s.persistedLevels, persistedLevels)
|
|
}
|
|
for _, l := range persistedLevels {
|
|
if !list.ExistInSlice(l, s.persistedLevels) {
|
|
t.Fatalf("Missing expected persisted level %v in %v", l, persistedLevels)
|
|
}
|
|
}
|
|
|
|
// check printed log levels
|
|
if len(s.printedLevels) != len(printedLevels) {
|
|
t.Fatalf("Expected printed levels \n%v\ngot\n%v", s.printedLevels, printedLevels)
|
|
}
|
|
for _, l := range printedLevels {
|
|
if !list.ExistInSlice(l, s.printedLevels) {
|
|
t.Fatalf("Missing expected printed level %v in %v", l, printedLevels)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|