Version: Latest (main branch)
What happened?
Custom sinks cannot properly render message templates because internal/parser is not accessible outside the mtlog module. When implementing core.LogEventSink, there's no public API to render the MessageTemplate with Properties, forcing manual string replacement that breaks with capturing operators (@), scalar hints ($), and format specifiers.
Expected behavior
Custom sinks should be able to render message templates just like built-in sinks. Serilog provides LogEvent.RenderMessage() for this purpose. mtlog should provide equivalent functionality.
Minimal reproduction
package main
import (
"fmt"
"os"
"strings"
"github.com/willibrandon/mtlog"
"github.com/willibrandon/mtlog/core"
)
// Custom sink per README documentation
type CustomSink struct{}
func (s *CustomSink) Emit(event *core.LogEvent) {
// ❌ No way to properly render the message!
// event.MessageTemplate = "Config: {@Config}"
// event.Properties = {"Config": &config.Config{...}}
// Can't do this (internal package):
// tmpl, _ := parser.Parse(event.MessageTemplate)
// message := tmpl.Render(event.Properties)
// Only option: manual string replacement (broken):
message := event.MessageTemplate
for name, value := range event.Properties {
// Doesn't handle {@Property}, {$Property}, {Property:format}, etc.
placeholder := fmt.Sprintf("{%s}", name)
message = strings.ReplaceAll(message, placeholder, fmt.Sprintf("%v", value))
}
fmt.Fprintln(os.Stderr, message)
}
func main() {
logger := mtlog.New(mtlog.WithSink(&CustomSink{}))
cfg := map[string]any{"debug": true, "port": 8080}
// Outputs: "Config: {@Config}" (placeholder not replaced!)
logger.Debug("Config: {@Config}", cfg)
}
Environment
- Go version: go1.25.1
- OS: darwin/arm64
Additional context
Serilog solves this by providing LogEvent.RenderMessage() and public MessageTemplateTextFormatter. Suggested solution:
Add RenderMessage() method to core.LogEvent (Serilog-style, cleanest)
Current workaround in use: Manual replacement of {Property}, {@Property}, and {$Property} with strings.ReplaceAll, but this doesn't support format specifiers or alignment.
Version: Latest (main branch)
What happened?
Custom sinks cannot properly render message templates because
internal/parseris not accessible outside the mtlog module. When implementingcore.LogEventSink, there's no public API to render theMessageTemplatewithProperties, forcing manual string replacement that breaks with capturing operators (@), scalar hints ($), and format specifiers.Expected behavior
Custom sinks should be able to render message templates just like built-in sinks. Serilog provides
LogEvent.RenderMessage()for this purpose. mtlog should provide equivalent functionality.Minimal reproduction
Environment
Additional context
Serilog solves this by providing
LogEvent.RenderMessage()and publicMessageTemplateTextFormatter. Suggested solution:Add
RenderMessage()method tocore.LogEvent(Serilog-style, cleanest)Current workaround in use: Manual replacement of
{Property},{@Property}, and{$Property}withstrings.ReplaceAll, but this doesn't support format specifiers or alignment.