---
title: Logcopter Logging Architecture
description: Understand logcopter areas, generated package loggers, Glazed integration, and shared logging profiles.
doc_version: 1
last_updated: 2026-07-02
---


# 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:

```yaml
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:

```go
// 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:

```go
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:

```bash
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:

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

or application-style shape:

```yaml
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.
