opentelemetry-js icon indicating copy to clipboard operation
opentelemetry-js copied to clipboard

Types returned by getMeter are not compatible

Open mbrevda opened this issue 1 year ago • 0 comments
trafficstars

What happened?

Steps to Reproduce

Install latest updates

Expected Result

Types to pass

Actual Result

Type error: (see below)

OpenTelemetry Setup Code

Code
import {
  CompositePropagator,
  W3CTraceContextPropagator,
} from '@opentelemetry/core';
import opentelemetry from '@opentelemetry/api';
import {SimpleSpanProcessor} from '@opentelemetry/sdk-trace-base';
import {NodeTracerProvider} from '@opentelemetry/sdk-trace-node';
import {
  Resource,
  hostDetectorSync,
  osDetectorSync,
  processDetectorSync,
} from '@opentelemetry/resources';
import {SEMRESATTRS_SERVICE_NAME} from '@opentelemetry/semantic-conventions';
import {
  Aggregation,
  InstrumentType,
  MeterProvider,
  PeriodicExportingMetricReader,
  View,
} from '@opentelemetry/sdk-metrics';

// exporters
import {OTLPMetricExporter} from '@opentelemetry/exporter-metrics-otlp-http';
import {OTLPTraceExporter} from '@opentelemetry/exporter-trace-otlp-http';

// instrumentation
import {registerInstrumentations} from '@opentelemetry/instrumentation';
import {HttpInstrumentation} from '@opentelemetry/instrumentation-http';
import {ExpressInstrumentation} from '@opentelemetry/instrumentation-express';
import {PinoInstrumentation} from '@opentelemetry/instrumentation-pino';
import {UndiciInstrumentation} from '@opentelemetry/instrumentation-undici';
import {FsInstrumentation} from '@opentelemetry/instrumentation-fs';

// GCP
import {TraceExporter as GCPTraceExporter} from '@google-cloud/opentelemetry-cloud-trace-exporter';
import {MetricExporter as GCPMetricExporter} from '@google-cloud/opentelemetry-cloud-monitoring-exporter';
import {CloudPropagator as GCPCloudPropagator} from '@google-cloud/opentelemetry-cloud-trace-propagator';
import {GcpDetectorSync} from '@google-cloud/opentelemetry-resource-util';

const onGCP = process.env.K_CONFIGURATION || process.env.CLOUD_RUN_JOB;

// // debug logging
// const {
//   // @ts-ignore
//   DiagConsoleLogger,
//   DiagLogLevel,
//   default: {diag},
// } = await import('@opentelemetry/api');
// diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.DEBUG);

const resource = new Resource({
  'git.revision': process.env.GIT_REVISION,
  [SEMRESATTRS_SERVICE_NAME]: 'careflow-app',
})
  // GcpDetectorSync.detect() is really async, so not all resources are available immediately
  .merge(new GcpDetectorSync().detect())
  .merge(hostDetectorSync.detect())
  .merge(osDetectorSync.detect())
  .merge(processDetectorSync.detect());

// traces
const provider = new NodeTracerProvider({resource});

provider.register({
  propagator: new CompositePropagator({
    propagators: [new W3CTraceContextPropagator(), new GCPCloudPropagator()],
  }),
});

const traceExporter = onGCP ? new GCPTraceExporter() : new OTLPTraceExporter();
provider.addSpanProcessor(new SimpleSpanProcessor(traceExporter));

// metrics
const metricExporter = onGCP
  ? new GCPMetricExporter()
  : new OTLPMetricExporter();

const metricReader = new PeriodicExportingMetricReader({
  exporter: metricExporter,
  exportIntervalMillis: 5000,
});

const meterProvider = new MeterProvider({
  resource,
  readers: [metricReader],
  views: [
    // use ExponentialHistogram aggregation for all Histograms
    // not sure this is what we want, but it's what @GoogleCloudPlatform/opentelemetry-operations-js suggests
    // https://github.com/GoogleCloudPlatform/opentelemetry-operations-js/tree/main/packages/opentelemetry-cloud-monitoring-exporter#enabling-exponential-histograms
    new View({
      aggregation: Aggregation.ExponentialHistogram(),
      instrumentType: InstrumentType.HISTOGRAM,
    }),
  ],
});

opentelemetry.metrics.setGlobalMeterProvider(meterProvider);

// register instrumentations
// do this last so that the global meter provider is already set
// (this will be auto-set on the instrumentations)
registerInstrumentations({
  instrumentations: [
    // not working: https://github.com/open-telemetry/opentelemetry-js-contrib/issues/1587
    new PinoInstrumentation(),
    new FsInstrumentation({
      endHook: (op, {args, span}) => span.updateName(`${op} ${args[0]}`),
    }),
    new UndiciInstrumentation({
      requestHook: (span, req) => span.updateName(`${req.method}: ${req.path}`),
    }),
    new ExpressInstrumentation(),
    new HttpInstrumentation({
      requestHook: (span, req) => {
        // req can be of different types that don't share a common interface
        let path = 'url' in req ? req.url : '';
        path ?? ('path' in req ? req.path : '');
        span.updateName(`${req.method}: ${path}`);
      },
    }),
  ],
});

const cleanup = async () => {
  await Promise.all([traceExporter.shutdown(), metricExporter.shutdown()]);
};
process.on('SIGTERM', cleanup);
process.on('exit', cleanup);

package.json

package
{
  "name": "xxx",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "type": "module",
  "directories": {
    "test": "tests"
  },
  "scripts": {
    "test": "xxx"
  },
  "imports": {
    "#src/*": "./src/*.ts"
  },
  "exports": {
    "./*": "./src/*.ts"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@google-cloud/opentelemetry-cloud-monitoring-exporter": "0.18.0",
    "@google-cloud/opentelemetry-cloud-trace-exporter": "2.2.0",
    "@google-cloud/opentelemetry-cloud-trace-propagator": "0.18.0",
    "@google-cloud/opentelemetry-resource-util": "2.2.0",
    "@opentelemetry/api": "1.9.0",
    "@opentelemetry/core": "1.25.1",
    "@opentelemetry/exporter-metrics-otlp-http": "0.52.1",
    "@opentelemetry/exporter-trace-otlp-http": "0.52.1",
    "@opentelemetry/instrumentation": "0.52.1",
    "@opentelemetry/instrumentation-express": "0.40.1",
    "@opentelemetry/instrumentation-fs": "0.13.0",
    "@opentelemetry/instrumentation-http": "0.52.1",
    "@opentelemetry/instrumentation-pino": "0.40.0",
    "@opentelemetry/instrumentation-undici": "0.3.0",
    "@opentelemetry/resources": "1.25.1",
    "@opentelemetry/sdk-metrics": "1.25.1",
    "@opentelemetry/sdk-trace-node": "1.25.1",
    "@opentelemetry/semantic-conventions": "1.25.1",
    "file-type": "19.0.0",
    "fetch-retry": "6.0.0",
    "pino": "9.1.0",
    "pino-pretty": "11.1.0"
  },
  "devDependencies": {
    "esmock": "2.6.6",
    "memfs": "4.9.3",
    "pino": "9.1.0",
    "tsx": "4.11.2"
  }
}

Relevant log output

opentelemetry.ts:98:46 - error TS2345: Argument of type 'import("WORKDIR/node_modules/@opentelemetry/sdk-metrics/build/src/MeterProvider").MeterProvider' is not assignable to parameter of type 'import("WORKDIR/packages/utils/node_modules/@opentelemetry/api/build/src/metrics/MeterProvider").MeterProvider'.
  The types returned by 'getMeter(...)' are incompatible between these types.
    Property 'createGauge' is missing in type 'import("WORKDIR/node_modules/@opentelemetry/api/build/src/metrics/Meter").Meter' but required in type 'import("WORKDIR/packages/utils/node_modules/@opentelemetry/api/build/src/metrics/Meter").Meter'.

98 opentelemetry.metrics.setGlobalMeterProvider(meterProvider);
                                                ~~~~~~~~~~~~~

  packages/utils/node_modules/@opentelemetry/api/build/src/metrics/Meter.d.ts:24:5
    24     createGauge<AttributesTypes extends MetricAttributes = MetricAttributes>(name: string, options?: MetricOptions): Gauge<AttributesTypes>;
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    'createGauge' is declared here.

mbrevda avatar Jul 01 '24 13:07 mbrevda