OTel SDK — Node.js
Send logs directly from a Node.js application to xScaler using the OpenTelemetry JS SDK over OTLP/HTTP.
:::warning Required headers
Both headers must be passed to OTLPLogExporter:
Authorization: "Bearer <token>"X-Scope-OrgID: "<tenant-id>":::
Install dependencies
npm install @opentelemetry/sdk-node \
@opentelemetry/exporter-logs-otlp-http \
@opentelemetry/sdk-logs \
@opentelemetry/winston-transport
Setup
Create otel.js and require it before your application code:
const { OTLPLogExporter } = require('@opentelemetry/exporter-logs-otlp-http');
const { LoggerProvider, BatchLogRecordProcessor } = require('@opentelemetry/sdk-logs');
const { logs } = require('@opentelemetry/api-logs');
const { Resource } = require('@opentelemetry/resources');
const { SEMRESATTRS_SERVICE_NAME } = require('@opentelemetry/semantic-conventions');
const exporter = new OTLPLogExporter({
url: 'https://euw1-01.l.xscalerlabs.com/otlp/v1/logs',
headers: {
Authorization: `Bearer ${process.env.XSCALER_TOKEN}`,
'X-Scope-OrgID': process.env.XSCALER_TENANT_ID,
},
});
const provider = new LoggerProvider({
resource: new Resource({
[SEMRESATTRS_SERVICE_NAME]: 'my-service',
}),
});
provider.addLogRecordProcessor(new BatchLogRecordProcessor(exporter));
logs.setGlobalLoggerProvider(provider);
// Flush on exit
process.on('SIGTERM', async () => {
await provider.shutdown();
process.exit(0);
});
Use with Winston
npm install winston @opentelemetry/winston-transport
const winston = require('winston');
const { OpenTelemetryTransportV3 } = require('@opentelemetry/winston-transport');
// otel.js must be required first (see Setup above)
require('./otel');
const logger = winston.createLogger({
level: 'info',
transports: [
new winston.transports.Console(),
new OpenTelemetryTransportV3(),
],
});
logger.info('application started', { version: '1.0.0' });
logger.warn('high memory usage', { usedMb: 480 });
logger.error('database connection failed', { host: 'db.internal' });
Use with Pino
npm install pino @opentelemetry/pino-transport
const pino = require('pino');
const logger = pino({
transport: {
targets: [
{ target: 'pino-pretty' },
{
target: '@opentelemetry/pino-transport',
options: {
resourceAttributes: { 'service.name': 'my-service' },
},
},
],
},
});
Run your application
XSCALER_TOKEN=<token> XSCALER_TENANT_ID=<tenant-id> node -r ./otel.js app.js
Troubleshooting
Logs not arriving
- Verify the
urlis the full path:https://euw1-01.l.xscalerlabs.com/otlp/v1/logs - Check
AuthorizationandX-Scope-OrgIDare both in theheadersobject. - Enable SDK diagnostics:
OTEL_LOG_LEVEL=debug node -r ./otel.js app.js
401 Unauthorized
- Confirm
XSCALER_TOKENis set and the header readsBearer <token>(with the prefix and space).
400 Bad Request
X-Scope-OrgIDis missing fromheadersor uses the wrong key name.