Skip to content

fix(logging): switch to slog-journal and add per-job journal fields #46

@ivy

Description

@ivy

Problem

Logging currently uses slog.NewTextHandler writing to stderr. This makes it impossible to trace a specific job using journalctl structured queries — you can't filter by repo or ticket number.

Three concrete issues:

1. slog-journal not wired up

ADR-002 chose systemd/slog-journal and CLAUDE.md documents it in the tech stack, but the dependency was never added. setupLogger() in cmd/hive/main.go creates a plain TextHandler:

handler := slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{
    Level: level,
})

2. Duplicate timestamps

TextHandler emits its own time= prefix on every line. When hive runs as a systemd service (or under systemd-run), journald also stamps each line. The result is two timestamps per log entry — one from slog, one from the journal — neither of which is useful for structured queries.

3. No way to filter by repo/ticket

Structured fields like repo and issue are passed as slog key-value args today, but TextHandler flattens them into free-text. There's no way to run:

journalctl HIVE_REPO=ivy/hive HIVE_ISSUE=42

Additionally, systemd-run in internal/jail/systemd.go doesn't pass any LogExtraFields= properties, so child-process output (the agent itself) is completely untagged in the journal.

Expected behavior

  • slog-journal handler used when stderr is connected to the journal (fall back to TextHandler for interactive use)
  • Structured slog attrs map to journal fields automatically (this is what slog-journal does)
  • systemd-run invocations include LogExtraFields=HIVE_REPO=<repo> and LogExtraFields=HIVE_ISSUE=<number> so agent output is queryable
  • journalctl HIVE_REPO=owner/repo HIVE_ISSUE=42 --output=json returns structured entries for a single job

Relevant code

File What's wrong
cmd/hive/main.go:58-73 setupLogger() uses TextHandler instead of journal handler
internal/jail/systemd.go:22-35 systemd-run args have no LogExtraFields
go.mod Missing github.com/systemd/slog-journal dependency

References

  • ADR-002 (docs/adrs/002-tech-stack.md) — chose slog-journal, documented expected behavior
  • Architecture doc (docs/architecture.md) — describes journald as the logging target
  • slog-journal: https://github.com/systemd/slog-journal

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions