cc-stacktracer
v2.4.1
Published
Observability SDK for Node.js — captures errors, structured logs, distributed traces and database spans, and ships them to a CC StackTracer ingestion API.
Maintainers
Readme
cc-stacktracer
Observability SDK for Node.js. Captures errors, structured logs, distributed traces and database spans, and ships them to a CC StackTracer ingestion API.
It sits between a bare logger and a full observability stack: lighter than OpenTelemetry to adopt, and opinionated about the payload contract, so your dashboards get consistent data without every route hand-building its own JSON.
npm install cc-stacktracerRequires Node.js 18 or newer. TypeScript types are bundled.
Quick start
Initialize once at startup:
import { StackTrace } from 'cc-stacktracer';
StackTrace.init({
apiKey: process.env.STACKTRACE_API_KEY!,
serviceId: process.env.STACKTRACE_SERVICE_ID!, // UUID from the dashboard /services screen
endpoint: process.env.STACKTRACE_ENDPOINT!, // base URL, without /v1/events
release: process.env.GIT_SHA, // strongly recommended
});Then instrument:
// Structured log
StackTrace.logStructured({
level: 'info',
message: 'invoice.approved',
attributes: { invoiceId, userId: auth.user.id, result: 'success' },
});
// Error with context
try {
await approveInvoice(id);
} catch (err) {
StackTrace.captureException(err as Error, {
http: { method: 'POST', route: '/invoices/:id/approve', status_code: 500, duration_ms: 842 },
correlation: { requestId: req.id },
});
throw err;
}
// Database call — emits a timed span with system/operation/table
await StackTrace.runQuery('postgres', 'invoices.update', () => db.query(sql), { table: 'invoices' });
// Business scope — entity/operation propagate into every span and event inside
await StackTrace.withBusinessContextAsync({ entity: 'invoice', operation: 'approve' }, async () => {
await approveInvoice(id);
});That gives you correlated logs, errors, and a trace waterfall with DB timings.
Framework integrations
Subpath exports, all optional — install only the peer dependency you actually use.
| Import | For |
| --- | --- |
| cc-stacktracer/fastify | Fastify plugin: HTTP spans, route templates, trace context |
| cc-stacktracer/express | Express middleware |
| cc-stacktracer/adonis | AdonisJS integration |
| cc-stacktracer/db-prisma | Prisma query instrumentation |
| cc-stacktracer/db-lucid | Lucid (AdonisJS) query instrumentation |
| cc-stacktracer/generic-http | Any other HTTP framework |
import Fastify from 'fastify';
import stacktracePlugin from 'cc-stacktracer/fastify';
const app = Fastify();
await app.register(stacktracePlugin);Inbound trace context (traceparent) is adopted automatically. Outbound propagation — so a request
crossing services shows up as one trace — is opt-in:
StackTrace.auto({
apiKey,
serviceId,
endpoint,
outboundHttp: { instrumentNodeHttp: true, instrumentFetch: true },
});What ships in the package
Beyond the compiled SDK, the package includes the full integration kit — no separate handoff:
node_modules/cc-stacktracer/
├── docs/
│ ├── client-installation-integration-playbook.md ← full guide + AI prompt pack
│ ├── client-payload-quality-checklist.md ← go-live gate (P0/P1/P2)
│ ├── client-distributed-tracing.md
│ ├── client-onboarding-troubleshooting.md
│ └── …
└── cursor-rules/ ← drop into .cursor/rules/Integrating with an AI assistant? The playbook's section 14 contains ready-to-paste prompts
(integration mapping, business context, DB instrumentation, distributed tracing, and a final audit).
Point your assistant at
node_modules/cc-stacktracer/docs/client-installation-integration-playbook.md and ask it to run
Prompt A.
Using Cursor? Copy node_modules/cc-stacktracer/cursor-rules/*.mdc into your project's
.cursor/rules/ and the assistant picks up the conventions automatically.
Core API
| Function | Purpose |
| --- | --- |
| init(options) | Configure once at startup |
| auto(options) | init plus optional framework/outbound auto-wiring |
| log(message, metadata?) | Simple log |
| logStructured({ level, message, attributes }) | Structured log |
| captureException(error, context?) | Error event |
| runQuery(system, name, fn, options?) | Timed DB span |
| measure(name, fn, options?) | Timed span for arbitrary work |
| withSpan(name, fn, options?) | Manual span |
| withBusinessContext(ctx, fn) | Scope entity/operation onto spans and events |
| setUser(user) / tag(key, value) | Scope metadata |
| flush() / shutdown() | Drain the queue on graceful shutdown |
Every public API is available both on the StackTrace object and as a named export.
Transport and security
- Events are batched and flushed on an interval, with retry and backpressure handling.
- Every request is signed (HMAC-SHA256 over a canonical string, with timestamp and nonce for replay protection). This is automatic — do not implement signing yourself.
- Keep your server clock in sync: requests outside the accepted skew window are rejected.
- Use HTTPS outside local development. Never log the API key.
Documentation
| Document | What it covers | | --- | --- | | Integration playbook | End-to-end guide, payload field reference, AI prompt pack, go-live gates | | Payload quality checklist | P0/P1/P2 checklist with ClickHouse acceptance queries | | Distributed tracing | Cross-service traces and outbound propagation | | Troubleshooting | Common onboarding failures | | CHANGELOG | Release history and migration notes |
Upgrading from cc-stacktrace (1.x)
The package was renamed in 2.0.0. The API is unchanged — only the module specifier:
npm uninstall cc-stacktrace && npm install cc-stacktracerThen find-and-replace cc-stacktrace → cc-stacktracer across your imports. See the
CHANGELOG for details.
License
MIT © Davi Alves
