An ffmpeg log is not named the way upstream names one #182

Closed
opened 2026-08-22 17:01:28 +02:00 by Claude · 2 comments
Collaborator

Minor, found in the dashboard's Logs list.

An ffmpeg job writes its log as

FFmpeg.DirectStream-ddd7674e9adfb468762c3ace496f1f2a.log

Upstream writes

FFmpeg.DirectStream-2026-08-22_16-50-00_{mediaSourceId}_{8 hex}.log

— TranscodeManager.StartFfMpeg,
upstream/MediaBrowser.MediaEncoding/Transcoding/TranscodeManager.cs:451-467.
The prefix itself is right: this job copied the video and encoded the audio, and
upstream calls that DirectStream- too (Remux- only when both are copies).

What differs is everything after it. Ours names the job; upstream names the
clock, the source and a fresh guid, so the list a dashboard shows sorts by when
a play happened and two plays of one source never share a name.

How to know it is done

The log a play leaves is named the way upstream names it, and the Logs list
orders and reads the same against both servers.

House rules

Tests run under cargo nextest; upstream's source is the checkout in
upstream/ at the pin. Generated artifacts are regenerated, never edited.

Minor, found in the dashboard's **Logs** list. An ffmpeg job writes its log as ``` FFmpeg.DirectStream-ddd7674e9adfb468762c3ace496f1f2a.log ``` Upstream writes ``` FFmpeg.DirectStream-2026-08-22_16-50-00_{mediaSourceId}_{8 hex}.log ``` — `TranscodeManager.StartFfMpeg`, `upstream/MediaBrowser.MediaEncoding/Transcoding/TranscodeManager.cs:451-467`. The prefix itself is right: this job copied the video and encoded the audio, and upstream calls that `DirectStream-` too (`Remux-` only when both are copies). What differs is everything after it. Ours names the job; upstream names the clock, the source and a fresh guid, so the list a dashboard shows sorts by when a play happened and two plays of one source never share a name. ## How to know it is done The log a play leaves is named the way upstream names it, and the Logs list orders and reads the same against both servers. ### House rules Tests run under `cargo nextest`; upstream's source is the checkout in `upstream/` **at the pin**. Generated artifacts are regenerated, never edited.
Author
Collaborator

Fixed in c2ed437, with the review's findings in bdfc113.

Measured rather than read: the reference instance at the pin was made to
transcode and wrote

FFmpeg.Transcode-2026-08-22_15-28-27_6af10317bb8965de8a759ce1186806a0_71d342f4.log

which is what log_file_name now spells. Three things the review corrected on
top of the first pass:

  • The source is the one the request named, not the one the state resolved.
    Upstream interpolates its parameter, so a request that named none leaves the
    field blank between two underscores; ours filled it in.
  • The clock is read where the job starts rather than inside the naming, so a
    test pins the whole name. It asserted only the lengths of the parts before,
    which a %d-%m-%Y or a UTC clock would both have passed.
  • The claim that both streaming routes refuse a request naming another source
    is false — only the progressive one does. GET /Videos/{A}/hls1/main/0.ts?mediaSourceId={B}
    starts a job here where upstream throws. That is a separate difference and is
    not this issue.

One thing this makes matter that did not before: a name is now unique per start
rather than per output path, so nothing overwrites and the directory grows.
sweep_logs answers Ok(0) — the Clean Log Directory task deletes nothing —
which is the next thing to look at.

Fixed in `c2ed437`, with the review's findings in `bdfc113`. Measured rather than read: the reference instance at the pin was made to transcode and wrote ``` FFmpeg.Transcode-2026-08-22_15-28-27_6af10317bb8965de8a759ce1186806a0_71d342f4.log ``` which is what `log_file_name` now spells. Three things the review corrected on top of the first pass: - The source is the one the **request** named, not the one the state resolved. Upstream interpolates its parameter, so a request that named none leaves the field blank between two underscores; ours filled it in. - The clock is read where the job starts rather than inside the naming, so a test pins the whole name. It asserted only the lengths of the parts before, which a `%d-%m-%Y` or a UTC clock would both have passed. - The claim that both streaming routes refuse a request naming another source is false — only the progressive one does. `GET /Videos/{A}/hls1/main/0.ts?mediaSourceId={B}` starts a job here where upstream throws. That is a separate difference and is not this issue. One thing this makes matter that did not before: a name is now unique per start rather than per output path, so nothing overwrites and the directory grows. `sweep_logs` answers `Ok(0)` — the Clean Log Directory task deletes nothing — which is the next thing to look at.
Author
Collaborator

Correction to the note above: the log sweeper is not a stub. sweep_logs
answering Ok(0) is NoHousekeeping, the null implementation a server built
with no directories is given. The real one is
crates/ephyra-server/src/maintenance.rs:89 — it takes
log_file_retention_days, floors it at LOGS_KEPT_AT_LEAST_DAYS, and sweeps
the log directory. So the directory is kept in hand and nothing follows from a
name being unique per start.

Correction to the note above: the log sweeper is not a stub. `sweep_logs` answering `Ok(0)` is `NoHousekeeping`, the null implementation a server built with no directories is given. The real one is `crates/ephyra-server/src/maintenance.rs:89` — it takes `log_file_retention_days`, floors it at `LOGS_KEPT_AT_LEAST_DAYS`, and sweeps the log directory. So the directory is kept in hand and nothing follows from a name being unique per start.
Sign in to join this conversation.
No description provided.