Skip to content

Commit

Permalink
feat(exporters)!: collapse base classes into one (#5031)
Browse files Browse the repository at this point in the history
  • Loading branch information
pichlermarc authored Nov 19, 2024
1 parent 1370810 commit 7e98761
Show file tree
Hide file tree
Showing 78 changed files with 2,075 additions and 1,744 deletions.
9 changes: 9 additions & 0 deletions experimental/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,15 @@ All notable changes to experimental packages in this project will be documented
* GetFunction
* Func
* Err
* feat(otlp-exporter-base)!: collapse base classes into one [#5031](https://github.com/open-telemetry/opentelemetry-js/pull/5031)
* `OTLPExporterNodeBase` has been removed in favor of a platform-agnostic implementation (`OTLPExporterBase`)
* `OTLPExporterBrowserBase` has been removed in favor of a platform-agnostic implementation (`OTLPExporterBase`)
* `ExportServiceError` was intended for internal use and has been dropped from exports
* `validateAndNormalizeHeaders` was intended for internal use and has been dropped from exports
* `OTLPExporterBase` all properties are now private, the constructor now takes an `IOTLPExportDelegate`, the type parameter for config type has been dropped.
* This type is scheduled for removal in a future version of this package, please treat all exporters as `SpanExporter`, `PushMetricExporter` or `LogRecordExporter`, based on their respective type.
* feat(otlp-grpc-exporter-base)!: collapse base classes into one [#5031](https://github.com/open-telemetry/opentelemetry-js/pull/5031)
* `OTLPGRPCExporterNodeBase` has been removed in favor of a platform-agnostic implementation (`OTLPExporterBase` from `@opentelemetry/otlp-exporter-base`)

### :rocket: (Enhancement)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,31 +16,28 @@

import { LogRecordExporter, ReadableLogRecord } from '@opentelemetry/sdk-logs';
import {
convertLegacyOtlpGrpcOptions,
createOtlpGrpcExportDelegate,
OTLPGRPCExporterConfigNode,
OTLPGRPCExporterNodeBase,
} from '@opentelemetry/otlp-grpc-exporter-base';
import {
IExportLogsServiceResponse,
ProtobufLogsSerializer,
} from '@opentelemetry/otlp-transformer';
import { ProtobufLogsSerializer } from '@opentelemetry/otlp-transformer';
import { OTLPExporterBase } from '@opentelemetry/otlp-exporter-base';

/**
* OTLP Logs Exporter for Node
*/
export class OTLPLogExporter
extends OTLPGRPCExporterNodeBase<
ReadableLogRecord,
IExportLogsServiceResponse
>
extends OTLPExporterBase<ReadableLogRecord[]>
implements LogRecordExporter
{
constructor(config: OTLPGRPCExporterConfigNode = {}) {
super(
config,
ProtobufLogsSerializer,
'LogsExportService',
'/opentelemetry.proto.collector.logs.v1.LogsService/Export',
'LOGS'
createOtlpGrpcExportDelegate(
convertLegacyOtlpGrpcOptions(config, 'LOGS'),
ProtobufLogsSerializer,
'LogsExportService',
'/opentelemetry.proto.collector.logs.v1.LogsService/Export'
)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,25 @@ import type {
LogRecordExporter,
} from '@opentelemetry/sdk-logs';
import type { OTLPExporterConfigBase } from '@opentelemetry/otlp-exporter-base';
import type { IExportLogsServiceResponse } from '@opentelemetry/otlp-transformer';
import { OTLPExporterBrowserBase } from '@opentelemetry/otlp-exporter-base';
import { OTLPExporterBase } from '@opentelemetry/otlp-exporter-base';
import { JsonLogsSerializer } from '@opentelemetry/otlp-transformer';
import { createLegacyOtlpBrowserExportDelegate } from '@opentelemetry/otlp-exporter-base/browser-http';

/**
* Collector Logs Exporter for Web
*/
export class OTLPLogExporter
extends OTLPExporterBrowserBase<ReadableLogRecord, IExportLogsServiceResponse>
extends OTLPExporterBase<ReadableLogRecord[]>
implements LogRecordExporter
{
constructor(config: OTLPExporterConfigBase = {}) {
super(
{
...config,
},
JsonLogsSerializer,
{
'Content-Type': 'application/json',
},
'v1/logs'
createLegacyOtlpBrowserExportDelegate(
config,
JsonLogsSerializer,
'v1/logs',
{ 'Content-Type': 'application/json' }
)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,35 +19,30 @@ import type {
LogRecordExporter,
} from '@opentelemetry/sdk-logs';
import type { OTLPExporterNodeConfigBase } from '@opentelemetry/otlp-exporter-base';
import type { IExportLogsServiceResponse } from '@opentelemetry/otlp-transformer';
import { OTLPExporterNodeBase } from '@opentelemetry/otlp-exporter-base';
import { OTLPExporterBase } from '@opentelemetry/otlp-exporter-base';
import { JsonLogsSerializer } from '@opentelemetry/otlp-transformer';

import { VERSION } from '../../version';

const USER_AGENT = {
'User-Agent': `OTel-OTLP-Exporter-JavaScript/${VERSION}`,
};
import {
convertLegacyHttpOptions,
createOtlpHttpExportDelegate,
} from '@opentelemetry/otlp-exporter-base/node-http';

/**
* Collector Logs Exporter for Node
*/
export class OTLPLogExporter
extends OTLPExporterNodeBase<ReadableLogRecord, IExportLogsServiceResponse>
extends OTLPExporterBase<ReadableLogRecord[]>
implements LogRecordExporter
{
constructor(config: OTLPExporterNodeConfigBase = {}) {
super(
{
...config,
},
JsonLogsSerializer,
{
...USER_AGENT,
'Content-Type': 'application/json',
},
'LOGS',
'v1/logs'
createOtlpHttpExportDelegate(
convertLegacyHttpOptions(config, 'LOGS', 'v1/logs', {
'User-Agent': `OTel-OTLP-Exporter-JavaScript/${VERSION}`,
'Content-Type': 'application/json',
}),
JsonLogsSerializer
)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,8 @@ import * as assert from 'assert';
import * as sinon from 'sinon';

import { OTLPLogExporter } from '../../src/platform/browser';
import { OTLPExporterConfigBase } from '@opentelemetry/otlp-exporter-base';
import { ReadableLogRecord } from '@opentelemetry/sdk-logs';
import { mockedReadableLogRecord } from '../logHelper';
import { ExportResultCode } from '@opentelemetry/core';

describe('OTLPLogExporter', () => {
let collectorExporter: OTLPLogExporter;
let collectorExporterConfig: OTLPExporterConfigBase;

afterEach(() => {
sinon.restore();
});
Expand All @@ -36,79 +29,4 @@ describe('OTLPLogExporter', () => {
assert.ok(exporter instanceof OTLPLogExporter);
});
});

describe('export - common', () => {
let spySend: any;
beforeEach(() => {
spySend = sinon.stub(OTLPLogExporter.prototype, 'send');
collectorExporter = new OTLPLogExporter(collectorExporterConfig);
});

it('should export spans as otlpTypes.Spans', done => {
const logs: ReadableLogRecord[] = [];
logs.push(Object.assign({}, mockedReadableLogRecord));

collectorExporter.export(logs, () => {});
setTimeout(() => {
const log = spySend.args[0][0][0] as ReadableLogRecord;
assert.deepStrictEqual(logs[0], log);
done();
});
assert.strictEqual(spySend.callCount, 1);
});

describe('when exporter is shutdown', () => {
it(
'should not export anything but return callback with code' +
' "FailedNotRetryable"',
async () => {
const spans: ReadableLogRecord[] = [];
spans.push(Object.assign({}, mockedReadableLogRecord));
await collectorExporter.shutdown();
spySend.resetHistory();

const callbackSpy = sinon.spy();
collectorExporter.export(spans, callbackSpy);
const returnCode = callbackSpy.args[0][0];

assert.strictEqual(
returnCode.code,
ExportResultCode.FAILED,
'return value is wrong'
);
assert.strictEqual(spySend.callCount, 0, 'should not call send');
}
);
});
describe('when an error occurs', () => {
it('should return failed export result', done => {
const spans: ReadableLogRecord[] = [];
spans.push(Object.assign({}, mockedReadableLogRecord));
spySend.throws({
code: 100,
details: 'Test error',
metadata: {},
message: 'Non-retryable',
stack: 'Stack',
});
const callbackSpy = sinon.spy();
collectorExporter.export(spans, callbackSpy);
setTimeout(() => {
const returnCode = callbackSpy.args[0][0];
assert.strictEqual(
returnCode.code,
ExportResultCode.FAILED,
'return value is wrong'
);
assert.strictEqual(
returnCode.error.message,
'Non-retryable',
'return error message is wrong'
);
assert.strictEqual(spySend.callCount, 1, 'should call send');
done();
});
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ import {
import { PassThrough, Stream } from 'stream';
import { IExportLogsServiceRequest } from '@opentelemetry/otlp-transformer';
import { ExportResultCode } from '@opentelemetry/core';
import { VERSION } from '../../src/version';

let fakeRequest: PassThrough;

Expand All @@ -57,7 +56,6 @@ class MockedResponse extends Stream {
}

describe('OTLPLogExporter', () => {
let envSource: Record<string, any>;
let collectorExporter: OTLPLogExporter;
let collectorExporterConfig: OTLPExporterNodeConfigBase;
let logs: ReadableLogRecord[];
Expand All @@ -70,55 +68,11 @@ describe('OTLPLogExporter', () => {
sinon.restore();
});

if (global.process?.versions?.node === undefined) {
envSource = globalThis as unknown as Record<string, any>;
} else {
envSource = process.env as Record<string, any>;
}

describe('constructor', () => {
it('should create an instance', () => {
const exporter = new OTLPLogExporter();
assert.ok(exporter instanceof OTLPLogExporter);
});

it('should include user-agent header by default', () => {
const exporter = new OTLPLogExporter();
assert.strictEqual(
exporter['_transport']['_transport']['_parameters']['headers'][
'User-Agent'
],
`OTel-OTLP-Exporter-JavaScript/${VERSION}`
);
});

it('should use headers defined via env', () => {
envSource.OTEL_EXPORTER_OTLP_LOGS_HEADERS = 'foo=bar';
const exporter = new OTLPLogExporter();
assert.strictEqual(
exporter['_transport']['_transport']['_parameters']['headers']['foo'],
'bar'
);
delete envSource.OTEL_EXPORTER_OTLP_LOGS_HEADERS;
});

it('should override headers defined via env with headers defined in constructor', () => {
envSource.OTEL_EXPORTER_OTLP_HEADERS = 'foo=bar,bar=foo';
const exporter = new OTLPLogExporter({
headers: {
foo: 'constructor',
},
});
assert.strictEqual(
exporter['_transport']['_transport']['_parameters']['headers']['foo'],
'constructor'
);
assert.strictEqual(
exporter['_transport']['_transport']['_parameters']['headers']['bar'],
'foo'
);
envSource.OTEL_EXPORTER_OTLP_HEADERS = '';
});
});

describe('export', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,28 +16,28 @@

import {
OTLPExporterConfigBase,
OTLPExporterBrowserBase,
OTLPExporterBase,
} from '@opentelemetry/otlp-exporter-base';
import {
IExportLogsServiceResponse,
ProtobufLogsSerializer,
} from '@opentelemetry/otlp-transformer';
import { ProtobufLogsSerializer } from '@opentelemetry/otlp-transformer';

import { ReadableLogRecord, LogRecordExporter } from '@opentelemetry/sdk-logs';
import { createLegacyOtlpBrowserExportDelegate } from '@opentelemetry/otlp-exporter-base/browser-http';

/**
* Collector Trace Exporter for Web
*/
export class OTLPLogExporter
extends OTLPExporterBrowserBase<ReadableLogRecord, IExportLogsServiceResponse>
extends OTLPExporterBase<ReadableLogRecord[]>
implements LogRecordExporter
{
constructor(config: OTLPExporterConfigBase = {}) {
super(
config,
ProtobufLogsSerializer,
{ 'Content-Type': 'application/x-protobuf' },
'v1/logs'
createLegacyOtlpBrowserExportDelegate(
config,
ProtobufLogsSerializer,
'v1/logs',
{ 'Content-Type': 'application/x-protobuf' }
)
);
}
}
Loading

0 comments on commit 7e98761

Please sign in to comment.