log

package module
v0.0.10 Latest Latest
Warning

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

Go to latest
Published: Sep 21, 2025 License: Apache-2.0 Imports: 24 Imported by: 43

README

Go-Spring :: Log

English | 中文

The project has been officially released, welcome to use!

Go-Spring :: Log is a high-performance and extensible logging library designed specifically for the Go programming language. It offers flexible and structured logging capabilities, including context field extraction, multi-level logging configuration, and multiple output options, making it ideal for a wide range of server-side applications.

Features

  • Multi-Level Logging: Supports standard log levels such as Trace, Debug, Info, Warn, Error, Panic, and Fatal, suitable for debugging and monitoring in various scenarios.
  • Structured Logging: Records logs in a structured format with key fields like trace_id and span_id, making them easy to parse and analyze by log aggregation systems.
  • Context Integration: Extracts additional information from context.Context (e.g., request ID, user ID) and automatically attaches them to log entries.
  • Tag-Based Logging: Introduces a tag system to distinguish logs across different modules or business lines.
  • Plugin Architecture:
    • Appender: Supports multiple output targets including console and file.
    • Layout: Provides both plain text and JSON formatting for log output.
    • Logger: Offers both synchronous and asynchronous loggers; asynchronous mode avoids blocking the main thread.
  • Performance Optimizations: Utilizes buffer management and event pooling to minimize memory allocation overhead.
  • Dynamic Configuration Reload: Supports runtime reloading of logging configurations from external files.
  • Well-Tested: All core modules are covered with unit tests to ensure stability and reliability.

Core Concepts

Tags

Tags are the core concept in this logging library, used to categorize logs. You can register tags via the RegisterTag function and match them with regular expressions. This approach enables a unified logging API without the need to explicitly create logger instances, even for third-party libraries, allowing them to write logs in a standardized way.

Logger

A Logger is the actual component that processes logs. You can retrieve a logger instance using the GetLogger function, mainly for backward compatibility with older projects. This allows you to fetch a logger by name and use the Write function to record pre-formatted messages.

Contextual Field Extraction

You can configure functions to extract contextual data from context.Context and include them in log entries:

  • StringFromContext: extracts string values from the context (e.g., request ID).
  • FieldsFromContext: returns structured fields from the context, such as trace ID or user ID.

Installation

go get github.com/go-spring/log

Quick Start

Here's a simple example demonstrating how to use Go-Spring :: Log:

package main

import (
	"context"

	"github.com/go-spring/log"
)

func main() {
	// Set the function to extract fields from context.
	// You may also use StringFromContext if only strings are needed.
	log.FieldsFromContext = func(ctx context.Context) []log.Field {
		return []log.Field{
			log.String("trace_id", "0a882193682db71edd48044db54cae88"),
			log.String("span_id", "50ef0724418c0a66"),
		}
	}

	// Load configuration file
	err := log.RefreshFile("log.xml")
	if err != nil {
		panic(err)
	}

	ctx := context.Background()

	// Record logs
	log.Infof(ctx, log.TagAppDef, "This is an info message")
	log.Errorf(ctx, log.TagBizDef, "This is an error message")

    // Log with structured fields
    log.Info(ctx, log.TagAppDef,
        log.String("key1", "value1"),
        log.Int("key2", 123),
        log.Msg("structured log message"),
    )
}

Configuration

Go-Spring :: Log supports defining logging behavior via XML, JSON, or YAML configuration files. For example:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
    <Properties>
        <Property name="LayoutBufferSize">100KB</Property>
    </Properties>
    <Appenders>
        <Console name="console">
            <JSONLayout bufferSize="${LayoutBufferSize}"/>
        </Console>
    </Appenders>
    <Loggers>
        <Root level="warn">
            <AppenderRef ref="console"/>
        </Root>
        <Logger name="logger" level="info" tags="_com_request_*">
            <AppenderRef ref="console"/>
        </Logger>
    </Loggers>
</Configuration>

Plugin Development

Go-Spring :: Log offers rich plugin interfaces for developers to easily implement custom Appender, Layout, and Logger components.

License

Go-Spring :: Log is licensed under the Apache License 2.0.

Documentation

Overview

Package log is a high-performance and extensible logging library designed specifically for the Go programming language. It provides flexible and structured logging capabilities, including context field extraction, multi-level logging configuration, and multiple output options, making it ideal for server-side applications.

## Core Concepts:

Tags:

Tags are a core concept in the log package used to categorize logs. By registering a tag via the `RegisterTag` function, you can use regular expressions to match the user-defined tags. This approach allows for a unified API for logging without explicitly creating logger instances. Even third-party libraries can write logs without setting up a logger object.

Loggers:

A Logger is the object that actually handles the logging process. You can obtain a logger instance using the `GetLogger` function, which is mainly provided for compatibility with legacy projects. This allows you to directly retrieve a logger by its name and log pre-formatted messages using the `Write` function.

Context Field Extraction:

Contextual data can be extracted and included in log entries via configurable functions: - `log.StringFromContext`: Extracts a string value (e.g., a request ID) from the context. - `log.FieldsFromContext`: Returns a list of structured fields from the context, such as trace IDs or user IDs.

Configuration from File:

The `log.RefreshFile` function allows loading the logger's configuration from an external file (e.g., XML or JSON).

Logger Initialization and Logging:

- Using `GetLogger`, you can fetch a logger instance (often for compatibility with older systems). - You can also register custom tags using `RegisterTag` to classify logs according to your needs.

Logging Messages:

The package provides various logging functions, such as `Tracef`, `Debugf`, `Infof`, `Warnf`, etc., which log messages at different levels (e.g., Trace, Debug, Info, Warn). These functions can either accept structured fields or formatted messages.

Structured Logging:

The logger also supports structured logging, where fields are captured as key-value pairs and logged with the message. The fields can be provided directly in the log functions or through a map.

## Examples:

Using a pre-registered tag:

log.Tracef(ctx, TagRequestOut, "hello %s", "world")
log.Debugf(ctx, TagRequestOut, "hello %s", "world")
log.Infof(ctx, TagRequestIn, "hello %s", "world")
log.Warnf(ctx, TagRequestIn, "hello %s", "world")
log.Errorf(ctx, TagRequestIn, "hello %s", "world")
log.Panicf(ctx, TagRequestIn, "hello %s", "world")
log.Fatalf(ctx, TagRequestIn, "hello %s", "world")

Using structured fields:

log.Trace(ctx, TagRequestOut, func() []log.Field {
	return []log.Field{
		log.Msgf("hello %s", "world"),
	}
})

log.Error(ctx, TagRequestIn, log.FieldsFromMap(map[string]any{
	"key1": "value1",
	"key2": "value2",
}))

Index

Constants

View Source
const (
	ValueTypeBool = ValueType(iota)
	ValueTypeInt64
	ValueTypeUint64
	ValueTypeFloat64
	ValueTypeString
	ValueTypeReflect
	ValueTypeArray
	ValueTypeObject
	ValueTypeFromMap
)
View Source
const (
	BufferFullPolicyBlock         = BufferFullPolicy(0) // Block until space is available
	BufferFullPolicyDiscard       = BufferFullPolicy(1) // Drop the new event or data
	BufferFullPolicyDiscardOldest = BufferFullPolicy(2) // Drop the oldest event or data
)
View Source
const MsgKey = "msg"
View Source
const RootLoggerName = "::ROOT::"

Variables

View Source
var (
	// TagAppDef is the default tag for application-related logs.
	TagAppDef = RegisterAppTag("def", "")

	// TagBizDef is the default tag for business-related logs.
	TagBizDef = RegisterBizTag("def", "")
)
View Source
var (
	// TimeNow is an overrideable function to provide custom timestamps.
	// For example, this can be replaced during testing to return a fixed time.
	TimeNow func(ctx context.Context) time.Time

	// StringFromContext is an optional hook to extract a string (e.g., trace ID)
	// from the context. This string will be attached to the log event.
	StringFromContext func(ctx context.Context) string

	// FieldsFromContext is an optional hook to extract structured fields
	// (e.g., trace ID, span ID, or request metadata) from the context.
	FieldsFromContext func(ctx context.Context) []Field
)
View Source
var (
	NoneLevel  = RegisterLevel(0, "NONE")    // No logging
	TraceLevel = RegisterLevel(100, "TRACE") // Very detailed logging, typically used for debugging at a granular level
	DebugLevel = RegisterLevel(200, "DEBUG") // Debugging information useful during development
	InfoLevel  = RegisterLevel(300, "INFO")  // General informational messages about application progress
	WarnLevel  = RegisterLevel(400, "WARN")  // Warnings about potential issues or unusual situations
	ErrorLevel = RegisterLevel(500, "ERROR") // Errors that allow the application to continue running
	PanicLevel = RegisterLevel(600, "PANIC") // Severe issues that may cause a panic in the application
	FatalLevel = RegisterLevel(700, "FATAL") // Critical issues that will terminate the application
)
View Source
var Caller = func(skip int, fast bool) (file string, line int) {

	if !fast {
		_, file, line, _ = runtime.Caller(skip + 1)
		return
	}

	rpc := make([]uintptr, 1)
	n := runtime.Callers(skip+2, rpc[:])
	if n < 1 {
		return
	}
	pc := rpc[0]
	if v, ok := frameCache.Load(pc); ok {
		e := v.(*runtime.Frame)
		return e.File, e.Line
	}
	frame, _ := runtime.CallersFrames(rpc).Next()
	frameCache.Store(pc, &frame)
	return frame.File, frame.Line
}

Caller returns the file name and line number of the calling function. If 'fast' is true, it uses a cache to speed up the lookup.

View Source
var Stdout io.Writer = os.Stdout

Stdout is the standard output stream used by appenders.

Functions

func BuildTag added in v0.0.4

func BuildTag(mainType, subType, action string) string

BuildTag constructs a structured tag string from main type, sub type, and action. The format is:

_<mainType>_<subType>
_<mainType>_<subType>_<action>

Example:

BuildTag("app", "startup", "init") -> "_app_startup_init"

func Debug

func Debug(ctx context.Context, tag *Tag, fn func() []Field)

Debug logs at DebugLevel using a tag and a lazy field generator function. The function fn() is only executed if DebugLevel logging is enabled.

func Debugf

func Debugf(ctx context.Context, tag *Tag, format string, args ...any)

Debugf logs at DebugLevel using a tag and a formatted message. Message formatting is only performed if DebugLevel logging is enabled.

func Destroy added in v0.0.5

func Destroy()

Destroy stops all loggers and appenders and resets global state.

func EncodeFields added in v0.0.10

func EncodeFields(enc Encoder, fields []Field)

EncodeFields encodes a slice of Fields into the Encoder.

func Error

func Error(ctx context.Context, tag *Tag, fields ...Field)

Error logs at ErrorLevel with structured fields.

func Errorf

func Errorf(ctx context.Context, tag *Tag, format string, args ...any)

Errorf logs at ErrorLevel using a formatted message.

func Fatal

func Fatal(ctx context.Context, tag *Tag, fields ...Field)

Fatal logs at FatalLevel with structured fields.

func Fatalf

func Fatalf(ctx context.Context, tag *Tag, format string, args ...any)

Fatalf logs at FatalLevel using a formatted message.

func FormatError added in v0.0.10

func FormatError(err error, format string, args ...any) error

FormatError formats an error message and wraps it around the given error.

func GetAllTags

func GetAllTags() []string

GetAllTags returns the names of all registered tags.

func Info

func Info(ctx context.Context, tag *Tag, fields ...Field)

Info logs at InfoLevel with structured fields.

func Infof

func Infof(ctx context.Context, tag *Tag, format string, args ...any)

Infof logs at InfoLevel using a formatted message.

func NewPlugin

func NewPlugin(t reflect.Type, prefix string, s *barky.Storage) (reflect.Value, error)

NewPlugin creates a new plugin instance and injects configuration values.

func Panic

func Panic(ctx context.Context, tag *Tag, fields ...Field)

Panic logs at PanicLevel with structured fields.

func Panicf

func Panicf(ctx context.Context, tag *Tag, format string, args ...any)

Panicf logs at PanicLevel using a formatted message.

func Ptr

func Ptr[T any](i T) *T

Ptr returns a pointer to the given value.

func PutEvent

func PutEvent(e *Event)

PutEvent resets the given Event and returns it to the pool for reuse.

func ReadJSON added in v0.0.6

func ReadJSON(b []byte) (map[string]any, error)

ReadJSON parses a JSON file into a map.

func ReadProperties added in v0.0.6

func ReadProperties(b []byte) (map[string]any, error)

ReadProperties parses a properties file into a map.

func ReadXML added in v0.0.6

func ReadXML(b []byte) (map[string]any, error)

ReadXML parses an XML configuration file into a map.

func ReadYAML added in v0.0.6

func ReadYAML(b []byte) (map[string]any, error)

ReadYAML parses a YAML file into a map.

func Record

func Record(ctx context.Context, level Level, tag *Tag, skip int, fields ...Field)

Record is the core logging function.

Responsibilities:

  1. Check whether the logger is enabled for the given level.
  2. Capture caller information (file, line). When fastCaller is enabled, a faster but less precise lookup is used.
  3. Determine the log timestamp, either via TimeNow (if set) or time.Now().
  4. Extract context-based metadata via StringFromContext and FieldsFromContext.
  5. Populate a pooled Event object with all gathered data.
  6. Publish the Event to the logger.

func RefreshConfig added in v0.0.6

func RefreshConfig(s *barky.Storage) error

RefreshConfig loads a logging configuration from a *barky.Storage object.

func RefreshFile

func RefreshFile(fileName string) error

RefreshFile loads a logging configuration from a file by its name.

func RefreshReader

func RefreshReader(r io.Reader, ext string) error

RefreshReader loads a logging configuration from an io.Reader.

func RegisterConverter

func RegisterConverter[T any](fn Converter[T])

RegisterConverter registers a custom converter for type T.

func RegisterPlugin

func RegisterPlugin[T any](name string, typ PluginType)

RegisterPlugin registers a plugin type T with a given name and plugin type.

func RegisterProperty added in v0.0.5

func RegisterProperty(key string, val func(string) error)

RegisterProperty registers a property setter function with a given key.

func RegisterReader

func RegisterReader(r Reader, ext ...string)

RegisterReader registers a Reader function for one or more file extensions.

func Trace

func Trace(ctx context.Context, tag *Tag, fn func() []Field)

Trace logs at TraceLevel using a tag and a lazy field generator function. The function fn() is only executed if TraceLevel logging is enabled.

func Tracef

func Tracef(ctx context.Context, tag *Tag, format string, args ...any)

Tracef logs at TraceLevel using a tag and a formatted message. Message formatting is only performed if TraceLevel logging is enabled.

func Warn

func Warn(ctx context.Context, tag *Tag, fields ...Field)

Warn logs at WarnLevel with structured fields.

func Warnf

func Warnf(ctx context.Context, tag *Tag, format string, args ...any)

Warnf logs at WarnLevel using a formatted message.

func WrapError

func WrapError(err error, format string, args ...any) error

WrapError wraps an existing error, creating a new error with hierarchical relationships.

func WriteLogString

func WriteLogString(buf *bytes.Buffer, s string)

WriteLogString escapes and writes a string according to JSON rules.

Types

type Appender

type Appender interface {
	Lifecycle        // Appenders must be startable and stoppable
	GetName() string // Returns the appender name
	Append(e *Event) // Handles writing a log event
	Write(b []byte)  // Directly writes a byte slice
}

Appender is an interface that defines components that handle log output.

type AppenderBase added in v0.0.10

type AppenderBase struct {
	Name   string `PluginAttribute:"name"` // Appender name from config
	Layout Layout `PluginElement:"Layout"` // Layout defines how logs are formatted
}

AppenderBase provides common configuration and default behavior for appenders.

func (*AppenderBase) Append added in v0.0.10

func (c *AppenderBase) Append(e *Event)

func (*AppenderBase) GetName added in v0.0.10

func (c *AppenderBase) GetName() string

func (*AppenderBase) Start added in v0.0.10

func (c *AppenderBase) Start() error

func (*AppenderBase) Stop added in v0.0.10

func (c *AppenderBase) Stop()

func (*AppenderBase) Write added in v0.0.10

func (c *AppenderBase) Write(b []byte)

type AppenderRef

type AppenderRef struct {
	Ref string `PluginAttribute:"ref"`
	// contains filtered or unexported fields
}

AppenderRef represents a reference to an appender by name. The actual appender is resolved and injected later during configuration.

type ArrayValue

type ArrayValue interface {
	EncodeArray(enc Encoder)
}

ArrayValue is an interface for types that can be encoded as array.

type AsyncLogger added in v0.0.4

type AsyncLogger struct {
	LoggerBase
	BufferSize       int              `PluginAttribute:"bufferSize,default=10000"`
	BufferFullPolicy BufferFullPolicy `PluginAttribute:"bufferFullPolicy,default=Discard"`
	// contains filtered or unexported fields
}

AsyncLogger is an asynchronous logger that buffers events and processes them in a dedicated background goroutine.

func (*AsyncLogger) GetDiscardCounter added in v0.0.5

func (c *AsyncLogger) GetDiscardCounter() int64

GetDiscardCounter returns the total number of discarded events and data.

func (*AsyncLogger) Publish added in v0.0.4

func (c *AsyncLogger) Publish(e *Event)

Publish enqueues a log event into the buffer. Behavior on full buffer depends on BufferFullPolicy.

func (*AsyncLogger) Start added in v0.0.4

func (c *AsyncLogger) Start() error

Start initializes channels and launches the worker goroutine.

func (*AsyncLogger) Stop added in v0.0.4

func (c *AsyncLogger) Stop()

Stop gracefully shuts down the async logger. It signals the worker goroutine to exit and waits for it. NOTE: Stop must be called only once, otherwise panic may occur.

func (*AsyncLogger) Write added in v0.0.4

func (c *AsyncLogger) Write(b []byte) (n int, err error)

Write enqueues raw bytes into the buffer. Behavior on full buffer depends on BufferFullPolicy.

type BaseLayout

type BaseLayout struct {
	FileLineLength int `PluginAttribute:"fileLineLength,default=48"`
}

BaseLayout provides common functionality for layouts.

func (*BaseLayout) GetBuffer

func (c *BaseLayout) GetBuffer() *bytes.Buffer

GetBuffer returns a buffer from the pool (or a new one if empty).

func (*BaseLayout) GetFileLine

func (c *BaseLayout) GetFileLine(e *Event) string

GetFileLine returns "file:line" string for the log event. If the string is too long, it is truncated and prefixed with "...".

func (*BaseLayout) PutBuffer

func (c *BaseLayout) PutBuffer(buf *bytes.Buffer)

PutBuffer resets and returns a buffer to the pool, but only if it does not exceed the configured capacity.

type BufferFullPolicy added in v0.0.5

type BufferFullPolicy int

BufferFullPolicy specifies what to do when an async buffer is full.

func ParseBufferFullPolicy added in v0.0.5

func ParseBufferFullPolicy(s string) (BufferFullPolicy, error)

ParseBufferFullPolicy converts a string to a BufferFullPolicy.

type ConsoleAppender

type ConsoleAppender struct {
	AppenderBase
}

ConsoleAppender writes formatted log events to stdout.

func (*ConsoleAppender) Append

func (c *ConsoleAppender) Append(e *Event)

Append formats the event and writes it to standard output.

func (*ConsoleAppender) Write added in v0.0.4

func (c *ConsoleAppender) Write(b []byte)

Write writes a byte slice directly to the stdout. Errors are deliberately ignored.

type Converter

type Converter[T any] func(string) (T, error)

Converter defines a function that converts a string to type T.

type DiscardAppender

type DiscardAppender struct {
	AppenderBase
}

DiscardAppender ignores all log events (no output).

type Encoder

type Encoder interface {
	AppendEncoderBegin()
	AppendEncoderEnd()
	AppendObjectBegin()
	AppendObjectEnd()
	AppendArrayBegin()
	AppendArrayEnd()
	AppendKey(key string)
	AppendBool(v bool)
	AppendInt64(v int64)
	AppendUint64(v uint64)
	AppendFloat64(v float64)
	AppendString(v string)
	AppendReflect(v any)
}

Encoder defines the interface for structured logging encoders. Implementations control how log fields are serialized (e.g. JSON, text).

type Event

type Event struct {
	Level     Level     // The severity level of the log (e.g., INFO, ERROR, DEBUG)
	Time      time.Time // The timestamp when the event occurred
	File      string    // The source file where the log was triggered
	Line      int       // The line number in the source file
	Tag       string    // A tag used to categorize the log (e.g., subsystem name)
	Fields    []Field   // Custom fields provided specifically for this log event
	CtxString string    // String representation extracted from the context (e.g., trace ID)
	CtxFields []Field   // Additional structured fields extracted from the context (e.g., request ID, user ID)
}

Event represents a single log entry. It contains both the log message context (e.g., time, file, line, tag) and structured metadata (fields and context values).

func GetEvent

func GetEvent() *Event

GetEvent retrieves an *Event from the pool. If the pool is empty, a new Event will be created.

func (*Event) Reset

func (e *Event) Reset()

Reset clears the Event's fields so the instance can be reused.

type Field

type Field struct {
	Key  string    // The field key
	Type ValueType // The type of the value
	Num  uint64    // Holds numeric values or length/bit-representation
	Any  any       // Holds pointers, references, or arbitrary values
}

Field represents a structured log field with a key and a typed value.

func Any

func Any(key string, value any) Field

Any creates a Field from a value of any type by inspecting its dynamic type. It dispatches to the appropriate typed constructor based on the actual value. If the type is not explicitly handled, it falls back to using Reflect.

func Array

func Array(key string, val ArrayValue) Field

Array creates a Field with array type, using the ArrayValue interface.

func Bool

func Bool(key string, val bool) Field

Bool creates a Field for a boolean value.

func BoolPtr

func BoolPtr(key string, val *bool) Field

BoolPtr creates a Field from a *bool, or Nil if pointer is nil.

func Bools

func Bools(key string, val []bool) Field

Bools creates a Field with a slice of booleans.

func FieldsFromMap added in v0.0.4

func FieldsFromMap(m map[string]any) Field

FieldsFromMap creates a special Field that wraps a map[string]any. When encoded, it expands the map into individual key-value fields. This allows existing map structures to be easily converted into log fields without manually iterating through the map and adding each field individually.

func Float

func Float[T FloatType](key string, val T) Field

Float creates a Field for a float value.

func FloatPtr

func FloatPtr[T FloatType](key string, val *T) Field

FloatPtr creates a Field from a *float, or Nil if pointer is nil.

func Floats

func Floats[T FloatType](key string, val []T) Field

Floats creates a Field with a slice of float32 values.

func Int

func Int[T IntType](key string, val T) Field

Int creates a Field for an integer value.

func IntPtr

func IntPtr[T IntType](key string, val *T) Field

IntPtr creates a Field from a *int, or Nil if pointer is nil.

func Ints

func Ints[T IntType](key string, val []T) Field

Ints creates a Field with a slice of integers.

func Msg

func Msg(msg string) Field

Msg creates a string Field with the fixed key "msg".

func Msgf

func Msgf(format string, args ...any) Field

Msgf formats a message and creates a Field with the fixed key "msg".

func Nil

func Nil(key string) Field

Nil creates a Field whose value is nil (Type = ValueTypeReflect).

func Object

func Object(key string, fields ...Field) Field

Object creates a Field containing a variadic slice of Fields, treated as a nested object.

func Reflect

func Reflect(key string, val any) Field

Reflect wraps any value into a Field using reflection.

func String

func String(key string, val string) Field

String creates a Field for a string value.

func StringPtr

func StringPtr(key string, val *string) Field

StringPtr creates a Field from a *string, or Nil if pointer is nil.

func Strings

func Strings(key string, val []string) Field

Strings creates a Field with a slice of strings.

func Uint

func Uint[T UintType](key string, val T) Field

Uint creates a Field for an unsigned integer value.

func UintPtr

func UintPtr[T UintType](key string, val *T) Field

UintPtr creates a Field from a *uint, or Nil if pointer is nil.

func Uints

func Uints[T UintType](key string, val []T) Field

Uints creates a Field with a slice of unsigned integers.

func (Field) Encode

func (f Field) Encode(enc Encoder)

Encode encodes the Field into the Encoder based on its type.

type FileAppender

type FileAppender struct {
	AppenderBase
	FileName string `PluginAttribute:"fileName"`
	// contains filtered or unexported fields
}

FileAppender writes formatted log events to a specified file.

func (*FileAppender) Append

func (c *FileAppender) Append(e *Event)

Append formats the log event and writes it to the file.

func (*FileAppender) Start

func (c *FileAppender) Start() error

Start opens the log file for appending.

func (*FileAppender) Stop

func (c *FileAppender) Stop()

Stop flushes and closes the file.

func (*FileAppender) Write added in v0.0.4

func (c *FileAppender) Write(b []byte)

Write writes a byte slice directly to the file. Errors are deliberately ignored.

type FloatType

type FloatType interface {
	~float32 | ~float64
}

FloatType is the type of float32, float64.

type HumanizeBytes

type HumanizeBytes int

HumanizeBytes represents a human-readable byte size

func ParseHumanizeBytes

func ParseHumanizeBytes(s string) (HumanizeBytes, error)

ParseHumanizeBytes converts a human-readable byte string (e.g., "10KB") to an integer.

type IntType

type IntType interface {
	~int | ~int8 | ~int16 | ~int32 | ~int64
}

IntType is the type of int, int8, int16, int32, int64.

type JSONEncoder

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

JSONEncoder encodes log fields into standard JSON format.

func NewJSONEncoder

func NewJSONEncoder(buf *bytes.Buffer) *JSONEncoder

NewJSONEncoder creates a new JSONEncoder.

func (*JSONEncoder) AppendArrayBegin

func (enc *JSONEncoder) AppendArrayBegin()

AppendArrayBegin writes the beginning of a JSON array.

func (*JSONEncoder) AppendArrayEnd

func (enc *JSONEncoder) AppendArrayEnd()

AppendArrayEnd writes the end of a JSON array.

func (*JSONEncoder) AppendBool

func (enc *JSONEncoder) AppendBool(v bool)

AppendBool writes a boolean value.

func (*JSONEncoder) AppendEncoderBegin

func (enc *JSONEncoder) AppendEncoderBegin()

AppendEncoderBegin writes the start of an encoder section.

func (*JSONEncoder) AppendEncoderEnd

func (enc *JSONEncoder) AppendEncoderEnd()

AppendEncoderEnd writes the end of an encoder section.

func (*JSONEncoder) AppendFloat64

func (enc *JSONEncoder) AppendFloat64(v float64)

AppendFloat64 writes a float64 value.

func (*JSONEncoder) AppendInt64

func (enc *JSONEncoder) AppendInt64(v int64)

AppendInt64 writes an int64 value.

func (*JSONEncoder) AppendKey

func (enc *JSONEncoder) AppendKey(key string)

AppendKey writes a JSON key.

func (*JSONEncoder) AppendObjectBegin

func (enc *JSONEncoder) AppendObjectBegin()

AppendObjectBegin writes the beginning of a JSON object.

func (*JSONEncoder) AppendObjectEnd

func (enc *JSONEncoder) AppendObjectEnd()

AppendObjectEnd writes the end of a JSON object.

func (*JSONEncoder) AppendReflect

func (enc *JSONEncoder) AppendReflect(v any)

AppendReflect marshals any Go value to JSON and writes it. If marshalling fails, the error message is written as a string.

func (*JSONEncoder) AppendString

func (enc *JSONEncoder) AppendString(v string)

AppendString writes a string value with proper escaping.

func (*JSONEncoder) AppendUint64

func (enc *JSONEncoder) AppendUint64(u uint64)

AppendUint64 writes an uint64 value.

func (*JSONEncoder) Reset

func (enc *JSONEncoder) Reset()

Reset resets the encoder's state.

type JSONLayout

type JSONLayout struct {
	BaseLayout
}

JSONLayout formats a log event as a structured JSON object.

func (*JSONLayout) ToBytes

func (c *JSONLayout) ToBytes(e *Event) []byte

ToBytes converts a log event to JSON representation.

type JSONTokenType added in v0.0.10

type JSONTokenType int

JSONTokenType represents the type of the last token written to JSONEncoder. It is used to determine when separators (commas) are required.

const (
	JSONTokenUnknown JSONTokenType = iota
	JSONTokenObjectBegin
	JSONTokenObjectEnd
	JSONTokenArrayBegin
	JSONTokenArrayEnd
	JSONTokenKey
	JSONTokenValue
)

type Layout

type Layout interface {
	ToBytes(e *Event) []byte
}

Layout defines how a log event is formatted into bytes.

type Level

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

Level represents a logging severity level. Each level has a numeric code (for comparison) and a string name (for display).

func ParseLevel

func ParseLevel(s string) (Level, error)

ParseLevel converts a string into a Level (case-insensitive). Returns an error if the string does not match any registered Level.

func RegisterLevel added in v0.0.6

func RegisterLevel(code int32, name string) Level

RegisterLevel defines a new logging Level with the given code and name. The Level is also stored in the global levels map for string lookups. Name is normalized to uppercase for consistency.

func (Level) Code added in v0.0.6

func (l Level) Code() int32

Code returns the numeric code of the Level. Levels with higher codes represent higher severity.

func (Level) String

func (l Level) String() string

String returns the string representation of the Level (e.g., "INFO").

type Lifecycle

type Lifecycle interface {
	Start() error
	Stop()
}

Lifecycle is an optional interface for plugin lifecycle hooks.

type Logger

type Logger interface {
	Lifecycle                          // Start/Stop methods
	GetName() string                   // Get the name of the logger
	Publish(e *Event)                  // Send events to appenders
	EnableLevel(level Level) bool      // Whether a log level is enabled
	Write(b []byte) (n int, err error) // Write raw bytes to appenders
}

Logger is the interface implemented by all loggers.

type LoggerBase added in v0.0.10

type LoggerBase struct {
	Name         string         `PluginAttribute:"name"`          // Logger name
	Level        Level          `PluginAttribute:"level"`         // Log level
	Tags         string         `PluginAttribute:"tags,default="` // Optional tags
	AppenderRefs []*AppenderRef `PluginElement:"AppenderRef"`     // Attached appenders
}

LoggerBase contains fields shared by all logger configurations.

func (*LoggerBase) EnableLevel added in v0.0.10

func (c *LoggerBase) EnableLevel(level Level) bool

EnableLevel checks if the given log level is enabled for this logger.

func (*LoggerBase) GetName added in v0.0.10

func (c *LoggerBase) GetName() string

GetName returns the name of the logger.

type LoggerHolder added in v0.0.5

type LoggerHolder struct {
	Logger
}

LoggerHolder wraps a Logger in order to store it in atomic.Value. This ensures type safety while using atomic operations.

type LoggerWrapper added in v0.0.4

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

LoggerWrapper wraps a Logger instance and allows atomic replacement of the underlying Logger at runtime. This ensures that concurrent readers always see a consistent Logger reference without needing locks.

func GetLogger added in v0.0.4

func GetLogger(name string) *LoggerWrapper

GetLogger retrieves an existing LoggerWrapper by name, or creates a new one if it does not exist yet.

This function must be called only during the initialization phase. It panics if called after global.init is set, indicating that the logging system has already been finalized.

func GetRootLogger added in v0.0.5

func GetRootLogger() *LoggerWrapper

GetRootLogger retrieves the root LoggerWrapper instance.

func (*LoggerWrapper) Write added in v0.0.4

func (m *LoggerWrapper) Write(b []byte) (n int, err error)

Write forwards the given byte slice to the currently active Logger. Implements the io.Writer interface.

type Plugin

type Plugin struct {
	Name  string       // Name of the plugin
	Type  PluginType   // Type of the plugin
	Class reflect.Type // Underlying struct type
	File  string       // File where plugin was registered
	Line  int          // Line number where plugin was registered
}

Plugin represents metadata about a plugin type.

type PluginTag

type PluginTag string

PluginTag is a wrapper for parsing struct field tags.

func (PluginTag) Get

func (tag PluginTag) Get(key string) string

Get returns the value for a key or the first unnamed value.

func (PluginTag) Lookup

func (tag PluginTag) Lookup(key string) (value string, ok bool)

Lookup returns the value of a key in a tag and a boolean indicating existence.

type PluginType

type PluginType string

PluginType represents different types of plugins.

const (
	PluginTypeProperty    PluginType = "Property"
	PluginTypeAppender    PluginType = "Appender"
	PluginTypeLayout      PluginType = "Layout"
	PluginTypeAppenderRef PluginType = "AppenderRef"
	PluginTypeRoot        PluginType = "Root"
	PluginTypeAsyncRoot   PluginType = "AsyncRoot"
	PluginTypeLogger      PluginType = "Logger"
	PluginTypeAsyncLogger PluginType = "AsyncLogger"
)

type Reader

type Reader func([]byte) (map[string]any, error)

Reader defines a function that converts a byte slice into a map.

type SyncLogger added in v0.0.4

type SyncLogger struct {
	LoggerBase
}

SyncLogger is a synchronous logger that immediately forwards events to appenders.

func (*SyncLogger) Publish added in v0.0.4

func (c *SyncLogger) Publish(e *Event)

Publish sends the event directly to appenders (blocking).

func (*SyncLogger) Start added in v0.0.4

func (c *SyncLogger) Start() error

func (*SyncLogger) Stop added in v0.0.4

func (c *SyncLogger) Stop()

func (*SyncLogger) Write added in v0.0.4

func (c *SyncLogger) Write(b []byte) (n int, err error)

Write writes raw bytes directly to appenders.

type Tag

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

Tag represents a named log tag, used to categorize logs by subsystem, business domain, or RPC interaction, and so on. Each Tag holds a reference to a Logger, which can be atomically replaced.

func RegisterAppTag added in v0.0.4

func RegisterAppTag(subType, action string) *Tag

RegisterAppTag registers or retrieves a Tag intended for application-layer logs.

  • subType: component or module name
  • action: lifecycle phase or behavior (optional)

func RegisterBizTag added in v0.0.4

func RegisterBizTag(subType, action string) *Tag

RegisterBizTag registers or retrieves a Tag intended for business-logic logs.

  • subType: business domain or feature name
  • action: operation being logged (optional)

func RegisterRPCTag added in v0.0.4

func RegisterRPCTag(subType, action string) *Tag

RegisterRPCTag registers or retrieves a Tag intended for RPC logs, covering external/internal dependency interactions.

  • subType: protocol or target system (e.g., http, grpc, redis)
  • action: RPC phase (e.g., send, retry, fail)

func RegisterTag added in v0.0.4

func RegisterTag(tag string) *Tag

RegisterTag retrieves or creates a Tag by name. If the tag is not yet registered, it is associated with initLogger. Panics if called after global.init is set (i.e., after logging refresh).

Normally, higher-level helpers like RegisterAppTag, RegisterBizTag, or RegisterRPCTag should be used to ensure semantic consistency.

type TextEncoder

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

TextEncoder encodes fields as "key=value" pairs separated by a delimiter. Nested arrays/objects are serialized as JSON using an internal JSONEncoder.

func NewTextEncoder

func NewTextEncoder(buf *bytes.Buffer, separator string) *TextEncoder

NewTextEncoder creates a new TextEncoder, using the specified separator.

func (*TextEncoder) AppendArrayBegin

func (enc *TextEncoder) AppendArrayBegin()

AppendArrayBegin signals the start of a JSON array. Increments the depth and delegates to the JSON encoder.

func (*TextEncoder) AppendArrayEnd

func (enc *TextEncoder) AppendArrayEnd()

AppendArrayEnd signals the end of a JSON array. Decrements the depth and resets the JSON encoder if back to top level.

func (*TextEncoder) AppendBool

func (enc *TextEncoder) AppendBool(v bool)

AppendBool appends a boolean value, using JSON encoder if nested.

func (*TextEncoder) AppendEncoderBegin

func (enc *TextEncoder) AppendEncoderBegin()

AppendEncoderBegin writes the start of an encoder section.

func (*TextEncoder) AppendEncoderEnd

func (enc *TextEncoder) AppendEncoderEnd()

AppendEncoderEnd writes the end of an encoder section.

func (*TextEncoder) AppendFloat64

func (enc *TextEncoder) AppendFloat64(v float64)

AppendFloat64 appends a float64 value, using JSON encoder if nested.

func (*TextEncoder) AppendInt64

func (enc *TextEncoder) AppendInt64(v int64)

AppendInt64 appends an int64 value, using JSON encoder if nested.

func (*TextEncoder) AppendKey

func (enc *TextEncoder) AppendKey(key string)

AppendKey appends a key for a key-value pair. If inside a JSON structure, the key is handled by the JSON encoder. Otherwise, it's written directly with proper separator handling.

func (*TextEncoder) AppendObjectBegin

func (enc *TextEncoder) AppendObjectBegin()

AppendObjectBegin signals the start of a JSON object. Increments the depth and delegates to the JSON encoder.

func (*TextEncoder) AppendObjectEnd

func (enc *TextEncoder) AppendObjectEnd()

AppendObjectEnd signals the end of a JSON object. Decrements the depth and resets the JSON encoder if back to top level.

func (*TextEncoder) AppendReflect

func (enc *TextEncoder) AppendReflect(v any)

AppendReflect uses reflection to marshal any value as JSON. If nested, delegates to JSON encoder.

func (*TextEncoder) AppendString

func (enc *TextEncoder) AppendString(v string)

AppendString appends a string value, using JSON encoder if nested.

func (*TextEncoder) AppendUint64

func (enc *TextEncoder) AppendUint64(v uint64)

AppendUint64 appends a uint64 value, using JSON encoder if nested.

type TextLayout

type TextLayout struct {
	BaseLayout
}

TextLayout formats a log event as a human-readable text line.

func (*TextLayout) ToBytes

func (c *TextLayout) ToBytes(e *Event) []byte

ToBytes converts a log event into a plain-text line with separators.

type UintType

type UintType interface {
	~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64
}

UintType is the type of uint, uint8, uint16, uint32, uint64.

type ValueType

type ValueType int

ValueType represents the underlying type stored in a Field. The Type determines how Num and Any should be interpreted.

Jump to

Keyboard shortcuts

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