Logcopter Logging Architecture

Understand logcopter areas, generated package loggers, Glazed integration, and shared logging profiles.

Sections

Terminology & Glossary
πŸ“– Documentation
Navigation
3 sectionsv0.1
πŸ“„ Logcopter Logging Architecture β€” glaze help logcopter-logging-architecture
logcopter-logging-architecture

Logcopter Logging Architecture

Understand logcopter areas, generated package loggers, Glazed integration, and shared logging profiles.

Topiclogginglogcopterzerologglazed

Logcopter Logging Architecture

Logcopter is a small utility package that adds package-scoped, configuration-driven log levels on top of zerolog. It does not replace zerolog; it gives applications a stable naming and configuration layer for package-local diagnostics.

The core idea is an area: a dot-separated logging namespace such as app.view.render, app.db, or lib.protocol.parser. Areas are stable configuration keys. Application packages use generated package-local loggers, while application startup configures one logcopter manager with default and per-area levels.

Why areas exist

A single process-wide --log-level debug is too blunt for large command-line applications. During debugging, you often want trace logs for one subsystem and warnings for another:

logging:
  log-level: info
  areas:
    app.view.render: trace
    app.db: warn
    lib.protocol: debug

With this config:

  • app.view.render.partial inherits trace from app.view.render.
  • app.db.sql inherits warn from app.db.
  • unrelated areas fall back to info.

Runtime split

Logcopter owns the mechanics:

  • reload-aware manager state;
  • generated package logger wrappers;
  • area normalization;
  • longest-prefix level lookup;
  • conversion to per-area zerolog child loggers.

Glazed owns command-line and config integration:

  • logging section fields;
  • root Cobra logging flags;
  • early logging initialization;
  • config-file and environment-source precedence.

This keeps logcopter useful as a small library and avoids forcing applications to import an extra Glazed adapter package. Existing applications can keep using github.com/go-go-golems/glazed/pkg/cmds/logging.

Generated package loggers

The generator writes package-local files like:

// Code generated by logcopter-gen; DO NOT EDIT.
package render

import logcopter "github.com/go-go-golems/logcopter/pkg/logcopter"

var log = logcopter.Package("app.view.render")

Package code then uses normal zerolog event chains:

log.Trace().Str("template", name).Msg("render start")
log.Debug().Msg("cache lookup")

The generated variable is a wrapper, not a raw zerolog.Logger. The wrapper resolves the current per-area logger at event creation time, so a logger created before configuration can still observe later configuration or reloads.

Shared logging profiles

Applications can keep logging settings in their normal config file, but logcopter also supports explicit logging profile files. These files are useful when the same logging profile should apply across applications:

pinocchio --log-config ~/.config/logcopter/profiles/dev-ui.yaml
geppetto  --log-config ~/.config/logcopter/profiles/dev-ui.yaml

A standalone profile can use direct logcopter shape:

level: info
format: text
areas:
  app.view.render: trace
  lib.protocol: debug

or application-style shape:

logging:
  log-level: info
  log-format: text
  areas:
    app.view.render: trace
    lib.protocol: debug

The intended precedence is:

  1. built-in defaults;
  2. the application's normal logging: config section;
  3. explicit --log-config files, in command-line order;
  4. direct CLI flags such as --log-area app.http=trace.

Global zerolog level warning

Area filtering must be performed with per-area child logger levels. A process-wide zerolog.SetGlobalLevel(zerolog.InfoLevel) would suppress debug and trace logs even when a specific area is configured for them. Glazed's logcopter-aware logging initialization should therefore leave the global level permissive and let logcopter child loggers filter normally.