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.
128 lines
3.3 KiB
Go
128 lines
3.3 KiB
Go
package zap
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/hanzoai/base/core"
|
|
"github.com/hanzoai/base/tools/hook"
|
|
luxlog "github.com/luxfi/log"
|
|
zaplib "github.com/luxfi/zap"
|
|
)
|
|
|
|
// MustRegister registers the ZAP transport plugin with a Base app.
|
|
// Call this before app.Start().
|
|
func MustRegister(app core.App) {
|
|
MustRegisterWithConfig(app, DefaultConfig())
|
|
}
|
|
|
|
// MustRegisterWithConfig registers the ZAP transport plugin with custom config.
|
|
func MustRegisterWithConfig(app core.App, config Config) {
|
|
if !config.Enabled {
|
|
return
|
|
}
|
|
|
|
p := &plugin{
|
|
app: app,
|
|
config: config,
|
|
}
|
|
|
|
app.OnServe().Bind(&hook.Handler[*core.ServeEvent]{
|
|
Id: "__zapTransport__",
|
|
Func: func(e *core.ServeEvent) error {
|
|
if err := e.Next(); err != nil {
|
|
return err
|
|
}
|
|
p.start()
|
|
return nil
|
|
},
|
|
})
|
|
|
|
app.OnTerminate().Bind(&hook.Handler[*core.TerminateEvent]{
|
|
Id: "__zapTransportCleanup__",
|
|
Func: func(e *core.TerminateEvent) error {
|
|
p.stop()
|
|
return e.Next()
|
|
},
|
|
})
|
|
}
|
|
|
|
type plugin struct {
|
|
app core.App
|
|
config Config
|
|
node *zaplib.Node
|
|
logger luxlog.Logger
|
|
handler *handler
|
|
}
|
|
|
|
func (p *plugin) start() {
|
|
p.logger = luxlog.New("component", "zap")
|
|
p.logger.Info("starting ZAP transport", "port", p.config.Port, "nodeID", p.config.NodeID)
|
|
|
|
p.node = zaplib.NewNode(zaplib.NodeConfig{
|
|
NodeID: p.config.NodeID,
|
|
Port: p.config.Port,
|
|
ServiceType: p.config.ServiceType,
|
|
})
|
|
|
|
p.handler = newHandler(p.app, p.logger)
|
|
|
|
// Register message handlers
|
|
p.node.Handle(MsgTypeCollections, func(ctx context.Context, from string, msg *zaplib.Message) (*zaplib.Message, error) {
|
|
return p.handler.handleCollections(ctx, from, msg)
|
|
})
|
|
|
|
p.node.Handle(MsgTypeRecords, func(ctx context.Context, from string, msg *zaplib.Message) (*zaplib.Message, error) {
|
|
return p.handler.handleRecords(ctx, from, msg)
|
|
})
|
|
|
|
p.node.Handle(MsgTypeAuth, func(ctx context.Context, from string, msg *zaplib.Message) (*zaplib.Message, error) {
|
|
return p.handler.handleAuth(ctx, from, msg)
|
|
})
|
|
|
|
p.node.Handle(MsgTypeRealtime, func(ctx context.Context, from string, msg *zaplib.Message) (*zaplib.Message, error) {
|
|
return p.handler.handleRealtime(ctx, from, msg)
|
|
})
|
|
|
|
if err := p.node.Start(); err != nil {
|
|
p.logger.Error("failed to start ZAP node", "error", err)
|
|
return
|
|
}
|
|
|
|
// Give the handler a reference to the node for push notifications
|
|
p.handler.setNode(p.node)
|
|
|
|
// Hook into app record events for realtime broadcasting
|
|
p.app.OnRecordAfterCreateSuccess().Bind(&hook.Handler[*core.RecordEvent]{
|
|
Id: "__zapRealtimeCreate__",
|
|
Func: func(e *core.RecordEvent) error {
|
|
p.handler.broadcastEvent(e.Record.Collection().Name, "create", e.Record)
|
|
return e.Next()
|
|
},
|
|
})
|
|
|
|
p.app.OnRecordAfterUpdateSuccess().Bind(&hook.Handler[*core.RecordEvent]{
|
|
Id: "__zapRealtimeUpdate__",
|
|
Func: func(e *core.RecordEvent) error {
|
|
p.handler.broadcastEvent(e.Record.Collection().Name, "update", e.Record)
|
|
return e.Next()
|
|
},
|
|
})
|
|
|
|
p.app.OnRecordAfterDeleteSuccess().Bind(&hook.Handler[*core.RecordEvent]{
|
|
Id: "__zapRealtimeDelete__",
|
|
Func: func(e *core.RecordEvent) error {
|
|
p.handler.broadcastEvent(e.Record.Collection().Name, "delete", e.Record)
|
|
return e.Next()
|
|
},
|
|
})
|
|
|
|
p.logger.Info("ZAP transport listening", "port", p.config.Port, "discovery", p.config.ServiceType)
|
|
}
|
|
|
|
func (p *plugin) stop() {
|
|
if p.node != nil {
|
|
p.logger.Info("stopping ZAP transport")
|
|
p.node.Stop()
|
|
}
|
|
}
|