Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin' into logs-exporter-otlp-proto
Browse files Browse the repository at this point in the history
  • Loading branch information
Abinet18 committed May 26, 2023
2 parents 922f2f3 + c6635fa commit 952f263
Show file tree
Hide file tree
Showing 48 changed files with 265 additions and 82 deletions.
12 changes: 12 additions & 0 deletions .github/workflows/label-releases.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
on:
pull_request_target:
branches:
- main

jobs:
label-release:
if: ${{ startsWith(github.event.pull_request.title, 'release:') }}
runs-on: ubuntu-latest
steps:
- run: echo this is a release PR
- run: gh pr edit ${{ github.event.pull_request.number }} --add-label release
2 changes: 1 addition & 1 deletion .github/workflows/peer-api.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
peer-api-check:
runs-on: ubuntu-latest
container:
image: node:18
image: node:20
steps:
- name: Checkout
uses: actions/checkout@v3
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ For experimental package changes, see the [experimental CHANGELOG](experimental/

### :rocket: (Enhancement)

* feat(SpanExpoter): Add optional forceFlush to SpanExporter interface [#3753](https://github.com/open-telemetry/opentelemetry-js/pull/3753/) @sgracias1 @JacksonWeber

### :bug: (Bug Fix)

### :books: (Refine Doc)
Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -188,13 +188,16 @@ We have a weekly SIG meeting! See the [community page](https://github.com/open-t

- [Gerhard Stöbich](https://github.com/Flarna), Dynatrace
- [Haddas Bronfman](https://github.com/haddasbronfman), Cisco
- [Hector Hernandez](https://github.com/hectorhdzg), Microsoft
- [Jamie Danielson](https://github.com/JamieDanielson), Honeycomb
- [John Bley](https://github.com/johnbley), Splunk
- [Mark Wolff](https://github.com/markwolff), Microsoft
- [Martin Kuba](https://github.com/martinkuba), Lightstep
- [Matthew Wear](https://github.com/mwear), LightStep
- [Naseem K. Ullah](https://github.com/naseemkullah), Transit
- [Neville Wylie](https://github.com/MSNev), Microsoft
- [Olivier Albertini](https://github.com/OlivierAlbertini), Ville de Montréal
- [Purvi Kanal](https://github.com/pkanal), Honeycomb
- [Svetlana Brennan](https://github.com/svetlanabrennan), New Relic

*Find more about the approver role in [community repository](https://github.com/open-telemetry/community/blob/main/community-membership.md#approver).*
Expand Down
10 changes: 6 additions & 4 deletions experimental/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,21 @@ All notable changes to experimental packages in this project will be documented

## Unreleased

### :rocket: (Enhancement)

* feat(otlp-trace-exporters): Add User-Agent header to OTLP trace exporters. [#3790](https://github.com/open-telemetry/opentelemetry-js/pull/3790) @JamieDanielson

### :boom: Breaking Change

* fix(exporter-logs-otlp-grpc): change OTLPLogsExporter to OTLPLogExporter [#3819](https://github.com/open-telemetry/opentelemetry-js/pull/3819) @fuaiyi

### :rocket: (Enhancement)

* feat(exporter-logs-otlp-proto): protobuf exporter for logs. [#3779](https://github.com/open-telemetry/opentelemetry-js/pull/3779) @Abinet18
* feat(instrumentation): add ESM support for instrumentation. [#3698](https://github.com/open-telemetry/opentelemetry-js/pull/3698) @JamieDanielson, @pkanal, @vmarchaud, @lizthegrey, @bengl
* feat(otlp-trace-exporters): Add User-Agent header to OTLP trace exporters. [#3790](https://github.com/open-telemetry/opentelemetry-js/pull/3790) @JamieDanielson
* feat(otlp-metric-exporters): Add User-Agent header to OTLP metric exporters. [#3806](https://github.com/open-telemetry/opentelemetry-js/pull/3806) @JamieDanielson

### :bug: (Bug Fix)

* fix(sdk-node): use resource interface instead of concrete class [#3803](https://github.com/open-telemetry/opentelemetry-js/pull/3803) @blumamir
* fix(sdk-logs): remove includeTraceContext configuration and use LogRecord context when available [#3817](https://github.com/open-telemetry/opentelemetry-js/pull/3817) @hectorhdzg

### :books: (Refine Doc)

Expand All @@ -38,6 +39,7 @@ All notable changes to experimental packages in this project will be documented
* feat(exporter-logs-otlp-grpc): otlp-grpc exporter for logs. [#3712](https://github.com/open-telemetry/opentelemetry-js/pull/3712/) @llc1123
* feat(otlp-grpc-exporter-base): use statically generated protobuf code [#3705](https://github.com/open-telemetry/opentelemetry-js/pull/3705) @pichlermarc
* refactor(otlp-transformer): refine metric transformers. [#3770](https://github.com/open-telemetry/opentelemetry-js/pull/3770/) @llc1123
* feat(api-logs): add `ObservedTimestamp` to `LogRecord`. [#3787](https://github.com/open-telemetry/opentelemetry-js/pull/3787/) @llc1123

### :bug: (Bug Fix)

Expand Down
5 changes: 5 additions & 0 deletions experimental/packages/api-logs/src/types/LogRecord.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ export interface LogRecord {
*/
timestamp?: number;

/**
* Time when the event was observed by the collection system.
*/
observedTimestamp?: number;

/**
* Numerical value of the severity.
*/
Expand Down
6 changes: 3 additions & 3 deletions experimental/packages/exporter-logs-otlp-grpc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,22 @@ To see documentation and sample code for the metric exporter, see the [exporter-

## Logs in Node - GRPC

The OTLPLogsExporter in Node expects the URL to only be the hostname. It will not work with `/v1/logs`. All
The OTLPLogExporter in Node expects the URL to only be the hostname. It will not work with `/v1/logs`. All
options that work with trace also work with logs.

```js
import {
LoggerProvider,
BatchLogRecordProcessor,
} from '@opentelemetry/sdk-logs';
import { OTLPLogsExporter } from '@opentelemetry/exporter-logs-otlp-grpc';
import { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-grpc';

const collectorOptions = {
// url is optional and can be omitted - default is http://localhost:4317
url: 'http://<collector-hostname>:<port>',
};

const loggerExporter = new OTLPLogsExporter(collectorOptions);
const loggerExporter = new OTLPLogExporter(collectorOptions);
const loggerProvider = new LoggerProvider();

loggerProvider.addLogRecordProcessor(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import {
/**
* OTLP Logs Exporter for Node
*/
export class OTLPLogsExporter
export class OTLPLogExporter
extends OTLPGRPCExporterNodeBase<ReadableLogRecord, IExportLogsServiceRequest>
implements LogRecordExporter
{
Expand Down
2 changes: 1 addition & 1 deletion experimental/packages/exporter-logs-otlp-grpc/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@
* limitations under the License.
*/

export * from './OTLPLogsExporter';
export * from './OTLPLogExporter';
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import * as fs from 'fs';
import * as grpc from '@grpc/grpc-js';
import * as path from 'path';
import * as sinon from 'sinon';
import { OTLPLogsExporter } from '../src';
import { OTLPLogExporter } from '../src';

import {
ensureExportedLogRecordIsCorrect,
Expand Down Expand Up @@ -55,10 +55,10 @@ const metadata = new grpc.Metadata();
metadata.set('k', 'v');

const testCollectorExporter = (params: TestParams) =>
describe(`OTLPLogsExporter - node ${
params.useTLS ? 'with' : 'without'
} TLS, ${params.metadata ? 'with' : 'without'} metadata`, () => {
let collectorExporter: OTLPLogsExporter;
describe(`OTLPLogExporter - node ${params.useTLS ? 'with' : 'without'} TLS, ${
params.metadata ? 'with' : 'without'
} metadata`, () => {
let collectorExporter: OTLPLogExporter;
let server: grpc.Server;
let exportedData: IResourceLogs | undefined;
let reqMetadata: grpc.Metadata | undefined;
Expand Down Expand Up @@ -122,7 +122,7 @@ const testCollectorExporter = (params: TestParams) =>
fs.readFileSync('./test/certs/client.crt')
)
: grpc.credentials.createInsecure();
collectorExporter = new OTLPLogsExporter({
collectorExporter = new OTLPLogExporter({
url: 'https://' + address,
credentials,
metadata: params.metadata,
Expand All @@ -140,7 +140,7 @@ const testCollectorExporter = (params: TestParams) =>
it('should warn about headers when using grpc', () => {
// Need to stub/spy on the underlying logger as the 'diag' instance is global
const spyLoggerWarn = sinon.stub(diag, 'warn');
collectorExporter = new OTLPLogsExporter({
collectorExporter = new OTLPLogExporter({
url: `http://${address}`,
headers: {
foo: 'bar',
Expand All @@ -151,7 +151,7 @@ const testCollectorExporter = (params: TestParams) =>
});
it('should warn about path in url', () => {
const spyLoggerWarn = sinon.stub(diag, 'warn');
collectorExporter = new OTLPLogsExporter({
collectorExporter = new OTLPLogExporter({
url: `http://${address}/v1/logs`,
});
const args = spyLoggerWarn.args[0];
Expand Down Expand Up @@ -198,7 +198,7 @@ const testCollectorExporter = (params: TestParams) =>
)
: grpc.credentials.createInsecure();

const collectorExporterWithTimeout = new OTLPLogsExporter({
const collectorExporterWithTimeout = new OTLPLogExporter({
url: 'grpcs://' + address,
credentials,
metadata: params.metadata,
Expand Down Expand Up @@ -229,7 +229,7 @@ const testCollectorExporter = (params: TestParams) =>
fs.readFileSync('./test/certs/client.crt')
)
: grpc.credentials.createInsecure();
collectorExporter = new OTLPLogsExporter({
collectorExporter = new OTLPLogExporter({
url: 'https://' + address,
credentials,
metadata: params.metadata,
Expand Down Expand Up @@ -272,7 +272,7 @@ const testCollectorExporter = (params: TestParams) =>
: grpc.credentials.createInsecure();

envSource.OTEL_EXPORTER_OTLP_COMPRESSION = 'gzip';
collectorExporter = new OTLPLogsExporter({
collectorExporter = new OTLPLogExporter({
url: 'https://' + address,
credentials,
metadata: params.metadata,
Expand All @@ -286,17 +286,17 @@ const testCollectorExporter = (params: TestParams) =>
});
});

describe('OTLPLogsExporter - node (getDefaultUrl)', () => {
describe('OTLPLogExporter - node (getDefaultUrl)', () => {
it('should default to localhost', done => {
const collectorExporter = new OTLPLogsExporter({});
const collectorExporter = new OTLPLogExporter({});
setTimeout(() => {
assert.strictEqual(collectorExporter['url'], 'localhost:4317');
done();
});
});
it('should keep the URL if included', done => {
const url = 'http://foo.bar.com';
const collectorExporter = new OTLPLogsExporter({ url });
const collectorExporter = new OTLPLogExporter({ url });
setTimeout(() => {
assert.strictEqual(collectorExporter['url'], 'foo.bar.com');
done();
Expand All @@ -308,21 +308,21 @@ describe('when configuring via environment', () => {
const envSource = process.env;
it('should use url defined in env', () => {
envSource.OTEL_EXPORTER_OTLP_ENDPOINT = 'http://foo.bar';
const collectorExporter = new OTLPLogsExporter();
const collectorExporter = new OTLPLogExporter();
assert.strictEqual(collectorExporter.url, 'foo.bar');
envSource.OTEL_EXPORTER_OTLP_ENDPOINT = '';
});
it('should override global exporter url with signal url defined in env', () => {
envSource.OTEL_EXPORTER_OTLP_ENDPOINT = 'http://foo.bar';
envSource.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT = 'http://foo.logs';
const collectorExporter = new OTLPLogsExporter();
const collectorExporter = new OTLPLogExporter();
assert.strictEqual(collectorExporter.url, 'foo.logs');
envSource.OTEL_EXPORTER_OTLP_ENDPOINT = '';
envSource.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT = '';
});
it('should use headers defined via env', () => {
envSource.OTEL_EXPORTER_OTLP_HEADERS = 'foo=bar';
const collectorExporter = new OTLPLogsExporter();
const collectorExporter = new OTLPLogExporter();
assert.deepStrictEqual(collectorExporter.metadata?.get('foo'), ['bar']);
envSource.OTEL_EXPORTER_OTLP_HEADERS = '';
});
Expand All @@ -332,7 +332,7 @@ describe('when configuring via environment', () => {
metadata.set('goo', 'lol');
envSource.OTEL_EXPORTER_OTLP_HEADERS = 'foo=jar,bar=foo';
envSource.OTEL_EXPORTER_OTLP_LOGS_HEADERS = 'foo=boo';
const collectorExporter = new OTLPLogsExporter({ metadata });
const collectorExporter = new OTLPLogExporter({ metadata });
assert.deepStrictEqual(collectorExporter.metadata?.get('foo'), ['boo']);
assert.deepStrictEqual(collectorExporter.metadata?.get('bar'), ['foo']);
assert.deepStrictEqual(collectorExporter.metadata?.get('goo'), ['lol']);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export const mockedReadableLogRecord: ReadableLogRecord = {
schemaUrl: 'http://url.to.schema',
},
hrTime: [1680253513, 123241635] as HrTime,
hrTimeObserved: [1683526948, 965142784] as HrTime,
attributes: {
'some-attribute': 'some attribute value',
},
Expand Down Expand Up @@ -92,7 +93,7 @@ export function ensureExportedLogRecordIsCorrect(logRecord: ILogRecord) {
);
assert.strictEqual(
logRecord.observedTimeUnixNano,
'1680253513123241728',
'1683526948965142784',
'observedTimeUnixNano is wrong'
);
assert.strictEqual(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,25 @@ import {
createExportMetricsServiceRequest,
IExportMetricsServiceRequest,
} from '@opentelemetry/otlp-transformer';
import { VERSION } from './version';

const USER_AGENT = {
'User-Agent': `OTel-OTLP-Exporter-JavaScript/${VERSION}`,
};

class OTLPMetricExporterProxy extends OTLPGRPCExporterNodeBase<
ResourceMetrics,
IExportMetricsServiceRequest
> {
constructor(config?: OTLPGRPCExporterConfigNode & OTLPMetricExporterOptions) {
super(config);
const headers = baggageUtils.parseKeyPairsIntoRecord(
getEnv().OTEL_EXPORTER_OTLP_METRICS_HEADERS
);
const headers = {
...USER_AGENT,
...baggageUtils.parseKeyPairsIntoRecord(
getEnv().OTEL_EXPORTER_OTLP_METRICS_HEADERS
),
};

this.metadata ||= new Metadata();
for (const [k, v] of Object.entries(headers)) {
this.metadata.set(k, v);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import {
IExportMetricsServiceRequest,
IResourceMetrics,
} from '@opentelemetry/otlp-transformer';
import { VERSION } from '../src/version';

const metricsServiceProtoPath =
'opentelemetry/proto/collector/metrics/v1/metrics_service.proto';
Expand Down Expand Up @@ -314,6 +315,13 @@ describe('when configuring via environment', () => {
);
envSource.OTEL_EXPORTER_OTLP_HEADERS = '';
});
it('should include user agent in header', () => {
const collectorExporter = new OTLPMetricExporter();
assert.deepStrictEqual(
collectorExporter._otlpExporter.metadata?.get('User-Agent'),
[`OTel-OTLP-Exporter-JavaScript/${VERSION}`]
);
});
it('should override global headers config with signal headers defined via env', () => {
const metadata = new grpc.Metadata();
metadata.set('foo', 'bar');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,27 @@ import {
createExportMetricsServiceRequest,
IExportMetricsServiceRequest,
} from '@opentelemetry/otlp-transformer';
import { VERSION } from '../../version';

const DEFAULT_COLLECTOR_RESOURCE_PATH = 'v1/metrics';
const DEFAULT_COLLECTOR_URL = `http://localhost:4318/${DEFAULT_COLLECTOR_RESOURCE_PATH}`;
const USER_AGENT = {
'User-Agent': `OTel-OTLP-Exporter-JavaScript/${VERSION}`,
};

class OTLPExporterNodeProxy extends OTLPExporterNodeBase<
ResourceMetrics,
IExportMetricsServiceRequest
> {
constructor(config?: OTLPExporterNodeConfigBase & OTLPMetricExporterOptions) {
super(config);
this.headers = Object.assign(
this.headers,
baggageUtils.parseKeyPairsIntoRecord(
this.headers = {
...this.headers,
...USER_AGENT,
...baggageUtils.parseKeyPairsIntoRecord(
getEnv().OTEL_EXPORTER_OTLP_METRICS_HEADERS
)
);
),
};
}

convert(metrics: ResourceMetrics[]): IExportMetricsServiceRequest {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import {
OTLPExporterNodeConfigBase,
} from '@opentelemetry/otlp-exporter-base';
import { IExportMetricsServiceRequest } from '@opentelemetry/otlp-transformer';
import { VERSION } from '../../src/version';

let fakeRequest: PassThrough;

Expand Down Expand Up @@ -188,6 +189,13 @@ describe('OTLPMetricExporter - node with json over http', () => {
assert.strictEqual(collectorExporter._otlpExporter.headers.foo, 'bar');
envSource.OTEL_EXPORTER_OTLP_HEADERS = '';
});
it('should include user agent in header', () => {
const collectorExporter = new OTLPMetricExporter();
assert.strictEqual(
collectorExporter._otlpExporter.headers['User-Agent'],
`OTel-OTLP-Exporter-JavaScript/${VERSION}`
);
});
it('should override global headers config with signal headers defined via env', () => {
envSource.OTEL_EXPORTER_OTLP_HEADERS = 'foo=bar,bar=foo';
envSource.OTEL_EXPORTER_OTLP_METRICS_HEADERS = 'foo=boo';
Expand Down
Loading

0 comments on commit 952f263

Please sign in to comment.