Skip to content

Log ​

Where log records go, and how much is written.

Structure ​

json
{
  "log": {
    "level": "info",
    "outputs": [
      { "type": "stderr", "format": "human", "color": true },
      { "type": "file", "path": "apranik.log" }
    ]
  }
}

NOTE

With no outputs, Apranik logs nothing, on purpose: a log naming what a user reached is evidence on a seized device.

Fields ​

level ​

stringDefault: info

The least severe level written, from most to least verbose: debug, info, notice, warning, error, critical, alert, emergency (RFC 5424).

outputs ​

list of outputsDefault: [], silent

Where records go. Every record goes to every output. Each output's type is one of the output types.

Output types ​

json
{
  "type": "stderr",
  "format": "human",
  "color": true
}

format ​

stringDefault: logfmt

ValueWrites
logfmttime=… level=INFO msg="Inbound active" tag=socks-in
json{"time":"…","level":"INFO","msg":"Inbound active","tag":"socks-in"}
human2026-09-27T05:24:55.324+03:30 INFO Inbound active tag=socks-in

Use human when a person reads the terminal.

color ​

booleanDefault: falsehuman only

Color the level name and dim the time. NO_COLOR in the environment turns it off.

Live view for an API ​

An API can subscribe to the log at its own level, without any output configured. With no subscriber this costs nothing. A subscriber that falls behind loses records and is told how many.