Skip to content

Commit 31ab012

Browse files
authored
fix(exporter-collector): all http export requests should share same a… (#1863)
* fix(exporter-collector): all http export requests should share same agent * fix(exporter-collector): no log warning on agent options with default keepAlive * fix(collector-exporter): add excpetion message to logger when agent creation fails * chore: fix typo in test * style(exporter-collector): object spread undefined
1 parent a78bb80 commit 31ab012

File tree

3 files changed

+42
-21
lines changed

3 files changed

+42
-21
lines changed

packages/opentelemetry-exporter-collector/src/platform/node/CollectorExporterNodeBase.ts

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import { CollectorExporterBase } from '../../CollectorExporterBase';
2121
import { CollectorExporterNodeConfigBase } from './types';
2222
import * as collectorTypes from '../../types';
2323
import { parseHeaders } from '../../util';
24-
import { sendWithHttp } from './util';
24+
import { createHttpAgent, sendWithHttp } from './util';
2525

2626
/**
2727
* Collector Metric Exporter abstract base class
@@ -36,26 +36,15 @@ export abstract class CollectorExporterNodeBase<
3636
> {
3737
DEFAULT_HEADERS: Record<string, string> = {};
3838
headers: Record<string, string>;
39-
keepAlive: boolean = true;
40-
httpAgentOptions: http.AgentOptions | https.AgentOptions = {};
39+
agent: http.Agent | https.Agent | undefined;
4140
constructor(config: CollectorExporterNodeConfigBase = {}) {
4241
super(config);
4342
if ((config as any).metadata) {
4443
this.logger.warn('Metadata cannot be set when using http');
4544
}
4645
this.headers =
4746
parseHeaders(config.headers, this.logger) || this.DEFAULT_HEADERS;
48-
if (typeof config.keepAlive === 'boolean') {
49-
this.keepAlive = config.keepAlive;
50-
}
51-
if (config.httpAgentOptions) {
52-
if (!this.keepAlive) {
53-
this.logger.warn(
54-
'httpAgentOptions is used only when keepAlive is true'
55-
);
56-
}
57-
this.httpAgentOptions = Object.assign({}, config.httpAgentOptions);
58-
}
47+
this.agent = createHttpAgent(this.logger, config);
5948
}
6049

6150
onInit(_config: CollectorExporterNodeConfigBase): void {

packages/opentelemetry-exporter-collector/src/platform/node/util.ts

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ import * as http from 'http';
1818
import * as https from 'https';
1919
import * as collectorTypes from '../../types';
2020
import { CollectorExporterNodeBase } from './CollectorExporterNodeBase';
21+
import { CollectorExporterNodeConfigBase } from '.';
22+
import { Logger } from '@opentelemetry/api';
2123

2224
/**
2325
* Sends data using http
@@ -46,16 +48,10 @@ export function sendWithHttp<ExportItem, ServiceRequest>(
4648
'Content-Type': contentType,
4749
...collector.headers,
4850
},
51+
agent: collector.agent,
4952
};
5053

5154
const request = parsedUrl.protocol === 'http:' ? http.request : https.request;
52-
const Agent = parsedUrl.protocol === 'http:' ? http.Agent : https.Agent;
53-
if (collector.keepAlive) {
54-
options.agent = new Agent({
55-
...collector.httpAgentOptions,
56-
keepAlive: true,
57-
});
58-
}
5955

6056
const req = request(options, (res: http.IncomingMessage) => {
6157
let data = '';
@@ -81,3 +77,26 @@ export function sendWithHttp<ExportItem, ServiceRequest>(
8177
req.write(data);
8278
req.end();
8379
}
80+
81+
export function createHttpAgent(
82+
logger: Logger,
83+
config: CollectorExporterNodeConfigBase
84+
): http.Agent | https.Agent | undefined {
85+
if (config.httpAgentOptions && config.keepAlive === false) {
86+
logger.warn('httpAgentOptions is used only when keepAlive is true');
87+
return undefined;
88+
}
89+
90+
if (config.keepAlive === false || !config.url) return undefined;
91+
92+
try {
93+
const parsedUrl = new url.URL(config.url as string);
94+
const Agent = parsedUrl.protocol === 'http:' ? http.Agent : https.Agent;
95+
return new Agent({ keepAlive: true, ...config.httpAgentOptions });
96+
} catch (err) {
97+
logger.error(
98+
`collector exporter failed to create http agent. err: ${err.message}`
99+
);
100+
return undefined;
101+
}
102+
}

packages/opentelemetry-exporter-collector/test/node/CollectorTraceExporter.test.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,19 @@ describe('CollectorTraceExporter - node with json over http', () => {
126126
});
127127
});
128128

129+
it('different http export requests should use the same agent', done => {
130+
collectorExporter.export(spans, () => {});
131+
collectorExporter.export(spans, () => {});
132+
133+
setTimeout(() => {
134+
const [firstExportAgent, secondExportAgent] = spyRequest.args.map(
135+
a => a[0].agent
136+
);
137+
assert.strictEqual(firstExportAgent, secondExportAgent);
138+
done();
139+
});
140+
});
141+
129142
it('should successfully send the spans', done => {
130143
collectorExporter.export(spans, () => {});
131144

0 commit comments

Comments
 (0)