• v0.11.0 a335621b62

    v0.11.0 — phase-tagged logs and a legible boot banner
    All checks were successful
    CI / gate (push) Successful in 39s
    CI / image (push) Successful in 27s
    Stable

    joeyr released this 2026-08-02 17:23:32 -05:00 | 222 commits to main since this release

    Every log line is now attributed to a phase, in Portainer's caller field —
    the fourth of the five keys the dashboard colours, and the one 0.10.2 named but
    left unused.

    Phase tags

    The two halves of a window run concurrently by design, so their lines
    interleave. Until now the only way to tell which crawl a line came from was to
    recognise its wording, and the only way to tell a classic failure from a ranked
    one was a queue= pair at the far end of the line. Portainer prints caller
    before the message and colours it distinctly, so it reads as a column:

    2026-08-03 02:14:07 INF riot/crawl >       crawl complete | rows=7478
    2026-08-03 02:41:22 WRN counters/classic > coverage below floor | coverage=0.87
    

    The vocabulary is riot/{crawl,damage,benchmarks}, opgg/{http,universe},
    counters/{ranked,classic} and runes/{ranked,classic}.

    Two segments, always. Portainer renders caller as the last two
    slash-separated segments — the field is meant for a Go pkg/file.go — so a
    third is dropped silently, which would make opgg/counters/classic and
    riot/counters/classic arrive identical. The list is closed (PHASES in
    logger.ts) so that holds by construction and a typo is a type error rather
    than a tag that quietly never appears.

    counters and runes split by queue rather than by half because that is the
    axis that actually distinguishes their lines — both run on the op.gg half. The
    shared HTTP client keeps its own opgg/http tag rather than borrowing whichever
    crawl was using it: one instance serves the universe, counters and runes crawls
    of a pass, so attributing its retry warnings to any single phase would be a
    guess.

    The boot banner

    It now reports the config it was silently omitting: runOnStart, classic,
    the op.gg query band (region/tier/queue), the op.gg pacing interval, and the
    per-artifact time caps.

    classic is what motivated this. It is the only opt-in artifact flag, and there
    was no way to tell from the outside whether the pass had run — an unset
    CLASSIC_ENABLED looks exactly like a pass that ran and published nothing.
    runOnStart is the reason a container that "did nothing" may in fact have
    crawled the moment it booted, outside the window. The query band decides which
    population every op.gg artifact describes, and three artifacts describing three
    different populations is a failure with no error attached to it.

    It is also three lines now — config/build, config/riot, config/opgg
    because the single line wrapped to four in the viewer where it is read, and at
    that width the wrap lands mid-field. The split follows the service's own shape:
    the process and its destinations, then one line per half.

    Local window times

    next and deadline were the last clocks still rendering as
    2026-08-01T07:00:00.000Z, sitting beside a local timestamp with nothing on the
    line to say the two were five hours apart by definition rather than by elapsed
    time. schedule.ts does all its arithmetic in local time off the container's
    TZ, so a UTC field was the one value that had to be converted before it could
    be checked against CRAWL_START_HOUR — and being five hours out is exactly what
    a TZ misconfiguration looks like. next now reads 2026-08-03 02:00:00
    against a window=02:00-05:00 on the line above it.

    The sv-SE formatting 0.10.2 inlined into pino's timestamp is now the exported
    localTime, so the timestamp and the fields beside it cannot drift apart.


    Minor rather than patch for the added boot output and the new caller field,
    though this remains confined to the dashboard: no artifact, schema, or published
    file changes.

    Downloads