pinojs / pino-opentelemetry-transport

OpenTelemetry transport for Pino
MIT License
17 stars 3 forks source link

Undefined traceId and spanId with ECMAScript? #172

Open c0j0s opened 1 month ago

c0j0s commented 1 month ago

Hi,

I am trying to get pino to report logs back to OTelCollector. The pipeline is working except for the traceId and spanId fields being undefined.

This only happens in ECMAScript modules, cjs works as expected.

Not an expert on this, please enlighted me.

// test.mjs
'use strict';

import process from 'process';
import * as opentelemetry from '@opentelemetry/sdk-node';
import { PinoInstrumentation } from '@opentelemetry/instrumentation-pino';
import { Resource } from '@opentelemetry/resources';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
import {
  SemanticResourceAttributes
} from '@opentelemetry/semantic-conventions';
import { trace } from '@opentelemetry/api';
import pino from 'pino';

const sdk = new opentelemetry.NodeSDK({
  resource: new Resource({
    [SemanticResourceAttributes.SERVICE_NAME]: 'Pino OpenTelemetry Example'
  }),
  traceExporter: new OTLPTraceExporter(),
  instrumentations: [new PinoInstrumentation()]
});

sdk.start();
console.log("=========SDK Started=========");

process.on('SIGTERM', () => {
  sdk
    .shutdown()
    .then(() => console.log('Tracing terminated'))
    .catch(error => console.log('Error terminating tracing', error))
    .finally(() => process.exit(0));
});

const transport = pino.transport({
  target: 'pino-opentelemetry-transport',
  options: {
    logRecordProcessorOptions: [
      {
        recordProcessorType: 'simple',
        exporterOptions: { protocol: 'console' }
      }
    ],
    loggerName: 'test',
    serviceVersion: '0.0.1'
  }
});

const logger = pino(transport);

setInterval(() => {
  const tracer = trace.getTracer("test-tracer");
  tracer.startActiveSpan('span-name', span => {
    logger.info('Hello time now: ' + new Date().toISOString());
    span.end();
  });
}, 5000);
// test.cjs
'use strict';

const process = require('process');
const opentelemetry = require('@opentelemetry/sdk-node');
const { PinoInstrumentation } = require('@opentelemetry/instrumentation-pino');
const { Resource } = require('@opentelemetry/resources');
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-http');
const {
  SemanticResourceAttributes
} = require('@opentelemetry/semantic-conventions');
const { trace } = require('@opentelemetry/api');

const sdk = new opentelemetry.NodeSDK({
  resource: new Resource({
    [SemanticResourceAttributes.SERVICE_NAME]: 'Pino OpenTelemetry Example'
}),
traceExporter: new OTLPTraceExporter(),
  instrumentations: [new PinoInstrumentation()]
});

sdk.start();
console.log("=========SDK Started=========");

process.on('SIGTERM', () => {
    sdk
    .shutdown()
    .then(() => console.log('Tracing terminated'))
    .catch(error => console.log('Error terminating tracing', error))
    .finally(() => process.exit(0));
});

const pino = require('pino');
const transport = pino.transport({
    target: 'pino-opentelemetry-transport',
    options: {
        logRecordProcessorOptions: [
            {
                recordProcessorType: 'simple',
                exporterOptions: { protocol: 'console' }
      }
    ],
    loggerName: 'test',
    serviceVersion: '0.0.1'
  }
});

const logger = pino(transport);

setInterval(() => {
  const tracer = trace.getTracer("test-tracer");
  tracer.startActiveSpan('span-name', span => {
    logger.info('Hello time now: ' + new Date().toISOString());
    span.end();
  });
}, 5000);

Thank you.

Vunovati commented 1 month ago

Hello, my first hunch is that this is possibly due to pino-instrumentation and the way it works with ESM. There is nothing ESM/CJS specific in the pino-opentelemetry-transport code. I'll try to debug this to confirm this with certainty.

Vunovati commented 1 month ago

This seems to be a tough problem. I was not able to get pino-instrumentation to work when using ESM. I converted the trace-context into .mjs and I stopped getting trace and span ids. I also had this problem when I did not use pino-opentelemetry-transport at all.

It seems like getting ESM to work is not straightforward. I guess that's why it is not documented. Currently, most instrumentations when using ESM are working via import-in-the-middle package. This issue (https://github.com/open-telemetry/opentelemetry-js/issues/4553) might be connected to the problem we are experiencing here.

It might be worth creating an issue in the pino-instrumentation repo.