Created
August 19, 2024 13:36
-
-
Save lxfontes/7a8d28a256a764cba2108600ad5d1aa7 to your computer and use it in GitHub Desktop.
wasi slog
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
// logger := slog.New(DefaultOptions().NewHandler()) | |
// a 'context' attribute will be promote to wasilog 'context' field | |
// logger = logger.With("context", "Get") | |
// | |
// logger.Info("Hello world") | |
// logger.Warn("Hello world 1", "key", "value") | |
// logger.Info("Hello world 2", slog.String("key", "value")) | |
// logger.Info("Hello world 3", slog.Any("key", 123), slog.String("context", "SomethingElse")) | |
// | |
// 2024-08-19T13:30:58.279639Z INFO log: wasmcloud_host::wasmbus::handler: Hello world component_id="demo_image_processor-task_manager" level=Level::Info context="Get" | |
// 2024-08-19T13:30:58.279860Z WARN log: wasmcloud_host::wasmbus::handler: key="value" Hello world 1 component_id="demo_image_processor-task_manager" level=Level::Warn context="Get" | |
// 2024-08-19T13:30:58.279950Z INFO log: wasmcloud_host::wasmbus::handler: key="value" Hello world 2 component_id="demo_image_processor-task_manager" level=Level::Info context="Get" | |
// 2024-08-19T13:30:58.280050Z INFO log: wasmcloud_host::wasmbus::handler: key="123" Hello world 3 component_id="demo_image_processor-task_manager" level=Level::Info context="SomethingElse" | |
import ( | |
"context" | |
"fmt" | |
"log/slog" | |
"strings" | |
slogcommon "github.com/samber/slog-common" | |
// need compiled wit with wasi logging | |
. "github.com/cosmonic-labs/wasmcloud.space/components/task-manager/gen" | |
) | |
type WasiLoggingOption struct { | |
// log level (default: debug) | |
Level slog.Leveler | |
// optional: fetch attributes from context | |
AttrFromContext []func(ctx context.Context) []slog.Attr | |
ReplaceAttr func(groups []string, a slog.Attr) slog.Attr | |
} | |
type WebassemblyHandler struct { | |
option WasiLoggingOption | |
attrs []slog.Attr | |
groups []string | |
} | |
var _ slog.Handler = (*WebassemblyHandler)(nil) | |
func wasiLevel(level slog.Level) WasiLoggingLoggingLevel { | |
switch level { | |
case slog.LevelDebug: | |
return WasiLoggingLoggingLevelDebug() | |
case slog.LevelInfo: | |
return WasiLoggingLoggingLevelInfo() | |
case slog.LevelWarn: | |
return WasiLoggingLoggingLevelWarn() | |
case slog.LevelError: | |
return WasiLoggingLoggingLevelError() | |
default: | |
return WasiLoggingLoggingLevelDebug() | |
} | |
} | |
func wasiConverter(replaceAttr func(groups []string, a slog.Attr) slog.Attr, loggerAttr []slog.Attr, groups []string, record *slog.Record) (string, string) { | |
attrs := slogcommon.AppendRecordAttrsToAttrs(loggerAttr, groups, record) | |
attrs = slogcommon.ReplaceAttrs(replaceAttr, []string{}, attrs...) | |
attrs = slogcommon.RemoveEmptyAttrs(attrs) | |
extra := slogcommon.AttrsToString(attrs...) | |
context, ok := extra["context"] | |
if ok { | |
delete(extra, "context") | |
} | |
var formattedAttrs []string | |
for k, v := range extra { | |
formattedAttrs = append(formattedAttrs, fmt.Sprintf("%s=%q", k, v)) | |
} | |
formattedAttrs = append(formattedAttrs, record.Message) | |
return strings.Join(formattedAttrs, " "), context | |
} | |
func DefaultOptions() WasiLoggingOption { | |
return WasiLoggingOption{ | |
Level: slog.LevelDebug, | |
AttrFromContext: []func(ctx context.Context) []slog.Attr{}, | |
} | |
} | |
func (o WasiLoggingOption) NewHandler() slog.Handler { | |
return &WebassemblyHandler{ | |
option: o, | |
} | |
} | |
func (h *WebassemblyHandler) Enabled(_ context.Context, level slog.Level) bool { | |
return level >= h.option.Level.Level() | |
} | |
func (h *WebassemblyHandler) Handle(ctx context.Context, record slog.Record) error { | |
fromContext := slogcommon.ContextExtractor(ctx, h.option.AttrFromContext) | |
message, logContext := wasiConverter(h.option.ReplaceAttr, append(h.attrs, fromContext...), h.groups, &record) | |
WasiLoggingLoggingLog(wasiLevel(record.Level), logContext, message) | |
return nil | |
} | |
func (h *WebassemblyHandler) WithAttrs(attrs []slog.Attr) slog.Handler { | |
return &WebassemblyHandler{ | |
option: h.option, | |
attrs: slogcommon.AppendAttrsToGroup(h.groups, h.attrs, attrs...), | |
groups: h.groups, | |
} | |
} | |
func (h *WebassemblyHandler) WithGroup(name string) slog.Handler { | |
// https://cs.opensource.google/go/x/exp/+/46b07846:slog/handler.go;l=247 | |
if name == "" { | |
return h | |
} | |
return &WebassemblyHandler{ | |
option: h.option, | |
attrs: h.attrs, | |
groups: append(h.groups, name), | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment