Skip to content

Commit

Permalink
fix(otlp-log-exporter-http): usehex for browser module
Browse files Browse the repository at this point in the history
  • Loading branch information
Nico385412 committed Jun 13, 2023
1 parent cdab6c8 commit c670d2c
Show file tree
Hide file tree
Showing 2 changed files with 145 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export class OTLPLogExporter
}

convert(logRecords: ReadableLogRecord[]): IExportLogsServiceRequest {
return createExportLogsServiceRequest(logRecords);
return createExportLogsServiceRequest(logRecords, true);
}

getDefaultUrl(config: OTLPExporterConfigBase): string {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,32 @@
* limitations under the License.
*/

import { diag } from '@opentelemetry/api';
import * as assert from 'assert';
import * as sinon from 'sinon';
import * as http from 'http';

import * as Config from '../../src/platform/config';
import { OTLPLogExporter } from '../../src/platform/browser';
import { OTLPExporterConfigBase } from '@opentelemetry/otlp-exporter-base';
import { ReadableLogRecord } from '@opentelemetry/sdk-logs';
import { MockedResponse, ensureExportLogsServiceRequestIsSet, ensureExportedLogRecordIsCorrect, mockedReadableLogRecord } from '../logHelper';
import { PassThrough, Stream } from 'stream';
import { IExportLogsServiceRequest } from '@opentelemetry/otlp-transformer';
import { ExportResultCode } from '@opentelemetry/core';

let fakeRequest: PassThrough;

describe('OTLPLogExporter', () => {
let envSource: Record<string, any>;
let collectorExporter: OTLPLogExporter;
let collectorExporterConfig: OTLPExporterConfigBase;
let logs: ReadableLogRecord[];

afterEach(() => {
fakeRequest = new Stream.PassThrough();
sinon.restore();
});

if (typeof process === 'undefined') {
envSource = globalThis as unknown as Record<string, any>;
Expand Down Expand Up @@ -61,4 +79,130 @@ describe('OTLPLogExporter', () => {
assert.strictEqual(getDefaultUrl.callCount, 2);
});
});

describe('export', () => {
beforeEach(() => {
collectorExporterConfig = {
headers: {
foo: 'bar',
},
hostname: 'foo',
url: 'http://foo.bar.com'
};
collectorExporter = new OTLPLogExporter(collectorExporterConfig);
logs = [];
logs.push(Object.assign({}, mockedReadableLogRecord));
});
afterEach(() => {
sinon.restore();
});

it('should open the connection', done => {
sinon.stub(http, 'request').callsFake((options: any, cb: any) => {
assert.strictEqual(options.hostname, 'foo.bar.com');
assert.strictEqual(options.method, 'POST');
assert.strictEqual(options.path, '/');

const mockRes = new MockedResponse(200);
cb(mockRes);
mockRes.send('success');
done();
return fakeRequest as any;
});
collectorExporter.export(logs, () => {});
});

it('should set custom headers', done => {

sinon.stub(http, 'request').callsFake((options: any, cb: any) => {
assert.strictEqual(options.headers['foo'], 'bar');

const mockRes = new MockedResponse(200);
cb(mockRes);
mockRes.send('success');
done();
return fakeRequest as any;
});

collectorExporter.export(logs, () => {});
});

it('should have keep alive and keepAliveMsecs option set', done => {

sinon.stub(http, 'request').callsFake((options: any, cb: any) => {
assert.strictEqual(options.agent.keepAlive, true);
assert.strictEqual(options.agent.options.keepAliveMsecs, 2000);

const mockRes = new MockedResponse(200);
cb(mockRes);
mockRes.send('success');
done();
return fakeRequest as any;
});

collectorExporter.export(logs, () => {});
});

it('should successfully send the logs', done => {
const fakeRequest = new Stream.PassThrough();
sinon.stub(http, 'request').returns(fakeRequest as any);

let buff = Buffer.from('');
fakeRequest.on('end', () => {
const responseBody = buff.toString();
const json = JSON.parse(responseBody) as IExportLogsServiceRequest;
const log1 = json.resourceLogs?.[0].scopeLogs?.[0].logRecords?.[0];
assert.ok(typeof log1 !== 'undefined', "log doesn't exist");
ensureExportedLogRecordIsCorrect(log1);

ensureExportLogsServiceRequestIsSet(json);

done();
});

fakeRequest.on('data', chunk => {
buff = Buffer.concat([buff, chunk]);
});

const clock = sinon.useFakeTimers();
collectorExporter.export(logs, () => {});
clock.tick(200);
clock.restore();
});

it('should log the successful message', done => {
// Need to stub/spy on the underlying logger as the "diag" instance is global
const spyLoggerError = sinon.stub(diag, 'error');

sinon.stub(http, 'request').callsFake((options: any, cb: any) => {
const mockRes = new MockedResponse(200);
cb(mockRes);
mockRes.send('success');
return fakeRequest as any;
});

collectorExporter.export(logs, result => {
assert.strictEqual(result.code, ExportResultCode.SUCCESS);
assert.strictEqual(spyLoggerError.args.length, 0);
done();
});
});

it('should log the error message', done => {
sinon.stub(http, 'request').callsFake((options: any, cb: any) => {
const mockResError = new MockedResponse(400);
cb(mockResError);
mockResError.send('failed');

return fakeRequest as any;
});

collectorExporter.export(logs, result => {
assert.strictEqual(result.code, ExportResultCode.FAILED);
// @ts-expect-error verify error code
assert.strictEqual(result.error.code, 400);
done();
});
});
});
});

0 comments on commit c670d2c

Please sign in to comment.