
Security News
Re-Enabled GitHub Actions Expose Thousands of Repositories to Mini Shai-Hulud
Two compromised GitHub Actions were re-enabled with malicious tags intact, exposing thousands of downstream repositories to Mini Shai-Hulud.
@sebspark/otel
Advanced tools
@sebspark/otelUnified OpenTelemetry implementation for logging, tracing, and metrics — with environment detection, auto-instrumentation, and clean console output for local development.
Install:
npm install @sebspark/otel
# or
yarn add @sebspark/otel
# or
pnpm add @sebspark/otel
This must be the first import in your application:
import { initialize, instrumentations, dispose } from '@sebspark/otel'
await initialize(
instrumentations.undici,
instrumentations.http,
instrumentations.express,
instrumentations.redis,
)
// start your application
// Add a listener for shutdown and call OTEL dispose to ensure messages
// are flushed
process.on('SIGTERM', async () => {
await dispose()
})
Automatically:
resourceAttributestrace_id and span_idSIGTERM| Key | Library |
|---|---|
instrumentations.http | @opentelemetry/instrumentation-http |
instrumentations.express | @opentelemetry/instrumentation-express |
instrumentations.grpc | @opentelemetry/instrumentation-grpc |
instrumentations.redis | @opentelemetry/instrumentation-redis |
instrumentations.undici | @opentelemetry/instrumentation-undici |
instrumentations.socketIo | @opentelemetry/instrumentation-socket.io |
instrumentations.dns | @opentelemetry/instrumentation-dns |
instrumentations.net | @opentelemetry/instrumentation-net |
instrumentations.fs | @opentelemetry/instrumentation-fs |
instrumentations.opensearch | @sebspark/opentelemetry-instrumentation-opensearch |
All instrumentations are lazy-loaded — only the ones passed to initialize are imported.
--importThe recommended pattern is to build otel.ts as a separate entry point and load it via Node's --import flag so it runs before any application code:
src/otel.ts
import { initialize, instrumentations } from '@sebspark/otel'
import pkg from '../package.json' with { type: 'json' }
process.env.OTEL_SERVICE_NAME ??= pkg.name
process.env.OTEL_SERVICE_VERSION ??= pkg.version
await initialize(
instrumentations.http,
instrumentations.express,
instrumentations.grpc,
instrumentations.redis,
instrumentations.undici,
)
Build both entry points:
spark-build src/index.ts src/otel.ts
Start the application with --import:
ENTRYPOINT ["node", "--import=./dist/otel.mjs", "./dist/index.mjs"]
This guarantees OTEL is fully initialized before the first line of application code runs, regardless of import order.
import { getLogger } from '@sebspark/otel'
const logger = getLogger()
// Will do nothing if OTEL is not yet initialized
logger.debug('debug message')
logger.info('something happened')
logger.warn('almost bad')
logger.error('very bad')
Logs inside active spans automatically include:
trace_idspan_idservice.nameservice.versionimport { getTracer } from '@sebspark/otel'
// Will throw if OTEL is not yet initialized
const tracer = getTracer()
await tracer.withTrace('trace.name', async (span) => {
span.setAttribute('user.id', '123')
// do something...
})
If the callback throws:
ERRORSynchronous variant:
tracer.withTraceSync('init.config', (span) => {
// synchronous code
span.setStatus({ code: SpanStatusCode.OK })
})
Nested:
await tracer.withTrace('trace.name', async (span1) => {
span1.setAttribute('user.id', '123')
await tracer.withTrace('trace.name2', span1, async (span2) => {
// do stuff
})
})
Manual span usage:
const span = tracer.startSpan('manual-operation')
span.setAttribute('manual', true)
// work...
span.end()
import { getMeter } from '@sebspark/otel'
// Will throw if OTEL is not yet initialized
const meter = getMeter()
const counter = meter.createCounter('http_requests_total', {
description: 'Total number of HTTP requests',
})
counter.add(1, {
route: '/api/hello',
method: 'GET',
})
When deployed to Cloud Run, GKE, or other cloud environments, telemetry automatically exports to your configured OpenTelemetry Collector.
Set these environment variables:
| Variable | Description | Example |
|---|---|---|
OTEL_EXPORTER_OTLP_ENDPOINT | Collector endpoint | http://otel-collector:4318 |
OTEL_SERVICE_NAME | Override detected service name | trade-api |
OTEL_SERVICE_VERSION | Version of this instance | 1.2.3 |
OTEL_SIMPLE_SPAN_PROCESSOR | Makes OTel use the SimpleSpanProcessor instead of BatchSpanProcessor. Recommended for batch jobs that may produce oversized batches. | true |
Additional GCP/Kubernetes context is auto-detected:
| Env Variable | Attribute Key | Example |
|---|---|---|
K_SERVICE | cloud.run.service | trade-api |
K_REVISION | cloud.run.revision | trade-api-v15 |
POD_NAME | k8s.pod_name | api-1234 |
KUBERNETES_SERVICE_HOST | cloud.orchestrator | kubernetes |
GCP_PROJECT | cloud.account.id | my-gcp-project |
In development, @sebspark/otel outputs human-readable logs, spans, and metrics directly to the console.
| Variable | Affects | Values | Description |
|---|---|---|---|
LOG_LEVEL | Logs | debug,info,warn,error | Minimum severity to print |
SPAN_LEVEL | Traces | OK, ERROR, UNSET (comma-separated) | Only trees containing at least one span with one of these statuses will be printed |
METRIC_FILTER | Metrics | Glob patterns (comma-separated) | Only metrics matching any of the patterns are shown |
Filtered by LOG_LEVEL:
LOG_LEVEL=warn yarn dev
⚠️ [trade-api@1.2.3] GET /orders/limit-exceeded WARN trace_id=abc123 span_id=def456
❌ [trade-api@1.2.3] Order validation failed ERROR trace_id=abc123 span_id=def456
Filtered by SPAN_LEVEL — the entire span tree is printed only if at least one span in the tree matches the status.
SPAN_LEVEL=ERROR yarn dev
[test@1.0.0] 12:00:00.000
└─ express ████████████████████ OK (0 ms–1.00 s)
└─ middleware:auth ███████ OK (0 ms–0.20 s)
└─ handler:getUser ████████████████████ ERROR (0 ms–1.00 s)
SPAN_LEVEL=OK,ERROR yarn dev
[test@1.0.0] 12:01:00.000
└─ express ████████████████████ OK (0 ms–1.00 s)
└─ middleware:auth ███████ OK (0 ms–0.20 s)
Filtered by METRIC_FILTER:
METRIC_FILTER=http.*,db.* yarn dev
📊 [trade-api@1.2.3] 12:00:00.000 📊 express http.server.duration 240ms {route=/api/hello method=GET}
📊 [trade-api@1.2.3] 12:00:01.000 📊 pg db.query.count 1 {query=SELECT * FROM users}
FAQs
Unknown package
The npm package @sebspark/otel receives a total of 351 weekly downloads. As such, @sebspark/otel popularity was classified as not popular.
We found that @sebspark/otel demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 3 open source maintainers collaborating on the project.

Security News
Two compromised GitHub Actions were re-enabled with malicious tags intact, exposing thousands of downstream repositories to Mini Shai-Hulud.

Research
/Security News
A malicious Firefox extension fetches its payload after installation to evade detection, steal Google session cookies, and automate account takeover.

Research
/Security News
The compromise affects MemTensor's MemOS, an open source memory framework for large language models (LLMs) and AI agents. Both npm package @memtensor/memos-cloud-openclaw-plugin and the PyPI package MemoryOS are compromised. They drop cross-platform Go binaries that exfiltrate developer secrets.