Skip to content

Commit

Permalink
feat(instr-openai): support openai@5
Browse files Browse the repository at this point in the history
  • Loading branch information
trentm committed Jan 10, 2025
1 parent 6b0bfda commit d48d1cb
Show file tree
Hide file tree
Showing 7 changed files with 70 additions and 20 deletions.
14 changes: 10 additions & 4 deletions packages/instrumentation-openai/.tav.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
openai:
versions:
include: '>=4.19.0 <5'
mode: max-5
commands: npm test
- versions:
include: '>=4.19.0 <6'
mode: max-5
commands: npm test
# It is a little bit hacky to get TAV to consider prereleases.
# Once there are non-prerelease 5.x releases we can drop this block.
- versions:
include: '>=5.0.0-alpha.0 <5.0.0-rc.99'
mode: max-2
commands: npm test
5 changes: 5 additions & 0 deletions packages/instrumentation-openai/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# @elastic/opentelemetry-instrumentation-openai Changelog

## Unreleased

- Support instrumenting openai@5, including preleases. Currently only 5.0.0-alpha.0
has been released.

## v0.4.1

- Include "LICENSE" file in the published package.
Expand Down
26 changes: 22 additions & 4 deletions packages/instrumentation-openai/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion packages/instrumentation-openai/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
"@opentelemetry/exporter-metrics-otlp-proto": "^0.56.0",
"@opentelemetry/exporter-trace-otlp-proto": "^0.56.0",
"@opentelemetry/instrumentation-http": "^0.56.0",
"@opentelemetry/instrumentation-undici": "^0.9.0",
"@opentelemetry/sdk-logs": "^0.56.0",
"@opentelemetry/sdk-metrics": "^1.29.0",
"@opentelemetry/sdk-node": "^0.56.0",
Expand All @@ -85,7 +86,7 @@
"@typescript-eslint/parser": "5.8.1",
"dotenv": "^16.4.5",
"nock": "^13.5.5",
"openai": "^4.57.0",
"openai": "^4.78.0",
"tape": "^5.8.1",
"test-all-versions": "^6.1.0",
"typescript": "4.4.4"
Expand Down
11 changes: 7 additions & 4 deletions packages/instrumentation-openai/src/instrumentation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
InstrumentationBase,
InstrumentationNodeModuleDefinition,
} from '@opentelemetry/instrumentation';
import type { InstrumentationModuleDefinition } from '@opentelemetry/instrumentation';
import { SeverityNumber } from '@opentelemetry/api-logs';

import {
Expand Down Expand Up @@ -98,10 +99,10 @@ export class OpenAIInstrumentation extends InstrumentationBase<OpenAIInstrumenta
}

protected init() {
return [
const defn: InstrumentationModuleDefinition =
new InstrumentationNodeModuleDefinition(
'openai',
['>=4.19.0 <5'],
['>=4.19.0 <6'],
(modExports, modVer) => {
debug(
'instrument openai@%s (isESM=%s), config=%o',
Expand All @@ -122,8 +123,10 @@ export class OpenAIInstrumentation extends InstrumentationBase<OpenAIInstrumenta

return modExports;
}
),
];
);
// Allow instrumentation to work on prereleases, e.g. 5.0.0-alpha.0.
defn.includePrerelease = true;
return [defn];
}

// This is a 'protected' method on class `InstrumentationAbstract`.
Expand Down
22 changes: 16 additions & 6 deletions packages/instrumentation-openai/test/fixtures.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ test('fixtures', async suite => {
/** @type {import('./testutils').TestFixture[]} */
let testFixtures = [
{
only: true, // XXX HERE
name: 'chat-completion (captureMessageContent=true)',
args: ['./fixtures/chat-completion.js'],
cwd: __dirname,
Expand Down Expand Up @@ -271,14 +272,17 @@ test('fixtures', async suite => {
);

if (!usingNock) {
t.equal(spans[1].scope.name, '@opentelemetry/instrumentation-http');
t.equal(spans[1].name, 'POST');
t.equal(
spans[1].parentSpanId,
spans[0].spanId,
'HTTP span is a child of the GenAI span'
);
const urlPath =
spans[1].attributes['http.target'] || // older semconv
spans[1].attributes['url.path'];
t.ok(
spans[1].attributes['http.target'].includes('/chat/completions'),
urlPath.includes('/chat/completions'),
'looks like a .../chat/completions HTTP endpoint'
);
}
Expand Down Expand Up @@ -478,14 +482,17 @@ test('fixtures', async suite => {
);

if (!usingNock) {
t.equal(spans[1].scope.name, '@opentelemetry/instrumentation-http');
t.equal(spans[1].name, 'POST');
t.equal(
spans[1].parentSpanId,
spans[0].spanId,
'HTTP span is a child of the GenAI span'
);
const urlPath =
spans[1].attributes['http.target'] || // older semconv
spans[1].attributes['url.path'];
t.ok(
spans[1].attributes['http.target'].includes('/chat/completions'),
urlPath.includes('/chat/completions'),
'looks like a .../chat/completions HTTP endpoint'
);
}
Expand Down Expand Up @@ -1244,14 +1251,17 @@ test('fixtures', async suite => {
);

if (!usingNock) {
t.equal(spans[1].scope.name, '@opentelemetry/instrumentation-http');
t.equal(spans[1].name, 'POST');
t.equal(
spans[1].parentSpanId,
spans[0].spanId,
'HTTP span is a child of the GenAI span'
);
const urlPath =
spans[1].attributes['http.target'] || // older semconv
spans[1].attributes['url.path'];
t.ok(
spans[1].attributes['http.target'].includes('/embeddings'),
urlPath.includes('/embeddings'),
'looks like a .../embeddings HTTP endpoint'
);
}
Expand Down
9 changes: 8 additions & 1 deletion packages/instrumentation-openai/test/fixtures/telemetry.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ const {
const { OTLPLogExporter } = require('@opentelemetry/exporter-logs-otlp-proto');
const { BatchLogRecordProcessor } = require('@opentelemetry/sdk-logs');
const { HttpInstrumentation } = require('@opentelemetry/instrumentation-http');
const {
UndiciInstrumentation,
} = require('@opentelemetry/instrumentation-undici');
const { OpenAIInstrumentation } = require('../../'); // @elastic/opentelemetry-instrumentation-openai
const { PeriodicExportingMetricReader } = require('@opentelemetry/sdk-metrics');

Expand All @@ -50,7 +53,11 @@ const sdk = new NodeSDK({
traceExporter: new OTLPTraceExporter(),
logRecordProcessor,
metricReader,
instrumentations: [new HttpInstrumentation(), new OpenAIInstrumentation()],
instrumentations: [
new HttpInstrumentation(),
new UndiciInstrumentation(), // openai@5 uses Node.js native fetch(), which is instrumented by instr-undici
new OpenAIInstrumentation(),
],
});

process.on('SIGTERM', async () => {
Expand Down

0 comments on commit d48d1cb

Please sign in to comment.