@worknice/instrumentation
v1.13.0
Published
Shared instrumentation management for Worknice applications
Downloads
1,363
Readme
@worknice/instrumentation
Shared instrumentation and correlation ID management for Worknice applications.
Features
- 🔍 Correlation ID Tracking: Request tracing across async boundaries using Node.js AsyncLocalStorage
- 📊 Next.js Instrumentation: Error reporting with Axiom
- 🔄 Cross-Service Tracing: Track requests across services (Notebook, MYOB, Micropay, Basics)
Installation
This package is part of the Worknice monorepo and is automatically available to all apps:
pnpm add @worknice/instrumentationGetting Started
App Instrumentation
For Next.js apps, create an instrumentation.ts file in the app root:
// apps/$app-name/instrumentation.ts
export { register, onRequestError } from "@worknice/instrumentation";register()- Initialises instrumentation. Automatically called by Next.js when instrumentation is enabled.onRequestError()- Handles and logs request errors with correlation tracking. Automatically called by Next.js on errors.
Correlation ID Usage
The package provides multiple ways to work with correlation IDs:
Getting the current correlation ID
import { getCorrelationId } from "@worknice/instrumentation";
const correlationId = getCorrelationId();Running code with a specific correlation ID
import { runWithCorrelationId, getCorrelationId } from "@worknice/instrumentation";
await runWithCorrelationId("$correlationId", async () => {
// All async operations here will have access to the correlation ID
const id = getCorrelationId(); // Returns "$correlationId"
});Getting or generating a correlation ID
import { getOrGenerateCorrelationId } from "@worknice/instrumentation";
const { correlationId, isNew } = getOrGenerateCorrelationId();Extracting from HTTP headers
Extract correlation ID from HTTP headers in order:
x-request-idx-correlation-idrequest-idcorrelation-id
import { extractCorrelationIdFromHeaders } from "@worknice/instrumentation";
const correlationId = extractCorrelationIdFromHeaders(request.headers);Configuration
Environment Variables
The package supports the following environment variables:
AXIOM_DATASET: Axiom dataset name for error loggingAXIOM_TOKEN: Axiom API token for authenticationNODE_ENV: Environment name (development, staging, production)
When Axiom credentials are not provided, the package falls back to console logging.
Architecture
AsyncLocalStorage
The package uses Node.js AsyncLocalStorage to maintain correlation context across async boundaries without explicitly passing IDs through function calls. This allows correlation IDs to automatically flow through:
- GraphQL operations
- Database queries
- API calls
- Background jobs
- Nested async operations
Development
Building
pnpm --filter=@worknice/instrumentation buildDevelopment Mode
pnpm --filter=@worknice/instrumentation devTesting & Linting
pnpm --filter=@worknice/instrumentation test:lint
pnpm --filter=@worknice/instrumentation test:types
pnpm --filter=@worknice/instrumentation test:formatUse Cases
Cross-Service Request Tracing
When a request flows through multiple services (e.g., Notebook → MYOB → External API), the correlation ID helps trace the entire request chain:
In Notebook app:
import { getOrGenerateCorrelationId } from "@worknice/instrumentation";
const { correlationId } = getOrGenerateCorrelationId();
await fetch("https://myob-service/api/endpoint", {
headers: {
"x-correlation-id": correlationId,
},
});In MYOB service:
import { extractCorrelationIdFromHeaders, runWithCorrelationId } from "@worknice/instrumentation";
const correlationId = extractCorrelationIdFromHeaders(req.headers);
runWithCorrelationId(correlationId, async () => {
// All operations here share the same correlation ID
await processRequest();
});Background Job Tracking
Track background jobs initiated from web requests:
In API route:
import { getCorrelationId } from "@worknice/instrumentation";
const correlationId = getCorrelationId();
await inngest.send({
name: "process.data",
data: { correlationId, ...payload },
});In Inngest function:
import { runWithCorrelationId } from "@worknice/instrumentation";
export const processData = inngest.createFunction(
{ id: "process-data" },
{ event: "process.data" },
async ({ event }) => {
return runWithCorrelationId(event.data.correlationId, async () => {
// Job execution with correlation tracking
});
}
);Troubleshooting
Correlation ID Not Available
If getCorrelationId() returns undefined:
- Ensure you're within a correlation context (use
runWithCorrelationId) - Verify the context hasn't been lost (e.g., through
setTimeoutwithout binding)
Axiom Logs Not Appearing
- Verify
AXIOM_DATASETandAXIOM_TOKENenvironment variables are set - Check console output on startup for "Axiom error logging enabled" message
- Ensure the Axiom dataset exists and token has write permissions
