Logging
Certeasy uses structured logging with configurable level, format, output, and per-service overrides.
logs.fileThe configured destination is installed once the configuration has been read, so
the lines emitted before that point are written to stderr and never appear in
logs.file. When startup is refused, the log file is not created at all and
everything — the JSON line and the human-readable message — goes to stderr.
Keep stderr captured wherever Certeasy runs. Under systemd it is routed to journald by default, so nothing is lost, only split across two places. Under the Windows Service Control Manager stderr is attached to nothing and those lines are lost; see Installation for what that means today.
Configuration
logs:
level: info
format: json
output: file
file: "C:\\ProgramData\\certeasy\\logs\\certeasy.log"
rotate:
max-size-mb: 100
max-backups: 10
services:
DB-Driver: warn
Certeasy-acme-server: debug
tags:
instance: cert-srv-01
region: eu-west
Fields
| Field | Default | Description |
|---|---|---|
level | info | Global log level: debug, info, warn, error, off. off (alias none) fully suppresses logs and is most useful as a per-service override. |
format | json | Log format: json or text |
output | stderr | Output destination: stderr, stdout, or file |
file | — | Log file path. Required if output: file. With rotation enabled it is a naming base, not a file — see Rotation. |
rotate.max-size-mb | 0 | Size at which a new segment is started. 0 disables rotation: a single file grows indefinitely. |
rotate.max-backups | 5 | Number of closed segments kept. 0 keeps only the one being written; -1 never deletes. |
services | empty | Per-service log level overrides |
tags | empty | User-defined labels added to every log entry — useful for Grafana/Loki filtering |
Rotation
When output: file and rotate.max-size-mb is greater than zero, file is a
naming base, not a file. Certeasy writes dated segments beside it and never
renames them:
file: C:\ProgramData\certeasy\logs\certeasy.log
C:\ProgramData\certeasy\logs\
certeasy.20260726T091702Z.ms123.log <- closed
certeasy.20260726T104417Z.ms008.log <- being written
The suffix is a UTC timestamp, so the alphabetical order of the file names is their chronological order. A closed segment is never reopened, which is what makes it safe to copy or archive.
Configure your log collector with the folder and a *.log pattern, not with
the path in file. To follow the live file interactively:
Get-Content -Wait (Get-ChildItem C:\ProgramData\certeasy\logs\certeasy.*.log |
Sort-Object Name | Select-Object -Last 1)
If a rotation cannot complete — an antivirus holding the file, a full disk, a permissions problem — Certeasy keeps writing to the current segment, reports the reason on stderr (captured by the Windows service manager), and retries later. Nothing is lost.
max-backups bounds disk usage at roughly max-backups × max-size-mb. It
defaults to 5; before v0.9.4 it defaulted to 0, which meant "keep nothing",
so enabling rotation silently discarded the log at each rotation.
On Windows, access to the log files is governed by the NTFS permissions
inherited from the containing folder — set that folder's ACL at install time.
On Linux and macOS, files are created 0600 and the directory 0700, so a
collector running under its own account cannot read them without being granted
access out of band.
Per-Service Log Levels
You can set a different log level for each internal service. This is useful for debugging a specific component without flooding logs with debug output from everything else.
logs:
level: info
services:
Certeasy-acme-server: debug
Async-Acme-Challenges: debug
Use off (or none) to fully silence a service — for example when a chatty driver is generating noise during dev or staging captures:
logs:
services:
DB-Driver: off
Certeasy-acme-server: warn
Registered Service Names
| Service Name | Description |
|---|---|
DB-Driver | Database driver and query logs |
Certeasy-acme-server | ACME HTTP request handling |
Async-Acme-Pki-Handler | Async PKI job processing |
Async-Acme-Challenges | Async challenge validation |
JWKS | JWS key validation |
worker | Job engine (lease, dispatch, backoff) |
http-server | HTTP server lifecycle |
adcs-native | ADCS authority operations — native in-process connector (default) |
adcs-cli | ADCS authority operations — certreq.exe connector (adcs-cli) |
license | License lifecycle (install, refresh, enforcement) |
node | Node identity (server_id, servers table) |
Tags (Grafana/Loki labels)
logs.tags is a free-form map of key: value pairs added to every log entry. Use it to attach environment metadata that your log aggregator (Grafana/Loki, Splunk, Elastic…) can filter on.
logs:
tags:
instance: cert-srv-01
region: eu-west
role: production
Each entry shows up as a top-level field in the JSON output, alongside time, level, msg, etc. There is no fixed list of allowed keys — pick whatever your stack expects.
The previous automatic env field is no longer added to log entries; it conflicted with the env= shown inside license-related log messages (license environment, e.g. env=dev / env=prod). If you want an environment label, set it explicitly under tags.
Log Rotation
Log rotation is supported when output: file. Configure rotate to limit disk usage:
logs:
output: file
file: "C:\\ProgramData\\certeasy\\certeasy.log"
rotate:
max-size-mb: 100
max-backups: 5
This keeps up to 5 rotated files of 100 MB each (500 MB total).
Production Recommendations
- Use
format: jsonfor structured log ingestion (Splunk, Elastic, Loki…) - Use
output: filewith rotation to avoid filling disk - Keep global level at
infoand only setdebugon specific services when troubleshooting - Route logs to your SIEM — the audit log entries contain account IDs, order IDs, and operation details

