log

package
v0.2.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 27, 2026 License: Apache-2.0 Imports: 6 Imported by: 0

README

Log Package

The log package provides structured logging capabilities for Reglet WASM plugins using Go's standard log/slog package. It automatically routes all plugin logs to the host for centralized logging and observability.

Overview

This package initializes a custom slog.Handler that sends log records from the WASM plugin to the host through a dedicated host function. Plugin authors can use standard Go logging (slog) without needing to understand WASM boundaries.

Features

  • Standard Library Integration: Uses Go's log/slog package
  • Structured Logging: Full support for key-value attributes
  • Multiple Log Levels: Debug, Info, Warn, Error
  • Context Aware: Propagates context metadata to host
  • Zero Configuration: Automatically initialized via init()

Basic Usage

package main

import (
    "context"
    "log/slog"

    "github.com/reglet-dev/reglet-sdk/go"
    _ "github.com/reglet-dev/reglet-sdk/go/log" // Import to initialize
)

type MyPlugin struct{}

func (p *MyPlugin) Check(ctx context.Context, config sdk.Config) (sdk.Evidence, error) {
    // Simple logging
    slog.Info("Starting check")
    slog.Debug("Config received", "keys", len(config))

    // Warning and errors
    if someCondition {
        slog.Warn("Unexpected condition detected", "value", someValue)
    }

    if err != nil {
        slog.Error("Operation failed", "error", err)
        return sdk.Failure("error", err.Error()), nil
    }

    slog.Info("Check completed successfully")
    return sdk.Success(map[string]interface{}{"status": "ok"}), nil
}

Context-Aware Logging

All logging functions support context-aware variants:

func (p *MyPlugin) Check(ctx context.Context, config sdk.Config) (sdk.Evidence, error) {
    // Context is propagated to host
    slog.InfoContext(ctx, "Starting check with context")

    // Context values (like request ID) are included
    slog.DebugContext(ctx, "Processing config", "config_size", len(config))

    // Errors with context
    if err != nil {
        slog.ErrorContext(ctx, "Failed to process", "error", err)
    }

    return sdk.Success(nil), nil
}

Structured Attributes

Add structured key-value attributes to logs:

// Simple attributes
slog.Info("User action", "user_id", 123, "action", "login")

// Multiple attributes
slog.Debug("API call",
    "method", "GET",
    "url", "/api/status",
    "duration_ms", 45,
)

// Error with context
slog.Error("Database error",
    "query", "SELECT * FROM users",
    "error", err,
    "retry_count", 3,
)

Log Levels

Debug

Verbose information for debugging:

slog.Debug("Cache hit", "key", cacheKey, "ttl", ttl)
Info

General informational messages:

slog.Info("Plugin initialized", "version", "1.0.0")
Warn

Warning conditions that should be investigated:

slog.Warn("Slow operation", "duration_ms", 5000, "threshold_ms", 1000)
Error

Error conditions requiring attention:

slog.Error("Failed to connect", "host", "api.example.com", "error", err)

Advanced Usage

Log Groups

Group related attributes:

slog.Info("HTTP request",
    slog.Group("request",
        slog.String("method", "POST"),
        slog.String("path", "/api/users"),
        slog.Int("status", 201),
    ),
    slog.Group("timing",
        slog.Duration("total", totalTime),
        slog.Duration("db", dbTime),
    ),
)
Custom Attributes
// Using slog.Attr for custom types
slog.Info("Operation complete",
    slog.String("operation", "backup"),
    slog.Time("completed_at", time.Now()),
    slog.Bool("success", true),
    slog.Any("metadata", customStruct),
)
Conditional Logging
// Only log if debug enabled
if slog.Default().Enabled(context.Background(), slog.LevelDebug) {
    expensiveDebugInfo := computeDebugInfo()
    slog.Debug("Debug info", "data", expensiveDebugInfo)
}

Log Handler Details

The package provides a WasmLogHandler that implements slog.Handler:

type WasmLogHandler struct {
    // Configured as default handler via init()
}
Wire Format

Logs are serialized to JSON and sent to the host:

{
    "context": { /* context metadata */ },
    "level": "INFO",
    "message": "Operation completed",
    "timestamp": "2024-01-15T10:30:00Z",
    "attributes": {
        "duration_ms": 150,
        "user_id": 123
    },
    "source": {
        "file": "plugin.go",
        "line": 42,
        "function": "MyPlugin.Check"
    }
}

Initialization

The log package automatically initializes itself when imported:

import (
    _ "github.com/reglet-dev/reglet-sdk/go/log" // Initialize WASM logging
)

This sets up:

  1. Custom WasmLogHandler as the default slog handler
  2. Log level from environment or defaults to Info
  3. Wire format protocol for host communication

Best Practices

1. Use Appropriate Log Levels
// ✅ Good
slog.Debug("Cache lookup", "key", key)           // Development info
slog.Info("Plugin started", "version", version)  // Important events
slog.Warn("Retry attempt", "count", retryCount)  // Potential issues
slog.Error("Failed to save", "error", err)       // Actual errors

// ❌ Bad
slog.Info("Variable x = 42")                     // Too verbose for Info
slog.Error("User not found")                     // Expected condition, not an error
2. Add Context with Structured Attributes
// ✅ Good
slog.Info("User logged in", "user_id", userID, "ip", ipAddr)

// ❌ Bad
slog.Info(fmt.Sprintf("User %d logged in from %s", userID, ipAddr))
3. Use Context-Aware Functions
// ✅ Good
slog.InfoContext(ctx, "Processing request", "request_id", reqID)

// ❌ Less useful
slog.Info("Processing request", "request_id", reqID)
4. Log Errors with Context
// ✅ Good
slog.Error("Database query failed",
    "query", query,
    "error", err,
    "retry_count", retries,
)

// ❌ Bad
slog.Error(err.Error())
5. Avoid Sensitive Data
// ✅ Good
slog.Info("Authentication successful", "user_id", userID)

// ❌ Bad - Leaks credentials
slog.Debug("Auth request", "password", password, "token", token)

Performance Considerations

  1. Lazy Evaluation: Expensive log message construction is only performed if the log level is enabled

  2. Buffering: Log messages are buffered and sent to host asynchronously (host-side implementation)

  3. Attribute Limits: Avoid extremely large attribute values (host may truncate)

  4. Debug Logs: Disable debug logging in production for better performance

Common Patterns

Plugin Lifecycle Logging
func (p *MyPlugin) Check(ctx context.Context, config sdk.Config) (sdk.Evidence, error) {
    slog.InfoContext(ctx, "Check started", "plugin", p.Name())

    defer func() {
        slog.InfoContext(ctx, "Check completed", "plugin", p.Name())
    }()

    // ... plugin logic
}
Operation Timing
start := time.Now()
result, err := doExpensiveOperation()
duration := time.Since(start)

if duration > 5*time.Second {
    slog.Warn("Slow operation detected",
        "operation", "expensive_op",
        "duration_ms", duration.Milliseconds(),
    )
}
Error Recovery
defer func() {
    if r := recover(); r != nil {
        slog.Error("Plugin panic recovered",
            "panic", r,
            "stack", debug.Stack(),
        )
    }
}()

Limitations

  1. No Direct File Output: Logs always go to host, cannot write to files directly
  2. Log Level Control: Log level is controlled by host, not configurable in plugin
  3. Output Format: Output formatting (JSON, text, etc.) determined by host
  4. Performance: Cross-WASM-boundary logging has overhead compared to native logging

Comparison with Standard Logging

Feature WASM Plugin Native Go
slog API ✅ Full support ✅ Native
Custom handlers ❌ Fixed handler ✅ Configurable
File output ❌ Host-only ✅ Direct
Performance ⚠️ WASM overhead ✅ Native
Centralized logs ✅ Automatic ⚠️ Manual setup

See Also

Documentation

Overview

Package log provides structure logging (slog) adapted for Reglet SDK's WASM environment.

Package log provides structure logging (slog) adapted for Reglet SDK's WASM environment.

Package log provides structure logging (slog) adapted for Reglet SDK's WASM environment.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type HandlerOption

type HandlerOption func(*handlerConfig)

HandlerOption configures the WasmLogHandler.

func WithLevel

func WithLevel(level slog.Level) HandlerOption

WithLevel sets the minimum log level to report. Records below this level will be filtered on the guest side.

func WithSource

func WithSource(enabled bool) HandlerOption

WithSource enables reporting of source location (file/line).

type LogAttrWire

type LogAttrWire struct {
	Key   string `json:"key"`
	Type  string `json:"type"`  // "string", "int64", "bool", "float64", "time", "error", "any"
	Value string `json:"value"` // String representation of the value
}

LogAttrWire represents a single slog attribute for wire transfer.

type LogMessageWire

type LogMessageWire struct {
	Timestamp time.Time            `json:"timestamp"`       // 24 bytes
	Attrs     []LogAttrWire        `json:"attrs,omitempty"` // 24 bytes (slice)
	Level     string               `json:"level"`           // 16 bytes
	Message   string               `json:"message"`         // 16 bytes
	Context   entities.ContextWire `json:"context"`         // contains pointers, largest struct
}

LogMessageWire is the JSON wire format for a log message from Guest to Host.

type WasmLogHandler

type WasmLogHandler struct {
	// contains filtered or unexported fields
}

WasmLogHandler implements slog.Handler to route logs through a host function.

func NewHandler

func NewHandler(opts ...HandlerOption) *WasmLogHandler

NewHandler creates a new WasmLogHandler with the given options.

func (*WasmLogHandler) Enabled

func (h *WasmLogHandler) Enabled(_ context.Context, level slog.Level) bool

Enabled reports whether the handler handles records at the given level.

func (*WasmLogHandler) Handle

func (h *WasmLogHandler) Handle(_ context.Context, record slog.Record) error

Handle for non-WASM builds (e.g., host tests). This is a stub to allow the code to compile and basic tests to run.

func (*WasmLogHandler) WithAttrs

func (h *WasmLogHandler) WithAttrs(attrs []slog.Attr) slog.Handler

WithAttrs returns a new WasmLogHandler that includes the given attributes.

func (*WasmLogHandler) WithGroup

func (h *WasmLogHandler) WithGroup(name string) slog.Handler

WithGroup returns a new WasmLogHandler with the given group name.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL