loggie

package module
v0.2.3 Latest Latest
Warning

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

Go to latest
Published: May 4, 2025 License: MIT Imports: 5 Imported by: 0

README ΒΆ

loggie 🧠⚑️ β€” Context-Aware Logger for Go

Context-aware, pluggable logger for Go web applications.
No more passing logger through every function β€” just use context.Context.


πŸš€ What is loggie?

loggie helps you embed a structured logger inside context.Context, so you can log from any layer β€” service, repository, or handler β€” with a consistent trace_id, user_id, or any custom field.

It supports Zap, Logrus (new!), and is ready for OpenTelemetry (OTEL).


✨ Features

βœ… Structured logging via context.Context
βœ… Auto-generated trace_id per request
βœ… OTEL-compatible (detects trace_id from OpenTelemetry spans)
βœ… Custom fields (e.g. user_id, order_id)
βœ… Middleware for Fiber / Gin / Echo
βœ… Pluggable backends: Zap, Logrus, Slog (soon)
βœ… Fallback logger included (safe anywhere)
βœ… Works with Fx lifecycle & context.WithTimeout


πŸ“¦ Installation

go get github.com/ditthkr/loggie

🧱 Architecture

               β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
               β”‚ context.Context    β”‚
               β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                        β”‚
                β”Œβ”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”
                β”‚ loggie.Logger  │◄── (interface)
                β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                        β”‚
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β–Ό               β–Ό                β–Ό
  ZapLogger        LogrusLogger       SlogLogger
(βœ… ready)         (βœ… ready)         (πŸ•“ planned)

πŸ”Œ Logger Interface

type Logger interface {
    Info(msg string, fields ...any)
    Error(msg string, fields ...any)
    With(fields ...any) Logger
}

You can plug any logger backend by implementing this interface.


βš™οΈ Middleware Usage

Fiber + Zap
import (
    "github.com/ditthkr/loggie"
    "github.com/ditthkr/loggie/middleware/fiberlog"
    "go.uber.org/zap"
    "github.com/gofiber/fiber/v3"
)

func main() {
    rawLogger, _ := zap.NewProduction()
    defer rawLogger.Sync()

    adapter := &loggie.ZapLogger{L: rawLogger}
    app := fiber.New()
    app.Use(fiberlog.Middleware(adapter))

    app.Get("/ping", func(c *fiber.Ctx) error {
        log := loggie.FromContext(c.UserContext())
        log.Info("Ping received", "path", c.Path())
        return c.SendString("pong")
    })

    app.Listen(":8080")
}
Fiber + Logrus
import (
    "github.com/sirupsen/logrus"
    "github.com/ditthkr/loggie/logruslogger"
    "github.com/ditthkr/loggie/middleware/fiberlog"
)


func main() {
    logger := logrus.New()
	
    adapter := &logruslogger.LogrusLogger{L: logrus.NewEntry(logger)}
    app := fiber.New()
    app.Use(fiberlog.Middleware(adapter))
    
    app.Get("/ping", func(c *fiber.Ctx) error {
        log := loggie.FromContext(c.UserContext())
        log.Info("Ping received", "path", c.Path())
        return c.SendString("pong")
    })
    
    app.Listen(":8080")
}

🌐 OTEL Support (OpenTelemetry)

If you're using OpenTelemetry, loggie will automatically extract trace_id from span context via go.opentelemetry.io/otel/trace.

No config required β€” just pass the OTEL-injected context.Context.

ctx := r.Context() // contains OTEL span
log := loggie.FromContext(ctx)

log.Info("Received payment webhook")
// trace_id will match what's in OTEL system (Jaeger, Tempo, etc)

✍️ Custom Fields

ctx = loggie.WithCustomField(ctx, "user_id", 42)

log := loggie.FromContext(ctx)
log.Info("Order created")

πŸ“€ Output:

{
  "msg": "Order created",
  "trace_id": "abc-xyz",
  "user_id": 42
}

🧰 Utilities

Function Purpose
FromContext(ctx) Retrieves logger from context
WithLogger(ctx, logger) Injects a logger
WithTraceID(ctx) Adds trace_id to context
TraceID(ctx) Retrieves trace_id (OTEL-aware)
WithCustomField(ctx, key, val) Adds structured field
DefaultLogger() No-op fallback logger

πŸ“ Middleware Support

Framework Import Path Function
Fiber github.com/ditthkr/loggie/middleware/fiberlog fiberlog.Middleware()
Gin github.com/ditthkr/loggie/middleware/ginlog ginlog.Middleware()
Echo github.com/ditthkr/loggie/middleware/echolog echolog.Middleware()

All middlewares are generic and support any loggie.Logger.


πŸ”Œ Logger Adapters

Logger Status Package
Zap βœ… Supported loggie.ZapLogger
Logrus βœ… Supported loggie/logruslogger
Slog πŸ•“ Planned loggie/slogger (coming soon)

πŸ§ͺ Testing & Fallbacks

Even without injecting a logger, loggie will still work with a safe no-op fallback:

log := loggie.FromContext(context.Background())
log.Info("This is safe even without a logger")

πŸ“ƒ License

MIT Β© 2025 @ditthkr

Documentation ΒΆ

Index ΒΆ

Constants ΒΆ

This section is empty.

Variables ΒΆ

This section is empty.

Functions ΒΆ

func TraceId ΒΆ

func TraceId(ctx context.Context) string

TraceId returns the current trace ID from the context.

It checks the following, in order:

  1. If an OpenTelemetry span exists in the context and has a valid TraceID, it is returned.
  2. If a local trace ID was previously stored in context via WithTraceID(), it is returned.
  3. Otherwise, a new UUID is generated and returned.

func WithCustomField ΒΆ

func WithCustomField(ctx context.Context, key string, value any) context.Context

WithCustomField adds a custom key-value pair to the context. These fields will be automatically injected into log output.

func WithLogger ΒΆ

func WithLogger(ctx context.Context, logger Logger) context.Context

WithLogger stores the given logger inside the context. It can be retrieved later using FromContext.

func WithTraceId ΒΆ

func WithTraceId(ctx context.Context) (context.Context, string)

WithTraceId returns a new context with a generated or existing trace ID, and the trace ID itself as a string.

It first checks if a trace ID exists in the context, otherwise it generates a new UUID. This function is compatible with both OpenTelemetry-based contexts and local fallback mode.

Types ΒΆ

type Logger ΒΆ

type Logger interface {
	Info(msg string, fields ...any)
	Error(msg string, fields ...any)
	With(fields ...any) Logger
}

Logger is the main interface used for logging. It mimics a simplified version of structured loggers like Zap or Logrus.

func DefaultLogger ΒΆ added in v0.2.1

func DefaultLogger() Logger

DefaultLogger returns the internal fallback logger used when no logger is found. This logger does nothing and is safe to call anywhere.

func FromContext ΒΆ

func FromContext(ctx context.Context) Logger

FromContext retrieves the logger from context. If no logger is found, it returns a default no-op logger.

type LogrusLogger ΒΆ added in v0.2.3

type LogrusLogger struct {
	L *logrus.Entry
}

func (*LogrusLogger) Error ΒΆ added in v0.2.3

func (l *LogrusLogger) Error(msg string, fields ...any)

func (*LogrusLogger) Info ΒΆ added in v0.2.3

func (l *LogrusLogger) Info(msg string, fields ...any)

func (*LogrusLogger) With ΒΆ added in v0.2.3

func (l *LogrusLogger) With(fields ...any) Logger

type ZapLogger ΒΆ

type ZapLogger struct {
	L *zap.Logger
}

func (*ZapLogger) Error ΒΆ

func (r *ZapLogger) Error(msg string, fields ...any)

func (*ZapLogger) Info ΒΆ

func (r *ZapLogger) Info(msg string, fields ...any)

func (*ZapLogger) With ΒΆ

func (r *ZapLogger) With(fields ...any) Logger

Directories ΒΆ

Path Synopsis
examples
echo command
fiber command
gin command
middleware

Jump to

Keyboard shortcuts

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