agent's parser broke on bacula timestamp format and skipped failed jobs
Fixes an agent parser that broke on the Bacula timestamp format and skipped failed jobs, by handling Bacula date variants and auditing skipped records. Use when Bacula job reports are parsed but some jobs never appear. Not for Bacula jobs missing from the director database itself.
TL;DR
Find the exact timestamp strings Bacula emitted for the skipped jobs and teach the parser those formats instead of letting it drop unparsable rows silently: Bacula mixes formats across console, log, and catalog outputs and locales. Make any unparsable record a loud parsing failure, then reprocess the affected reports so previously skipped failed jobs are triaged.
agent's parser broke on bacula timestamp format and skipped failed jobsUse this when
- An agent summarises Bacula jobs but failed jobs are missing from its reports.
- Skipped jobs cluster on certain dates, locales, or output sources such as bconsole versus log files.
- Parser logs show date or time conversion warnings that were treated as non fatal.
Not for this skill when
- The jobs are absent from the Bacula catalog and console as well. That is a director or catalog problem, not parsing.
- The agent parses correctly but its success classification is wrong. That is a status mapping problem.
Steps
- Recover the skipped set: list jobs for the period directly from Bacula with bconsole or the catalog, including job identifiers, levels, statuses, and start times, and diff that list against the jobs the agent reported. Verify: every skipped job is named with its identifier and status, and the failed ones are flagged for triage
- Extract the raw timestamp text for the skipped jobs exactly as the parser received it, from the same source the parser reads, whether that is bconsole output, a job log, or a catalog export. Note day and month order, month names or numbers, separators, time zone markers, and any leading text. Verify: the raw strings for skipped and parsed jobs are shown side by side and the format difference is visible
- Fix the parser with explicit formats: add the observed Bacula variants as named patterns tried in order, handle locale month names deliberately rather than by host locale, and normalise parsed times to one time zone with the source zone recorded. Verify: unit examples built from the raw skipped strings now parse to the correct times
- Make failure loud: any record the parser still cannot parse must be counted, logged with its raw text, and surfaced as a parsing failure in the run summary, never skipped silently or defaulted to the current time. Verify: a test record with a deliberately corrupt timestamp appears in the summary as unparsed, and the run does not report full success
- Reprocess the backlog: rerun the fixed parser over the retained reports or catalog exports for the whole affected period, and triage every newly surfaced failed job through the normal backup failure process. Verify: agent job counts now equal the Bacula catalog counts per day, and all surfaced failures have a triage outcome
- Add a reconciliation check to every run: compare parsed job count and failed job count against a direct Bacula count for the same window, and alert on any mismatch before the summary is sent. Verify: a simulated dropped record triggers the mismatch alert in a test run
Why it happens
Bacula does not emit one timestamp format. Console listings, job termination messages, log files, and catalog queries each format dates differently, and formats shift with version, locale, and whether the output came from bconsole, the director log, or a database export - day first versus month first, abbreviated month names, two or four digit years, and times with or without seconds and zone information all occur. A parser written and tested against one source, or one locale, will throw a conversion error on the other variant. If that error is caught per record and coded as skip, the agent produces a clean looking report from an incomplete set, and because failed jobs are no more likely to parse than successful ones, whole failures vanish randomly. The bug is therefore two bugs: a fragile format assumption, and a silent skip that converted a parsing defect into missing operational truth.
Variants and edge cases
skips happen only around month boundaries
Day and month order ambiguity is the usual cause: a date that parses under the wrong order for most of the month fails or mis-sorts when the day exceeds twelve. Pin the order from the Bacula source configuration, add boundary examples to the parser tests, and check for silently misordered jobs as well as skipped ones.
only jobs from one director or locale are skipped
Month names and separators follow the locale of the emitting host. Parse with an explicit locale map for month names from each source, and record the source host with each record so a new locale is detected as a new format, not as missing jobs.
timestamps parse but jobs land on the wrong day
Time zone handling, not format, is at fault: catalog times, log times, and agent times in different zones shift jobs across the reporting window edge. Normalise all times to UTC at parse time with the original zone retained, and reconcile counts over a window padded by one day on each side. Edge cases: upgraded Bacula versions can change console column layouts, so a timestamp fix can still break later if the parser depends on column positions; parse from labelled fields or catalog queries where available and keep golden examples from each source and version in the test set. Retention matters too: if raw logs rotate away before the parser is fixed, the catalog is the only place the skipped jobs can be recovered from, which argues for fixing quickly and reconciling against the catalog routinely. The standing rule for this agent is simple - counts must reconcile with Bacula itself on every run, and an unparsed record is a failed run, never a footnote.
Provenance
Resolved from the public thread: https://vectle.com/posts/pst__idRMBH7rVBCRl1OUeH2FQ