Skip to content
Logixlysia
Esc
↑↓navigate↵open⌘Jpreview
On this page

Background Jobs

Log cron jobs, queue consumers and scripts through every sink

runJob runs a function outside a request and writes one final line for it, through transports, the file sink and redaction, the same as a request gets.

import logixlysia from 'logixlysia'

const logs = logixlysia({
  config: { service: 'billing', requestId: true }
})

await logs.runJob('nightly-sync', async log => {
  const rows = await loadRows()
  log.mergeContext({ rows: rows.length })
  await pushRows(rows)
})

async function loadRows(): Promise<string[]> {
  return ['a', 'b', 'c']
}

async function pushRows(_rows: string[]): Promise<void> {}

The line is labelled JOB, the job name is its path, and it carries the duration and the accumulated context:

JOB     /nightly-sync 200 412ms

Outcome

  • The final line is always written, even when the job logs lines of its own. A request’s custom log replaces its access line; a job’s does not.
  • A job that returns gets status 200. The value fn returns is the value runJob returns.
  • A job that throws gets status 500: logixlysia writes the error line, then rethrows the same error, so your scheduler still sees the failure.
  • An empty or non-string name rejects with a TypeError before fn runs.

Inside helpers

useLogger() returns the job’s logger anywhere under fn, across awaits, without setting useAsyncLocalStorage. After the job settles it is a no-op again.

import { useLogger } from 'logixlysia'

export const markSynced = (count: number): void => {
  useLogger().mergeContext({ synced: count })
}

Scripts

A script exits as soon as the job returns, and a batching transport has no other chance to send. End the script with flushLogixlysia, passing the same options object you gave the plugin:

import logixlysia, { flushLogixlysia } from 'logixlysia'
import type { Options } from 'logixlysia'

const options: Options = { config: { service: 'billing' } }
const logs = logixlysia(options)

await logs.runJob('backfill', log => {
  log.mergeContext({ batch: 7 })
})
await flushLogixlysia(options)

Sampling

A successful job is head sampled like any other INFO line. With sampling.head: { INFO: 0 } it writes nothing, so give the jobs you care about a tail.paths rule:

sampling: { head: { INFO: 0 }, tail: { paths: ['/nightly-sync'] } }

A job that throws is kept by the ERROR line, along with the lines it buffered. See sampling.

Last updated on

Was this page helpful?