Qadam Roadmap
проектplans/archived/2026-03-28-integrated/2026-03-14-axiom-transport.md

Axiom Transport Integration Implementation Plan

Обновлён 1 апр. 2026 г., 12:41 · 0 комментариев

Axiom Transport Integration Implementation Plan

For agentic workers: REQUIRED: Use superpowers:subagent-driven-development (if subagents available) or superpowers:executing-plans to implement this plan. Steps use checkbox (- [ ]) syntax for tracking.

Goal: Add @axiomhq/pino as a production-only log transport to the NestJS API, with graceful degradation when Axiom credentials are absent.

Architecture: A module-level buildPinoTransport() helper returns a partial pinoHttp options object that is spread into LoggerModule.forRoot(). In production with credentials present it outputs to both stdout and Axiom; without credentials it warns and falls back to stdout JSON; in non-production it uses pino-pretty.

Tech Stack: NestJS 10, nestjs-pino ^4.6.1, pino ^10.3.1, @axiomhq/pino ^1.2


Chunk 1: Install package and wire transport

Task 1: Install @axiomhq/pino

Files:

  • Modify: apps/api/package.json (dependencies section)

  • Updated automatically: pnpm-lock.yaml (monorepo root)

  • Step 1: Install the package

Run from the apps/api directory:

cd apps/api && pnpm add @axiomhq/pino@^1.2

Expected: @axiomhq/pino appears in apps/api/package.json under dependencies.

  • Step 2: Verify the install
cd apps/api && pnpm list @axiomhq/pino

Expected: one line showing @axiomhq/pino 1.x.x.


Task 2: Update app.module.ts with buildPinoTransport()

Files:

  • Modify: apps/api/src/app.module.ts (lines 25–33)

No automated tests — this is pure configuration. Manual verification is in Task 3.

  • Step 1: Replace the inline ternary with buildPinoTransport()

Open apps/api/src/app.module.ts. The current LoggerModule.forRoot() block (lines 25–33) looks like:

LoggerModule.forRoot({
  pinoHttp: {
    autoLogging: true,
    quietReqLogger: false,
    transport: process.env.NODE_ENV !== 'production'
      ? { target: 'pino-pretty', options: { colorize: true, singleLine: true } }
      : undefined,
  },
}),

Replace with the following. Add the buildPinoTransport function above the @Module decorator (after the last import line), and update LoggerModule.forRoot():

function buildPinoTransport() {
  if (process.env.NODE_ENV !== 'production') {
    return {
      transport: { target: 'pino-pretty', options: { colorize: true, singleLine: true } },
    };
  }

  const token = process.env.AXIOM_TOKEN;
  const dataset = process.env.AXIOM_DATASET;

  // Treat undefined AND empty string as absent
  if (!token || !dataset) {
    // console.warn fires before the pino instance is initialised — intentional plain-text warning
    console.warn('[Logger] AXIOM_TOKEN or AXIOM_DATASET not set — Axiom transport disabled, using stdout JSON only');
    return {};
  }

  return {
    transport: {
      targets: [
        { target: 'pino/file', level: 'info', options: { destination: 1 } },    // stdout
        { target: '@axiomhq/pino', level: 'info', options: { token, dataset } }, // Axiom
      ],
    },
  };
}

@Module({
  imports: [
    LoggerModule.forRoot({
      pinoHttp: {
        autoLogging: true,
        quietReqLogger: false,
        ...buildPinoTransport(),
      },
    }),
    // ... rest unchanged
  • Step 2: Verify TypeScript compiles
cd apps/api && pnpm check-types

Expected: no errors.


Task 3: Add Axiom env vars to .env.example

Files:

  • Modify: .env.example (monorepo root)

  • Step 1: Append Axiom vars to .env.example

Open .env.example at the monorepo root. Append after the existing content:

# Axiom (production log ingestion)
AXIOM_TOKEN=""
AXIOM_DATASET=""

Task 4: Verify and commit

  • Step 1: Run the full test suite to confirm nothing is broken
cd apps/api && pnpm test

Expected: all tests pass (136 tests, 0 failures).

  • Step 2: Start the dev server and verify pino-pretty output still works
cd apps/api && pnpm dev

Expected: colourised, single-line pino-pretty output in the terminal (non-production mode). No errors on startup.

  • Step 3: Verify graceful degradation — production mode without credentials

Stop the dev server. Run:

NODE_ENV=production node -e "
  process.env.AXIOM_TOKEN = '';
  process.env.AXIOM_DATASET = '';
  // Inline the logic to test it in isolation
  const token = process.env.AXIOM_TOKEN;
  const dataset = process.env.AXIOM_DATASET;
  if (!token || !dataset) {
    console.warn('[Logger] AXIOM_TOKEN or AXIOM_DATASET not set — Axiom transport disabled, using stdout JSON only');
    console.log('PASS: graceful degradation fires');
  } else {
    console.log('FAIL: should have degraded');
  }
"

Expected: prints [Logger] AXIOM_TOKEN or AXIOM_DATASET not set... followed by PASS: graceful degradation fires.

  • Step 4: Commit
git add apps/api/package.json apps/api/src/app.module.ts .env.example pnpm-lock.yaml
git commit -m "feat(api): add Axiom pino transport with graceful degradation"