Skip to content

Commit 50b3fd8

Browse files
committed
openai: make services entirely optional when initializing (#3420)
1 parent 3026e93 commit 50b3fd8

File tree

8 files changed

+86
-18
lines changed

8 files changed

+86
-18
lines changed

.github/workflows/plugins.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -786,6 +786,23 @@ jobs:
786786
uses: ./.github/actions/testagent/logs
787787
- uses: codecov/codecov-action@v2
788788

789+
openai:
790+
runs-on: ubuntu-latest
791+
env:
792+
PLUGINS: openai
793+
steps:
794+
- uses: actions/checkout@v2
795+
- uses: ./.github/actions/testagent/start
796+
- uses: ./.github/actions/node/setup
797+
- run: yarn install
798+
- uses: ./.github/actions/node/oldest
799+
- run: yarn test:plugins:ci
800+
- uses: ./.github/actions/node/latest
801+
- run: yarn test:plugins:ci
802+
- if: always()
803+
uses: ./.github/actions/testagent/logs
804+
- uses: codecov/codecov-action@v2
805+
789806
opensearch:
790807
runs-on: ubuntu-latest
791808
services:

packages/datadog-plugin-openai/src/index.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ class OpenApiPlugin extends TracingPlugin {
2626
this.sampler = new Sampler(0.1) // default 10% log sampling
2727

2828
// hoist the max length env var to avoid making all of these functions a class method
29-
MAX_TEXT_LEN = this._tracerConfig.openaiSpanCharLimit
29+
if (this._tracerConfig) {
30+
MAX_TEXT_LEN = this._tracerConfig.openaiSpanCharLimit
31+
}
3032
}
3133

3234
configure (config) {
@@ -547,7 +549,7 @@ function usageExtraction (tags, body) {
547549
}
548550

549551
function truncateApiKey (apiKey) {
550-
return `sk-...${apiKey.substr(apiKey.length - 4)}`
552+
return apiKey && `sk-...${apiKey.substr(apiKey.length - 4)}`
551553
}
552554

553555
/**

packages/datadog-plugin-openai/src/services.js

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use strict'
22

33
const { DogStatsDClient, NoopDogStatsDClient } = require('../../dd-trace/src/dogstatsd')
4-
const ExternalLogger = require('../../dd-trace/src/external-logger/src')
4+
const { ExternalLogger, NoopExternalLogger } = require('../../dd-trace/src/external-logger/src')
55

66
const FLUSH_INTERVAL = 10 * 1000
77

@@ -10,7 +10,7 @@ let logger = null
1010
let interval = null
1111

1212
module.exports.init = function (tracerConfig) {
13-
if (tracerConfig.dogstatsd) {
13+
if (tracerConfig && tracerConfig.dogstatsd) {
1414
metrics = new DogStatsDClient({
1515
host: tracerConfig.dogstatsd.hostname,
1616
port: tracerConfig.dogstatsd.port,
@@ -24,13 +24,17 @@ module.exports.init = function (tracerConfig) {
2424
metrics = new NoopDogStatsDClient()
2525
}
2626

27-
logger = new ExternalLogger({
28-
ddsource: 'openai',
29-
hostname: tracerConfig.hostname,
30-
service: tracerConfig.service,
31-
apiKey: tracerConfig.apiKey,
32-
interval: FLUSH_INTERVAL
33-
})
27+
if (tracerConfig && tracerConfig.apiKey) {
28+
logger = new ExternalLogger({
29+
ddsource: 'openai',
30+
hostname: tracerConfig.hostname,
31+
service: tracerConfig.service,
32+
apiKey: tracerConfig.apiKey,
33+
interval: FLUSH_INTERVAL
34+
})
35+
} else {
36+
logger = new NoopExternalLogger()
37+
}
3438

3539
interval = setInterval(() => {
3640
metrics.flush()

packages/datadog-plugin-openai/test/index.spec.js

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,15 @@ const { expect } = require('chai')
66
const semver = require('semver')
77
const nock = require('nock')
88
const sinon = require('sinon')
9+
const { spawn } = require('child_process')
910

1011
const agent = require('../../dd-trace/test/plugins/agent')
1112
const { DogStatsDClient } = require('../../dd-trace/src/dogstatsd')
12-
const ExternalLogger = require('../../dd-trace/src/external-logger/src')
13+
const { NoopExternalLogger } = require('../../dd-trace/src/external-logger/src')
1314
const Sampler = require('../../dd-trace/src/sampler')
1415

16+
const tracerRequirePath = '../../dd-trace'
17+
1518
describe('Plugin', () => {
1619
let openai
1720
let clock
@@ -20,8 +23,10 @@ describe('Plugin', () => {
2023

2124
describe('openai', () => {
2225
withVersions('openai', 'openai', version => {
26+
const moduleRequirePath = `../../../versions/openai@${version}`
27+
2328
beforeEach(() => {
24-
require('../../dd-trace')
29+
require(tracerRequirePath)
2530
})
2631

2732
before(() => {
@@ -34,7 +39,7 @@ describe('Plugin', () => {
3439

3540
beforeEach(() => {
3641
clock = sinon.useFakeTimers()
37-
const { Configuration, OpenAIApi } = require(`../../../versions/openai@${version}`).get()
42+
const { Configuration, OpenAIApi } = require(moduleRequirePath).get()
3843

3944
const configuration = new Configuration({
4045
apiKey: 'sk-DATADOG-ACCEPTANCE-TESTS'
@@ -43,7 +48,7 @@ describe('Plugin', () => {
4348
openai = new OpenAIApi(configuration)
4449

4550
metricStub = sinon.stub(DogStatsDClient.prototype, '_add')
46-
externalLoggerStub = sinon.stub(ExternalLogger.prototype, 'log')
51+
externalLoggerStub = sinon.stub(NoopExternalLogger.prototype, 'log')
4752
sinon.stub(Sampler.prototype, 'isSampled').returns(true)
4853
})
4954

@@ -52,6 +57,20 @@ describe('Plugin', () => {
5257
sinon.restore()
5358
})
5459

60+
describe('without initialization', () => {
61+
it('should not error', (done) => {
62+
spawn('node', ['no-init'], {
63+
cwd: __dirname,
64+
stdio: 'inherit',
65+
env: {
66+
...process.env,
67+
PATH_TO_DDTRACE: tracerRequirePath,
68+
PATH_TO_OPENAI: moduleRequirePath
69+
}
70+
}).on('exit', done) // non-zero exit status fails test
71+
})
72+
})
73+
5574
describe('createCompletion()', () => {
5675
let scope
5776

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#!/usr/bin/env node
2+
3+
/**
4+
* Due to the complexity of the service initialization required by openai
5+
* there was a bug where when requiring dd-trace followed by openai
6+
* would result in an error if dd-trace wasn't first initialized.
7+
*
8+
* @see https://github.com/DataDog/dd-trace-js/issues/3357
9+
*/
10+
require(process.env.PATH_TO_DDTRACE)
11+
require(process.env.PATH_TO_OPENAI).get()

packages/datadog-plugin-openai/test/services.spec.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ describe('Plugin', () => {
99
services.shutdown()
1010
})
1111

12-
it('dogstatsd does not throw', () => {
12+
it('dogstatsd does not throw when missing .dogstatsd', () => {
1313
const service = services.init({
1414
hostname: 'foo',
1515
service: 'bar',
@@ -30,6 +30,13 @@ describe('Plugin', () => {
3030

3131
service.logger.log('hello')
3232
})
33+
34+
it('logger does not throw when passing in null', () => {
35+
const service = services.init(null)
36+
37+
service.metrics.increment('mykey')
38+
service.logger.log('hello')
39+
})
3340
})
3441
})
3542
})

packages/dd-trace/src/external-logger/src/index.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,4 +127,12 @@ class ExternalLogger {
127127
}
128128
}
129129

130-
module.exports = ExternalLogger
130+
class NoopExternalLogger {
131+
log () { }
132+
enqueue () { }
133+
shutdown () { }
134+
flush () { }
135+
}
136+
137+
module.exports.ExternalLogger = ExternalLogger
138+
module.exports.NoopExternalLogger = NoopExternalLogger

packages/dd-trace/src/external-logger/test/index.spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ describe('External Logger', () => {
1515
beforeEach(() => {
1616
errorLog = sinon.spy(tracerLogger, 'error')
1717

18-
const ExternalLogger = proxyquire('../src', {
18+
const { ExternalLogger } = proxyquire('../src', {
1919
'../../log': {
2020
error: errorLog
2121
}

0 commit comments

Comments
 (0)