Skip to content

Commit

Permalink
Change telemetry provider (#12)
Browse files Browse the repository at this point in the history
  • Loading branch information
qetza committed Mar 18, 2024
1 parent f891633 commit e08bbfc
Show file tree
Hide file tree
Showing 7 changed files with 89 additions and 111 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# Changelog
## v1.1.2
- Change telemetry provider.

## v1.1.1
- Fix variable case-sensitivity ([#7](https://github.com/qetza/replacetokens-action/issues/7)).
Expand Down
85 changes: 34 additions & 51 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -63417,7 +63417,7 @@ async function run() {
const telemetry = new telemetry_1.TelemetryClient(process.env['GITHUB_REPOSITORY'], process.env['GITHUB_WORKFLOW'], process.env['GITHUB_SERVER_URL'] === 'https://github.com' ? 'cloud' : 'server', process.env['RUNNER_OS']);
if (!core.getBooleanInput('no-telemetry') &&
!['true', '1'].includes(process.env['REPLACETOKENS_TELEMETRY_OPTOUT'] || '')) {
telemetry.useApplicationInsightsExporter({ log: core.debug });
telemetry.enableTelemetry({ log: core.debug });
}
const telemetryEvent = telemetry.startSpan('run');
try {
Expand Down Expand Up @@ -63803,11 +63803,11 @@ const sdk_trace_base_1 = __nccwpck_require__(29253);
const crypto = __importStar(__nccwpck_require__(6113));
const axios_1 = __importDefault(__nccwpck_require__(88757));
const application = 'replacetokens-action';
const version = '1.1.0';
const url = 'https://westeurope-5.in.applicationinsights.azure.com/v2/track';
const key = 'e18a8793-c093-46f9-8c3b-433c9553eb7f';
const version = '1.1.2';
const endpoint = 'https://insights-collector.eu01.nr-data.net/v1/accounts/4392697/events';
const key = 'eu01xxc28887c2d47d9719ed24a74df5FFFFNRAL';
const timeout = 3000;
class ApplicationInsightsExporter {
class NewRelicExporter {
_log;
_isShutdown = false;
constructor(log) {
Expand All @@ -63821,9 +63821,7 @@ class ApplicationInsightsExporter {
}
if (spans.length > 0) {
const events = spans.map(s => this._spanToEvent(s));
this._log(`telemetry: ${JSON.stringify(events.map(e => {
return { ...e, name: '*****', iKey: '*****' };
}))}`);
this._log(`telemetry: ${JSON.stringify(events)}`);
resultCallback(await this._send(events));
}
resultCallback({ code: core_1.ExportResultCode.SUCCESS });
Expand All @@ -63834,48 +63832,33 @@ class ApplicationInsightsExporter {
}
_spanToEvent(span) {
return {
name: `Microsoft.ApplicationInsights.Dev.${key}.Event`,
time: new Date((0, core_1.hrTimeToNanoseconds)(span.startTime) / 1000000).toISOString(),
iKey: key,
tags: {
'ai.application.ver': version,
'ai.cloud.role': span.attributes['host'],
'ai.internal.sdkVersion': 'replacetokens:2.0.0',
'ai.operation.id': span.spanContext().traceId,
'ai.operation.name': application,
'ai.user.accountId': span.attributes['account'],
'ai.user.authUserId': span.attributes['workflow']
},
data: {
baseType: 'EventData',
baseData: {
ver: '2',
name: 'tokens.replaced',
properties: {
...span.attributes,
host: undefined,
account: undefined,
workflow: undefined,
result: (() => {
switch (span.status.code) {
case api_1.SpanStatusCode.ERROR:
return 'failed';
case api_1.SpanStatusCode.OK:
return 'success';
default:
return '';
}
})(),
duration: (0, core_1.hrTimeToMilliseconds)(span.duration)
}
eventType: 'TokensReplaced',
application: application,
version: version,
...span.attributes,
result: (() => {
switch (span.status.code) {
case api_1.SpanStatusCode.ERROR:
return 'failed';
case api_1.SpanStatusCode.OK:
return 'success';
default:
return '';
}
}
})(),
duration: (0, core_1.hrTimeToMilliseconds)(span.duration)
};
}
async _send(data) {
try {
const options = { timeout: timeout };
await axios_1.default.post(url, data, options);
const options = {
headers: {
'Api-Key': key,
'Content-Type': 'application/json'
},
timeout: timeout
};
await axios_1.default.post(endpoint, data, options);
return { code: core_1.ExportResultCode.SUCCESS };
}
catch (e) {
Expand All @@ -63890,7 +63873,7 @@ class TelemetryClient {
_workflow;
_host;
_os;
_isApplicationInsightsExporterRegistered = false;
_isEnabled = false;
constructor(account, workflow, host, os) {
this._provider = new sdk_trace_base_1.BasicTracerProvider({ forceFlushTimeoutMillis: timeout });
this._tracer = this._provider.getTracer(application, version);
Expand All @@ -63907,14 +63890,14 @@ class TelemetryClient {
}
startSpan(name) {
return this._tracer.startSpan(name, {
attributes: { account: this._account, workflow: this._workflow, host: this._host, os: this._os }
attributes: { account: this._account, pipeline: this._workflow, host: this._host, os: this._os }
});
}
useApplicationInsightsExporter(options) {
if (this._isApplicationInsightsExporterRegistered)
enableTelemetry(options) {
if (this._isEnabled)
return;
this._provider.addSpanProcessor(new sdk_trace_base_1.SimpleSpanProcessor(new ApplicationInsightsExporter(options.log)));
this._isApplicationInsightsExporterRegistered = true;
this._provider.addSpanProcessor(new sdk_trace_base_1.SimpleSpanProcessor(new NewRelicExporter(options.log)));
this._isEnabled = true;
}
}
exports.TelemetryClient = TelemetryClient;
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "replacetokens-action",
"version": "1.1.1",
"version": "1.1.2",
"description": "An action to replace tokens with variables and/or secrets.",
"private": true,
"author": "Guillaume ROUCHON",
Expand Down Expand Up @@ -30,7 +30,7 @@
"build": "npm run format && npm run package",
"format": "prettier --write **/*.ts",
"format:check": "prettier --check **/*.ts",
"package": "ncc build src/index.ts --license licenses.txt",
"package": "ncc build src/index.ts --license licenses.txt && node scripts/package.js",
"test": "jest"
},
"dependencies": {
Expand Down
14 changes: 14 additions & 0 deletions scripts/package.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
var fs = require('fs');
var path = require('path');

console.log();
console.log('update metadata');

var package = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'package.json'), 'utf-8'));

var p = path.join(__dirname, '..', 'dist', 'index.js');
var index = fs.readFileSync(p, 'utf-8');
index = index.replace(/const\s+version\s*=\s*'[^']*'\s*;/, `const version = '${package.version}';`);
console.log(`> version: ${package.version}`)

fs.writeFileSync(p, index);
2 changes: 1 addition & 1 deletion src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export async function run(): Promise<void> {
!core.getBooleanInput('no-telemetry') &&
!['true', '1'].includes(process.env['REPLACETOKENS_TELEMETRY_OPTOUT'] || '')
) {
telemetry.useApplicationInsightsExporter({ log: core.debug });
telemetry.enableTelemetry({ log: core.debug });
}

const telemetryEvent = telemetry.startSpan('run');
Expand Down
89 changes: 34 additions & 55 deletions src/telemetry.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { ExportResult, ExportResultCode, hrTimeToMilliseconds, hrTimeToNanoseconds } from '@opentelemetry/core';
import { ExportResult, ExportResultCode, hrTimeToMilliseconds } from '@opentelemetry/core';
import { SpanStatusCode, Tracer, Span } from '@opentelemetry/api';
import { BasicTracerProvider, SimpleSpanProcessor, SpanExporter, ReadableSpan } from '@opentelemetry/sdk-trace-base';
import * as crypto from 'crypto';
import axios from 'axios';

const application = 'replacetokens-action';
const version = '1.1.0';
const url = 'https://westeurope-5.in.applicationinsights.azure.com/v2/track';
const key = 'e18a8793-c093-46f9-8c3b-433c9553eb7f';
const version = '1.0.0';
const endpoint = 'https://insights-collector.eu01.nr-data.net/v1/accounts/4392697/events';
const key = 'eu01xxc28887c2d47d9719ed24a74df5FFFFNRAL';
const timeout = 3000;

class ApplicationInsightsExporter implements SpanExporter {
class NewRelicExporter implements SpanExporter {
private readonly _log: (message: string) => void;
private _isShutdown = false;

Expand All @@ -28,13 +28,7 @@ class ApplicationInsightsExporter implements SpanExporter {

if (spans.length > 0) {
const events = spans.map(s => this._spanToEvent(s));
this._log(
`telemetry: ${JSON.stringify(
events.map(e => {
return { ...e, name: '*****', iKey: '*****' };
})
)}`
);
this._log(`telemetry: ${JSON.stringify(events)}`);

resultCallback(await this._send(events));
}
Expand All @@ -50,49 +44,34 @@ class ApplicationInsightsExporter implements SpanExporter {

private _spanToEvent(span: ReadableSpan): { [key: string]: any } {
return {
name: `Microsoft.ApplicationInsights.Dev.${key}.Event`,
time: new Date(hrTimeToNanoseconds(span.startTime) / 1000000).toISOString(),
iKey: key,
tags: {
'ai.application.ver': version,
'ai.cloud.role': span.attributes['host'],
'ai.internal.sdkVersion': 'replacetokens:2.0.0',
'ai.operation.id': span.spanContext().traceId,
'ai.operation.name': application,
'ai.user.accountId': span.attributes['account'],
'ai.user.authUserId': span.attributes['workflow']
},
data: {
baseType: 'EventData',
baseData: {
ver: '2',
name: 'tokens.replaced',
properties: {
...span.attributes,
host: undefined,
account: undefined,
workflow: undefined,
result: (() => {
switch (span.status.code) {
case SpanStatusCode.ERROR:
return 'failed';
case SpanStatusCode.OK:
return 'success';
default:
return '';
}
})(),
duration: hrTimeToMilliseconds(span.duration)
}
eventType: 'TokensReplaced',
application: application,
version: version,
...span.attributes,
result: (() => {
switch (span.status.code) {
case SpanStatusCode.ERROR:
return 'failed';
case SpanStatusCode.OK:
return 'success';
default:
return '';
}
}
})(),
duration: hrTimeToMilliseconds(span.duration)
};
}

private async _send(data: any[]): Promise<ExportResult> {
try {
const options: axios.AxiosRequestConfig<any[]> = { timeout: timeout };
await axios.post(url, data, options);
const options: axios.AxiosRequestConfig<any[]> = {
headers: {
'Api-Key': key,
'Content-Type': 'application/json'
},
timeout: timeout
};
await axios.post(endpoint, data, options);

return { code: ExportResultCode.SUCCESS };
} catch (e) {
Expand All @@ -109,7 +88,7 @@ export class TelemetryClient {
private readonly _host: string;
private readonly _os: string;

private _isApplicationInsightsExporterRegistered = false;
private _isEnabled = false;

constructor(account?: string, workflow?: string, host?: string, os?: string) {
this._provider = new BasicTracerProvider({ forceFlushTimeoutMillis: timeout });
Expand All @@ -128,14 +107,14 @@ export class TelemetryClient {

startSpan(name: string): Span {
return this._tracer.startSpan(name, {
attributes: { account: this._account, workflow: this._workflow, host: this._host, os: this._os }
attributes: { account: this._account, pipeline: this._workflow, host: this._host, os: this._os }
});
}

useApplicationInsightsExporter(options: { log: (message: string) => void }) {
if (this._isApplicationInsightsExporterRegistered) return;
enableTelemetry(options: { log: (message: string) => void }) {
if (this._isEnabled) return;

this._provider.addSpanProcessor(new SimpleSpanProcessor(new ApplicationInsightsExporter(options.log)));
this._isApplicationInsightsExporterRegistered = true;
this._provider.addSpanProcessor(new SimpleSpanProcessor(new NewRelicExporter(options.log)));
this._isEnabled = true;
}
}
4 changes: 2 additions & 2 deletions tests/run.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ describe('run', () => {

expect(debugSpy).toHaveBeenCalledWith(
expect.stringMatching(
/\[\{"name":"\*+","time":"[^"]+","iKey":"\*+","tags":\{"ai\.application\.ver":"1\.\d+\.\d+","ai\.cloud\.role":"server","ai\.internal\.sdkVersion":"replacetokens:2\.0\.0","ai\.operation\.id":"[^"]+","ai\.operation\.name":"replacetokens-action","ai\.user\.accountId":"c054bf9f6127dc352a184a29403ac9114f6c2a8e27cb467197cdfc1c3df119e4","ai\.user\.authUserId":"59830ebc3a4184110566bf1a290d08473dfdcbd492ce498b14cd1a5e2fa2e441"},"data":\{"baseType":"EventData","baseData":\{"ver":"2","name":"tokens\.replaced","properties":\{"os":"Windows","sources":3,"add-bom":false,"chars-to-escape":"","encoding":"auto","escape":"auto","escape-char":"","if-no-files-found":"ignore","log-level":"info","missing-var-action":"none","missing-var-default":"","missing-var-log":"warn","recusrive":false,"separator":"\.","token-pattern":"default","token-prefix":"","token-suffix":"","transforms":false,"transforms-prefix":"\(","transforms-suffix":"\)","variable-files":0,"variable-envs":0,"inline-variables":0,"output-defaults":1,"output-files":2,"output-replaced":3,"output-tokens":4,"output-transforms":5,"result":"success","duration":\d+(?:\.\d+)?}}}}]/
/\[\{"eventType":"TokensReplaced","application":"replacetokens-action","version":"1\.\d+\.\d+","account":"c054bf9f6127dc352a184a29403ac9114f6c2a8e27cb467197cdfc1c3df119e4","pipeline":"59830ebc3a4184110566bf1a290d08473dfdcbd492ce498b14cd1a5e2fa2e441","host":"server","os":"Windows","sources":3,"add-bom":false,"chars-to-escape":"","encoding":"auto","escape":"auto","escape-char":"","if-no-files-found":"ignore","log-level":"info","missing-var-action":"none","missing-var-default":"","missing-var-log":"warn","recusrive":false,"separator":"\.","token-pattern":"default","token-prefix":"","token-suffix":"","transforms":false,"transforms-prefix":"\(","transforms-suffix":"\)","variable-files":0,"variable-envs":0,"inline-variables":0,"output-defaults":1,"output-files":2,"output-replaced":3,"output-tokens":4,"output-transforms":5,"result":"success","duration":\d+(?:\.\d+)?}]/
)
);
});
Expand All @@ -267,7 +267,7 @@ describe('run', () => {

expect(debugSpy).toHaveBeenCalledWith(
expect.stringMatching(
/\[\{"name":"\*+","time":"[^"]+","iKey":"\*+","tags":\{"ai\.application\.ver":"1\.\d+\.\d+","ai\.cloud\.role":"server","ai\.internal\.sdkVersion":"replacetokens:2\.0\.0","ai\.operation\.id":"[^"]+","ai\.operation\.name":"replacetokens-action","ai\.user\.accountId":"c054bf9f6127dc352a184a29403ac9114f6c2a8e27cb467197cdfc1c3df119e4","ai\.user\.authUserId":"59830ebc3a4184110566bf1a290d08473dfdcbd492ce498b14cd1a5e2fa2e441"},"data":\{"baseType":"EventData","baseData":\{"ver":"2","name":"tokens\.replaced","properties":\{"os":"Windows","result":"failed","duration":\d+(?:\.\d+)?}}}}]/
/\[\{"eventType":"TokensReplaced","application":"replacetokens-action","version":"1\.\d+\.\d+","account":"c054bf9f6127dc352a184a29403ac9114f6c2a8e27cb467197cdfc1c3df119e4","pipeline":"59830ebc3a4184110566bf1a290d08473dfdcbd492ce498b14cd1a5e2fa2e441","host":"server","os":"Windows","result":"failed","duration":\d+(?:\.\d+)?}]/
)
);
});
Expand Down

0 comments on commit e08bbfc

Please sign in to comment.