Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Types returned by getMeter are not compatible #4836

Closed
mbrevda opened this issue Jul 1, 2024 · 2 comments
Closed

Types returned by getMeter are not compatible #4836

mbrevda opened this issue Jul 1, 2024 · 2 comments
Labels
bug Something isn't working information-requested Bug is waiting on additional information from the user triage

Comments

@mbrevda
Copy link

mbrevda commented Jul 1, 2024

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 mbrevda added bug Something isn't working triage labels Jul 1, 2024
@trentm
Copy link
Contributor

trentm commented Jul 10, 2024

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'.

This is referring to two separate node_modules/... trees (one in WORKDIR, one in WORKDIR/packages/utils/...). Is it possible you have an old version of one of the @opentelemetry/api or @opentelemetry/sdk-metrics packages in those two trees?

@JamieDanielson JamieDanielson added the information-requested Bug is waiting on additional information from the user label Jul 10, 2024
@mbrevda
Copy link
Author

mbrevda commented Jul 15, 2024

yes, possible. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working information-requested Bug is waiting on additional information from the user triage
Projects
None yet
Development

No branches or pull requests

3 participants