File and stdout
sinks: file: path: /var/log/ghchronicle/points.lp format: influx # or json max_bytes: 67108864 keep: 5For the setups that already run a shipper. Telegraf tails line protocol, Promtail and Vector tail JSON, and neither needs this process to know anything about their backend.
It is also the simplest durable buffer there is: when the database is down, the file still has the data.
Rotation
Section titled “Rotation”By size, with numbered suffixes, so retention is a count and two rotations in the same second cannot collide. The size counter is read from the file on start-up, so a restart does not reset it and let the file grow without bound.
gh_traffic,full_name=acme/telemetry,kind=views,owner=acme,repo=telemetry count=220i,uniques=131i 1788739200000000000{"time":"2026-09-07T00:00:00Z","measurement":"gh_traffic","tags":{"full_name":"acme/telemetry","kind":"views","owner":"acme","repo":"telemetry"},"fields":{"count":220,"uniques":131}}One object per line in JSON, which is the shape a line-oriented shipper wants.
Standard output
Section titled “Standard output”sinks: stdout: true stdout_format: influx # or jsonLine protocol on standard output, for piping into Telegraf or for seeing what would be written before pointing this at a database. It is the fastest way to answer “what does this actually collect”.
ghchronicle -config config.yaml -once | head -20ghchronicle -config config.yaml -once | grep gh_workflow_runstdout_format: json prints one object per line instead, the same shape the
file sink writes.
As a buffer
Section titled “As a buffer”The file sink is the answer to “what happens when the database is down”. Run it
alongside the real store: the write to the database fails and is logged, the
sweep continues, and the points are on disk. Replaying them afterwards is a
curl for InfluxDB, or psql -f for the SQL sink, and it converges rather
than duplicating because the points carry their own timestamps.
curl -s -XPOST "http://localhost:8181/api/v2/write?org=default&bucket=github&precision=ns" \ -H "Authorization: Token $INFLUX_TOKEN" \ --data-binary @/var/log/ghchronicle/points.lpPermissions
Section titled “Permissions”The dump is created 0600 inside a 0750 directory. A sweep of a private
account puts private repository names, Dependabot severities and whole job log
lines in it, so it is not created readable by the whole machine just because a
shipper is coming to read it.
Letting the shipper read it
Section titled “Letting the shipper read it”Telegraf, Promtail, Vector and Fluent Bit all read as their own user. None of
them documents a required mode, and every one of them documents the same
remedy, which is a group: their own answers say usermod -aG adm. So the grant
is yours to make, and it is two commands:
usermod -aG ghchronicle telegraf # the shipper joins the service's groupchmod 0640 /var/log/ghchronicle/points.lp # or create it that way beforehandThe grant sticks. The sink never changes the mode of a file that is already
there, and a rotation creates the replacement with the mode of the file it is
renaming away, so the chmod is not undone the first time the dump fills up.
If you would rather the dump belonged to the shipper’s own group, own the directory with it and set the setgid bit, which is what makes every file created in it inherit the group, rotations included:
install -d -o ghchronicle -g telegraf -m 2750 /var/log/ghchronicleThat settles which group owns the dump, not what the group may do with it, so
the chmod 0640 above is still the other half. Making the directory yourself is
worth doing whichever route you take: the one this process creates when the
directory is missing is 0750 less whatever the process umask takes off it, and
a shipper that cannot traverse the directory fails as quietly as one that cannot
read the file.
An ACL is not carried, because it belongs to the file it was set on and a
rotation creates a new one, so grant through the group rather than through
setfacl on the dump. What a rotation does carry is the mode, not the owner:
this process cannot chown a file to a user it is not. The write ledger behind
sinks.dedupe_file is the opposite case and gets the opposite answer: nothing
but this process is meant to read it, so it is written 0600 and every save
puts it back to 0600.
Where it can write at all
Section titled “Where it can write at all”Under the hardened systemd unit, the directory has to be in ReadWritePaths.
In a container it has to be writable by uid 65532. Both are the same mistake in
two clothes: the process is deliberately allowed to write almost nowhere.
Where to go next
Section titled “Where to go next”- Choosing a store compares the file sink with the other nine, and holds the write ledger every one of them shares.
- The dashboards says which of the five is drawn against which store, and what a panel a store cannot answer becomes.