npm package: @onelog-sdk/node
Description: OneLog Node SDK for unified tracing, logging, and error handling.
Latest version: 0.1.9

# @onelog/node

Unified Node.js SDK for tracing, logging, HTTP calls, and exception capture. Drop it into any Express-based service to get consistent telemetry with one import.

## Install
```bash
npm install @onelog/node
```

## Quickstart
```ts
import express from 'express';
import {
  sdkStartPromise,
  instrumentApp,
  createLogger,
  errorMiddleware,
  httpCall,
} from '@onelog/node';

const logger = createLogger();
const app = express();
const PORT = process.env.PORT || 8700;

app.use(express.json());
instrumentApp(app, logger, process.env.MAIN_MODULE);

app.get('/health', (_req, res) => res.json({ status: 'ok', module: process.env.MAIN_MODULE }));

app.post('/do', async (req, res, next) => {
  try {
    const reply = await httpCall(
      process.env.PEER_URL || 'http://localhost:3001/work',
      { method: 'POST', body: req.body },
      logger,
      { flow: 'demo' }
    );
    res.json({ ok: true, reply });
  } catch (err) { next(err); }
});

app.use(errorMiddleware(logger));

sdkStartPromise.finally(() => {
  app.listen(PORT, () => logger.info({ port: PORT }, 'Service started'));
});
```

### Dynamic attributes at runtime
Set attributes without restarting—globally or per request—and they’ll show up in spans, logs, HTTP call logs, and error responses.

```ts
import {
  setGlobalAttributes,
  setRequestAttributes,
  withRequestAttributes,
} from '@onelog/node';

// Global attributes (applied to all spans/logs going forward)
setGlobalAttributes({ version: '1.2.3', cluster: 'blue' });

// Per-request attributes (inside middleware/handlers)
app.use((req, _res, next) => {
  setRequestAttributes({ userId: req.get('x-user-id') });
  next();
});

// Or wrap a block with temporary attributes
await withRequestAttributes({ tenant: 'acme' }, async () => {
  // logs and spans inside here carry tenant=acme
});
```

## What’s inside
- **Tracing** (`sdkStartPromise`, `instrumentApp`) — boots OpenTelemetry Node SDK with HTTP/Express/undici auto-instrumentation and renames spans to `[module] METHOD /path` while adding `module.name`.
- **Logging** (`createLogger`) — Pino with dual transports: OTLP-friendly output plus pretty console, pre-tagged with env/app/module.
- **Exceptions** (`errorMiddleware`) — records exceptions on the active span, sets span status to ERROR, logs details, and returns JSON.
- **HTTP calls** (`httpCall`) — fetch wrapper with consistent logging, JSON handling, and error propagation.
- **Runtime attributes** (`setGlobalAttributes`, `setRequestAttributes`) — update attributes on the fly (globally or per request) and they flow into spans, logs, outbound calls, and error responses.

## Environment variables
- `PORT` — HTTP port for your service.
- `MAIN_MODULE` — logical module name (shown in spans and logs).
- `MAIN_APP` — application/system name.
- `MAIN_ENV` — environment (production/staging/dev).
- `OTEL_EXPORTER_OTLP_ENDPOINT` — OTLP HTTP endpoint (e.g., `http://localhost:4318`, no trailing slash).
- `OTEL_SERVICE_NAME` — service name for tracing.
- `OTEL_NAMESPACE` / `OTEL_SERVICE_NAMESPACE` — optional namespace.
- Downstream URLs as needed: `PEER_URL`, etc.
- `ONELOG_EXPRESS_LAYERS` — set to `true` to include middleware/request_handler spans (defaults to lean mode without them).
- `HTTP_PROXY` / `HTTPS_PROXY` (also lowercase variants) — if present, outbound HTTP (including OTLP export) uses the proxy.

## Build (for contributors)
```bash
npm install
npm run build   # tsup → dist/index.{mjs,cjs} + types, minified
```

## Notes
- Requires Node 18+.
- Auto-instrumentation is focused on HTTP/Express/undici; noisy instrumentations are off by default.