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-prettyoutput 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"