
Research
/Security News
PolinRider Spreads Through Compromised GitHub Accounts and Packagist
Operators behind PolinRider used a compromised GitHub account to plant malware in four development versions of a Packagist package with 700,000+ downloads.
@sylphx/cat-tracing
Advanced tools
W3C Trace Context support for @sylphx/cat logger
1.46 KB • W3C compliant • Distributed tracing • Auto trace ID generation
npm install @sylphx/cat @sylphx/cat-tracing
Adds W3C Trace Context support to @sylphx/cat logger. Automatically generates and propagates trace IDs and span IDs for distributed tracing across microservices. Compatible with OpenTelemetry, Datadog, New Relic, and any W3C Trace Context-compliant system.
import { createLogger } from '@sylphx/cat'
import { tracingPlugin } from '@sylphx/cat-tracing'
const logger = createLogger({
plugins: [tracingPlugin()]
})
logger.info('Request processed')
// {"level":"info","message":"Request processed","traceId":"4bf92f3577b34da6a3ce929d0e0e4736","spanId":"00f067aa0ba902b7"}
import { createLogger } from '@sylphx/cat'
import { TracingPlugin, tracingPlugin } from '@sylphx/cat-tracing'
import express from 'express'
const tracingPluginInstance = tracingPlugin()
const logger = createLogger({
plugins: [tracingPluginInstance]
})
const app = express()
app.use((req, res, next) => {
// Extract trace context from incoming request
const context = TracingPlugin.fromHeaders(req.headers)
if (context) {
tracingPluginInstance.setTraceContext(context)
}
logger.info({ req }, 'Request received')
next()
})
app.get('/api/users', async (req, res) => {
// Make downstream request with trace context
const context = tracingPluginInstance.getContext()
const headers = context ? TracingPlugin.toHeaders(context) : {}
const response = await fetch('http://downstream-service/users', {
headers: {
...headers, // Propagates traceparent header
'Content-Type': 'application/json'
}
})
res.json(await response.json())
})
import { createLogger } from '@sylphx/cat'
import { tracingPlugin, createTraceContext } from '@sylphx/cat-tracing'
const tracing = tracingPlugin()
const logger = createLogger({
plugins: [tracing]
})
// Create custom trace context
const context = createTraceContext({
traceId: '4bf92f3577b34da6a3ce929d0e0e4736',
spanId: '00f067aa0ba902b7',
sampled: true
})
tracing.setTraceContext(context)
logger.info('Custom trace context')
tracingPlugin(options?: TracingPluginOptions): PluginCreates a tracing plugin instance.
Options:
enabled?: boolean - Enable tracing (default: true)generateTraceId?: boolean - Auto-generate trace IDs if not present (default: true)traceparentHeader?: string - Header name for trace parent (default: 'traceparent')getTraceContext?: () => TraceContext | null - Custom trace context getterincludeTraceContext?: boolean - Include trace context in logs (default: true)Example:
tracingPlugin({
enabled: true,
generateTraceId: true,
getTraceContext: () => {
// Custom logic to get trace context
// e.g., from AsyncLocalStorage
return asyncStorage.getStore()?.traceContext
}
})
createTraceContext(options?: Partial<TraceContext>): TraceContextCreates a new trace context with optional overrides.
import { createTraceContext } from '@sylphx/cat-tracing'
const context = createTraceContext()
// { traceId: '...', spanId: '...', traceFlags: 1 }
generateTraceId(): stringGenerates a random 32-character hexadecimal trace ID.
import { generateTraceId } from '@sylphx/cat-tracing'
const traceId = generateTraceId()
// '4bf92f3577b34da6a3ce929d0e0e4736'
generateSpanId(): stringGenerates a random 16-character hexadecimal span ID.
import { generateSpanId } from '@sylphx/cat-tracing'
const spanId = generateSpanId()
// '00f067aa0ba902b7'
parseTraceparent(traceparent: string): TraceContext | nullParses a W3C traceparent header.
import { parseTraceparent } from '@sylphx/cat-tracing'
const context = parseTraceparent('00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01')
// { traceId: '4bf92f3577b34da6a3ce929d0e0e4736', spanId: '00f067aa0ba902b7', traceFlags: 1 }
formatTraceparent(context: TraceContext): stringFormats a trace context as a W3C traceparent header.
import { formatTraceparent } from '@sylphx/cat-tracing'
const header = formatTraceparent({
traceId: '4bf92f3577b34da6a3ce929d0e0e4736',
spanId: '00f067aa0ba902b7',
traceFlags: 1
})
// '00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01'
TracingPlugin.fromHeaders(headers: Record<string, string | string[]>): TraceContext | nullExtracts trace context from HTTP headers.
const context = TracingPlugin.fromHeaders(request.headers)
TracingPlugin.toHeaders(context: TraceContext): Record<string, string>Converts trace context to HTTP headers.
const headers = TracingPlugin.toHeaders(context)
// { traceparent: '00-...-...-01' }
setTraceContext(context: TraceContext | null): voidSets the current trace context.
const tracing = tracingPlugin()
tracing.setTraceContext(context)
getContext(): TraceContext | nullGets the current trace context.
const tracing = tracingPlugin()
const context = tracing.getContext()
The plugin follows the W3C Trace Context specification:
traceparent header format:
00-{trace-id}-{parent-id}-{trace-flags}
Example:
00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
│ │ │ │
│ │ │ └─ flags (01 = sampled)
│ │ └────────────────── parent-id (16 hex chars)
│ └───────────────────────────────────────────────── trace-id (32 hex chars)
└────────────────────────────────────────────────────── version (00)
import { createLogger } from '@sylphx/cat'
import { tracingPlugin } from '@sylphx/cat-tracing'
import { otlpTransport } from '@sylphx/cat-otlp'
const logger = createLogger({
plugins: [tracingPlugin()],
transports: [
otlpTransport({
endpoint: 'https://api.honeycomb.io/v1/logs',
headers: { 'x-honeycomb-team': process.env.API_KEY }
})
]
})
logger.info('Traced and exported to OTLP')
// Trace context automatically included in OTLP export
import { AsyncLocalStorage } from 'async_hooks'
import { createLogger } from '@sylphx/cat'
import { tracingPlugin } from '@sylphx/cat-tracing'
const asyncStorage = new AsyncLocalStorage()
const logger = createLogger({
plugins: [
tracingPlugin({
getTraceContext: () => asyncStorage.getStore()?.traceContext
})
]
})
// In your request handler
app.use((req, res, next) => {
const context = TracingPlugin.fromHeaders(req.headers) || createTraceContext()
asyncStorage.run({ traceContext: context }, () => {
next()
})
})
MIT © Kyle Zhu
FAQs
W3C Trace Context support for @sylphx/cat logger
We found that @sylphx/cat-tracing demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Research
/Security News
Operators behind PolinRider used a compromised GitHub account to plant malware in four development versions of a Packagist package with 700,000+ downloads.

Security News
GitHub Actions now supports cache-mode, a least-privilege control on the Actions cache aimed at the cache poisoning technique behind recent compromises.

Company News
Allow myself to introduce... myself.