Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: zipkin in web #1265 #1393

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion packages/opentelemetry-exporter-zipkin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
"description": "OpenTelemetry Zipkin Exporter allows the user to send collected traces to Zipkin.",
"main": "build/src/index.js",
"types": "build/src/index.d.ts",
"repository": "open-telemetry/opentelemetry-js",
"repository": "open-telemetry/opentelemetry-js", "browser": {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

browser on its own line please.

Why is this a different platform configuration style than our other packages?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed for the new line.

I don't understand the issue with the "different style than the other packages", could you elaborate please ? I took @opentelemetry/exporter-collector as an exemple.

"./src/platform/index.ts": "./src/platform/browser/index.ts",
"./build/src/platform/index.js": "./build/src/platform/browser/index.js"
},
"scripts": {
"test": "nyc ts-mocha -p tsconfig.json 'test/**/*.test.ts'",
"tdd": "npm run test -- --watch-extensions ts --watch",
Expand Down
2 changes: 1 addition & 1 deletion packages/opentelemetry-exporter-zipkin/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 './zipkin';
export * from './platform';
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './zipkin';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing header

please add a newline at the end of the file

168 changes: 168 additions & 0 deletions packages/opentelemetry-exporter-zipkin/src/platform/browser/zipkin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import * as api from '@opentelemetry/api';
import { ExportResult, NoopLogger } from '@opentelemetry/core';
import { SpanExporter, ReadableSpan } from '@opentelemetry/tracing';
import { SERVICE_RESOURCE } from '@opentelemetry/resources';
import * as zipkinTypes from './../../types';
import {
toZipkinSpan,
statusCodeTagName,
statusDescriptionTagName,
} from './../../transform';
import { OT_REQUEST_HEADER } from './../../utils';
/**
* Zipkin Exporter
*/
export class ZipkinExporter implements SpanExporter {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is almost the same as the node version, but is completely copied. Is there no way to use a base class to share functionality?

static readonly DEFAULT_URL = 'http://localhost:9411/api/v2/spans';
private readonly DEFAULT_SERVICE_NAME = 'OpenTelemetry Service';
private readonly _logger: api.Logger;
private readonly _statusCodeTagName: string;
private readonly _statusDescriptionTagName: string;
private readonly _reqOpts: RequestInit;
private readonly _url: string;
private _serviceName?: string;
private _isShutdown: boolean;

constructor(config: zipkinTypes.ExporterConfig = {}) {
this._url = config.url || ZipkinExporter.DEFAULT_URL;
this._logger = config.logger || new NoopLogger();
this._reqOpts = Object.assign(
{
method: 'POST',
headers: {
'Content-Type': 'application/json;charset=UTF-8"',
[OT_REQUEST_HEADER]: 1,
...config.headers,
},
}
);
this._serviceName = config.serviceName;
this._statusCodeTagName = config.statusCodeTagName || statusCodeTagName;
this._statusDescriptionTagName =
config.statusDescriptionTagName || statusDescriptionTagName;
this._isShutdown = false;
}

/**
* Export spans.
*/
export(
spans: ReadableSpan[],
resultCallback: (result: ExportResult) => void
) {
if (typeof this._serviceName !== 'string') {
this._serviceName = String(
spans[0].resource.labels[SERVICE_RESOURCE.NAME] ||
this.DEFAULT_SERVICE_NAME
);
}
this._logger.debug('Zipkin exporter export');
if (this._isShutdown) {
setTimeout(() => resultCallback(ExportResult.FAILED_NOT_RETRYABLE));
return;
}
return this._sendSpans(spans, this._serviceName, resultCallback);
}

/**
* Shutdown exporter. Noop operation in this exporter.
*/
shutdown() {
this._logger.debug('Zipkin exporter shutdown');
if (this._isShutdown) {
return;
}
this._isShutdown = true;
}

/**
* Transform spans and sends to Zipkin service.
*/
private _sendSpans(
spans: ReadableSpan[],
serviceName: string,
done?: (result: ExportResult) => void
) {
const zipkinSpans = spans.map(span =>
toZipkinSpan(
span,
serviceName,
this._statusCodeTagName,
this._statusDescriptionTagName
)
);
return this._send(zipkinSpans, (result: ExportResult) => {
if (done) {
return done(result);
}
});
}

/**
* Send spans to the remote Zipkin service.
*/
private _send(
zipkinSpans: zipkinTypes.Span[],
done: (result: ExportResult) => void
) {
if (zipkinSpans.length === 0) {
this._logger.debug('Zipkin send with empty spans');
return done(ExportResult.SUCCESS);
}
// Issue request to remote service
const payload = JSON.stringify(zipkinSpans);
const requestOptions = Object.assign(
{},
this._reqOpts,
{
body: payload
}
);
const request = new Request(this._url, requestOptions);
let response: Response;
this._logger.debug('Zipkin request payload: %s', payload);
fetch(request)
.then((res: Response) => {
response = res;
return res.text();
})
.then((rawData: string) => {
const statusCode = response.status || 0;
this._logger.debug(
'Zipkin response status code: %d, body: %s',
statusCode,
rawData
);
// Consider 2xx and 3xx as success.
if (statusCode < 400) {
return done(ExportResult.SUCCESS);
// Consider 4xx as failed non-retriable.
} else if (statusCode < 500) {
return done(ExportResult.FAILED_NOT_RETRYABLE);
// Consider 5xx as failed retriable.
} else {
return done(ExportResult.FAILED_RETRYABLE);
}
})
.catch((err: Error) => {
this._logger.error('Zipkin request error', err);
return done(ExportResult.FAILED_RETRYABLE);
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './node/zipkin';
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ import * as https from 'https';
import * as url from 'url';
import { ExportResult, NoopLogger } from '@opentelemetry/core';
import { SpanExporter, ReadableSpan } from '@opentelemetry/tracing';
import * as zipkinTypes from './types';
import { SERVICE_RESOURCE } from '@opentelemetry/resources';
import * as zipkinTypes from './../../types';
import {
toZipkinSpan,
statusCodeTagName,
statusDescriptionTagName,
} from './transform';
import { OT_REQUEST_HEADER } from './utils';
import { SERVICE_RESOURCE } from '@opentelemetry/resources';
} from './../../transform';
import { OT_REQUEST_HEADER } from './../../utils';
/**
* Zipkin Exporter
*/
Expand Down
2 changes: 1 addition & 1 deletion packages/opentelemetry-exporter-zipkin/src/transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
import * as api from '@opentelemetry/api';
import { ReadableSpan } from '@opentelemetry/tracing';
import { hrTimeToMicroseconds } from '@opentelemetry/core';
import * as zipkinTypes from './types';
import { Resource } from '@opentelemetry/resources';
import * as zipkinTypes from './types';

const ZIPKIN_SPAN_KIND_MAPPING = {
[api.SpanKind.CLIENT]: zipkinTypes.SpanKind.CLIENT,
Expand Down