Add Package-Scoped Logging with Logcopter

Generate package loggers and configure area-specific levels through Glazed logging settings.

Sections

Terminology & Glossary
📖 Documentation
Navigation
77 sectionsv0.1
📄 Add Package-Scoped Logging with Logcopter — glaze help logcopter-package-logging-tutorial
logcopter-package-logging-tutorial

Add Package-Scoped Logging with Logcopter

Generate package loggers and configure area-specific levels through Glazed logging settings.

Tutoriallogginglogcoptertutorialglazed

Add Package-Scoped Logging with Logcopter

This tutorial shows how to add package-scoped logging to a Go application using logcopter. The application keeps its existing Glazed logging setup, while logcopter supplies generated package-local loggers and per-area level filtering.

1. Choose area names

Start by choosing an area prefix. Applications usually use app; reusable libraries should use a library prefix such as lib.protocol or lib.ble.

Example mapping:

github.com/acme/server/internal/view/render -> app.view.render
github.com/acme/server/internal/db/sql      -> app.db.sql
github.com/acme/protocol/parser             -> lib.protocol.parser

2. Generate package logger files

Run logcopter-gen with the runtime import path, package strip prefix, and area prefix:

go run github.com/go-go-golems/logcopter/cmd/logcopter-gen \
  -logcopter-import github.com/go-go-golems/logcopter/pkg/logcopter \
  -strip-prefix github.com/acme/server/internal \
  -area-prefix app \
  ./internal/...

A package such as internal/view/render receives a generated file:

// 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")

3. Use the package logger

Use the generated log variable like a zerolog logger:

func Render(name string) {
    log.Trace().Str("template", name).Msg("render start")
    log.Debug().Msg("cache lookup")
}

Do not manually repeat the area string at every call site. That is the generator's job.

4. Configure levels in the application config

In an application config file, use the normal Glazed logging: section:

logging:
  log-level: info
  log-format: text
  areas:
    app.view: debug
    app.view.render: trace
    app.db: warn

This sets the default level to info, enables debug logging for app.view and descendants, trace logging for app.view.render and descendants, and warning-only logging for app.db.

5. Override areas from the command line

Glazed should expose area overrides as a key-value logging field:

myapp --log-area app.view:debug --log-area app.db:warn

For user convenience, key=value should also be accepted:

myapp --log-area app.view=debug --log-area app.db=warn

Direct command-line overrides should win over config files.

6. Use shared logging profiles

Create a shared profile for a debugging scenario:

# ~/.config/logcopter/profiles/render-debug.yaml
level: info
format: text
areas:
  app.view.render: trace
  lib.protocol: debug

Run any Glazed application with that profile:

myapp --log-config ~/.config/logcopter/profiles/render-debug.yaml

You can still add a one-off override:

myapp \
  --log-config ~/.config/logcopter/profiles/render-debug.yaml \
  --log-area app.http=trace

7. Validate generated files in CI

Use generator check mode in CI:

go run github.com/go-go-golems/logcopter/cmd/logcopter-gen \
  -logcopter-import github.com/go-go-golems/logcopter/pkg/logcopter \
  -strip-prefix github.com/acme/server/internal \
  -area-prefix app \
  -check \
  ./internal/...

The check should fail if generated logger files are stale.