Skip to content

Commit

Permalink
Change telemetry provider (#19)
Browse files Browse the repository at this point in the history
  • Loading branch information
qetza authored Mar 18, 2024
1 parent 54e0f7d commit a5415f5
Show file tree
Hide file tree
Showing 31 changed files with 299 additions and 601 deletions.
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,17 @@
# Changelog
## 5.0.4
Task 6.0.4
- Update @qetza/replacetokens to 1.4.0.
- Change telemetry provider.

Task 5.3.2
- Change telemetry provider.

Task 4.4.2
- Change telemetry provider.

Task 3.12.2
- Change telemetry provider.

## 5.0.3
Task 6.0.3
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ The task was completely rewritten to use the npm package [@qetza/replacetokens](
addBOM: ''

# A YAML formatted string containing additional variable values (keys are case-insensitive).
# YAML can be:
# Value can be:
# - an object: properties will be parsed as key/value pairs
# - a string starting with '@': value is parsed as multiple glob patterns separated
# by a semi-colon ';' using fast-glob syntax to JSON or YAML files
Expand Down
10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@
"build:v4": "tsc --project tasks/ReplaceTokensV4/tsconfig.json",
"build:v5": "tsc --project tasks/ReplaceTokensV5/tsconfig.json",
"build:v6": "tsc --project tasks/ReplaceTokensV6/tsconfig.json",
"test": "mocha tasks/**/tests/L0.js",
"test:v3": "mocha tasks/ReplaceTokensV3/dist/tests/L0.js",
"test:v4": "mocha tasks/ReplaceTokensV4/dist/tests/L0.js",
"test:v5": "mocha tasks/ReplaceTokensV5/dist/tests/L0.js",
"test:v6": "mocha tasks/ReplaceTokensV6/dist/tests/L0.js",
"test": "npm run build && mocha tasks/**/tests/L0.js",
"test:v3": "npm run build:v3 && mocha tasks/ReplaceTokensV3/dist/tests/L0.js",
"test:v4": "npm run build:v4 && mocha tasks/ReplaceTokensV4/dist/tests/L0.js",
"test:v5": "npm run build:v5 && mocha tasks/ReplaceTokensV5/dist/tests/L0.js",
"test:v6": "npm run build:v6 && mocha tasks/ReplaceTokensV6/dist/tests/L0.js",
"package": "node scripts/package.js",
"package:public": "node scripts/package.js --public",
"format": "npm run format:v3 && npm run format:v4 && npm run format:v5 && npm run format:v6",
Expand Down
2 changes: 2 additions & 0 deletions tasks/ReplaceTokensV3/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# Changelog
## 3.12.2
- Change telemetry provider.

## 3.12.1
- Add agent OS in telemetry ([#5](https://github.com/qetza/replacetokens-task/issues/5)).
Expand Down
2 changes: 1 addition & 1 deletion tasks/ReplaceTokensV3/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ The following **anonymous** data is send:
- the **number of** _targetFiles_ entries having an output pattern
- the **number of** _variableFiles_ entries
- the **number of** _inlineVariables_ entries
- the task result (`succeed` or `failed`)
- the task result (`success` or `failed`)
- the task execution duration
- the **number of** tokens replaced with the default value
- the **number of** files parsed
Expand Down
18 changes: 7 additions & 11 deletions tasks/ReplaceTokensV3/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import iconv = require('iconv-lite');
import jschardet = require('jschardet');
import path = require('path');
import os = require('os');
import crypto = require('crypto');
import trackEvent, { TelemetryEvent } from './telemetry';
import yaml = require('js-yaml');
import stripJsonComments from './strip-json-comments';
Expand Down Expand Up @@ -498,8 +497,11 @@ var normalize = function (p: string): string {

async function run() {
// initialize telemetry (outside of try as needed in catch and finally)
let telemetryEnabled: boolean = false;
let telemetryEvent: TelemetryEvent = {} as TelemetryEvent;
let telemetryEnabled = false;
let telemetryEvent = new TelemetryEvent(
tl.getVariable('ystem.collectionid'),
`${tl.getVariable('system.teamprojectid')}${tl.getVariable('system.definitionid')}`
);

let proxyUrl: string | undefined = undefined;
const config = tl.getHttpProxyConfiguration();
Expand All @@ -513,13 +515,7 @@ async function run() {
tl.getBoolInput('enableTelemetry', false) &&
['true', '1'].indexOf(process.env['REPLACETOKENS_TELEMETRY_OPTOUT'] || process.env['REPLACETOKENS_DISABLE_TELEMETRY']) === -1;

telemetryEvent.account = crypto.createHash('sha256').update(tl.getVariable('system.collectionid')).digest('hex');
telemetryEvent.pipeline = crypto
.createHash('sha256')
.update(tl.getVariable('system.teamprojectid') + tl.getVariable('system.definitionid'))
.digest('hex');
telemetryEvent.pipelineType = tl.getVariable('release.releaseid') ? 'release' : 'build';
telemetryEvent.serverType = !serverType || serverType.toLowerCase() !== 'hosted' ? 'server' : 'cloud';
telemetryEvent.host = !serverType || serverType.toLowerCase() !== 'hosted' ? 'server' : 'cloud';
telemetryEvent.os = (() => {
const os = tl.getVariable('Agent.OS');
switch (os) {
Expand Down Expand Up @@ -693,7 +689,7 @@ async function run() {
telemetryEvent.escapeType = options.escapeType;
telemetryEvent.keepToken = options.keepToken;
telemetryEvent.pattern = regex.source;
telemetryEvent.result = 'succeed';
telemetryEvent.result = 'success';
telemetryEvent.rules = rules.length;
telemetryEvent.rulesWithInputWildcard = ruleUsingInputWildcardCount;
telemetryEvent.rulesWithNegativePattern = ruleUsingNegativeInputPattern;
Expand Down
2 changes: 1 addition & 1 deletion tasks/ReplaceTokensV3/task.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"version": {
"Major": 3,
"Minor": 12,
"Patch": 1
"Patch": 2
},
"instanceNameFormat": "Replace tokens in $(targetFiles)",
"minimumAgentVersion": "2.105.0",
Expand Down
131 changes: 41 additions & 90 deletions tasks/ReplaceTokensV3/telemetry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,85 +3,26 @@ import url = require('url');
import http = require('http');
import https = require('https');

const instrumentationKey = 'e18a8793-c093-46f9-8c3b-433c9553eb7f';
const preview = false;
const version = '3.5.0';
const sdkVersion = 'replacetokens:1.0.0';
const application = 'replacetokens-task';
const eventName = 'tokens.replaced';
const telemetryUrl = 'https://westeurope-5.in.applicationinsights.azure.com/v2/track';
const version = '3.0.0';
const endpoint = 'https://insights-collector.eu01.nr-data.net/v1/accounts/4392697/events';
const key = 'eu01xxc28887c2d47d9719ed24a74df5FFFFNRAL';
const timeout = 3000;

export default function trackEvent(event: TelemetryEvent, proxyUrl?: string): string {
export default function trackEvent(event: TelemetryEvent, proxy?: string): string | undefined {
try {
// create event payload
let operationId: string = crypto.randomBytes(16).toString('hex');
let body = {
name: 'Microsoft.ApplicationInsights.Dev.' + instrumentationKey + '.Event',
time: new Date().toISOString(),
iKey: instrumentationKey,
tags: {
'ai.application.ver': version,
'ai.cloud.role': event.serverType,
'ai.internal.sdkVersion': sdkVersion,
'ai.operation.id': operationId,
'ai.operation.name': application,
'ai.operation.parentId': '|' + operationId,
'ai.user.accountId': event.account,
'ai.user.authUserId': event.pipeline
},
data: {
baseType: 'EventData',
baseData: {
ver: '2',
name: eventName,
properties: {
preview: preview,
pipelineType: event.pipelineType,
result: event.result,
tokenPrefix: event.tokenPrefix,
tokenSuffix: event.tokenSuffix,
pattern: event.pattern,
encoding: event.encoding,
keepToken: event.keepToken,
actionOnMissing: event.actionOnMissing,
writeBOM: event.writeBOM,
emptyValue: event.emptyValue,
escapeType: event.escapeType,
escapeChar: event.escapeChar,
charsToEscape: event.charsToEscape,
verbosity: event.verbosity,
variableFiles: event.variableFiles,
variableSeparator: event.variableSeparator,
rules: event.rules,
rulesWithInputWildcard: event.rulesWithInputWildcard,
rulesWithOutputPattern: event.rulesWithOutputPattern,
rulesWithNegativePattern: event.rulesWithNegativePattern,
duration: event.duration,
tokenReplaced: event.tokenReplaced,
tokenFound: event.tokenFound,
fileProcessed: event.fileProcessed,
useLegacyPattern: event.useLegacyPattern,
enableTransforms: event.enableTransforms,
transformPrefix: event.transformPrefix,
transformSuffix: event.transformSuffix,
transformPattern: event.transformPattern,
transformExecuted: event.transformExecuted,
defaultValue: event.defaultValue,
defaultValueReplaced: event.defaultValueReplaced,
actionOnNoFiles: event.actionOnNoFiles,
inlineVariables: event.inlineVariables,
enableRecursion: event.enableRecursion,
useLegacyEmptyFeature: event.useLegacyEmptyFeature,
useDefaultValue: event.useDefaultValue,
os: event.os
}
}
let body = [
{
...event,
eventType: 'TokensReplaced',
application: application,
version: version
}
};
];

// send event
let telemetryUrlParsed = url.parse(telemetryUrl);
let telemetryUrlParsed = url.parse(endpoint);
let options = {
method: 'POST',
host: telemetryUrlParsed.hostname,
Expand All @@ -90,29 +31,30 @@ export default function trackEvent(event: TelemetryEvent, proxyUrl?: string): st
withCredentials: false,
timeout: timeout,
headers: <{ [key: string]: string }>{
'Api-Key': key,
'Content-Type': 'application/json'
}
};

proxyUrl = proxyUrl || process.env['https_proxy'] || undefined;
if (proxyUrl) {
if (proxyUrl.indexOf('//') === 0) proxyUrl = 'http:' + proxyUrl;
proxy = proxy || process.env['https_proxy'] || undefined;
if (proxy) {
if (proxy.indexOf('//') === 0) proxy = 'http:' + proxy;

let proxyUrlParsed = url.parse(proxyUrl);
let proxyUrlParsed = url.parse(proxy);
if (proxyUrlParsed.protocol === 'https:') {
proxyUrl = undefined;
proxy = undefined;
} else {
options = {
...options,
host: proxyUrlParsed.hostname,
port: proxyUrlParsed.port || '80',
path: telemetryUrl,
path: endpoint,
headers: { ...options.headers, Host: telemetryUrlParsed.hostname }
};
}
}

let request = proxyUrl ? http.request(options) : https.request(options);
let request = proxy ? http.request(options) : https.request(options);

request.setTimeout(timeout, () => {
request.abort();
Expand All @@ -122,20 +64,31 @@ export default function trackEvent(event: TelemetryEvent, proxyUrl?: string): st
request.write(JSON.stringify(body));
request.end();

// return payload
body.name = 'Microsoft.ApplicationInsights.Dev.*****.Event';
body.iKey = '*****';

return JSON.stringify(body);
} catch {}
} catch {
// silently continue
}
}

export interface TelemetryEvent {
account: string;
pipeline: string;
pipelineType: string;
serverType: string;
export class TelemetryEvent {
private readonly account: string;
private readonly pipeline: string;

constructor(account: string, pipeline: string) {
this.account = crypto
.createHash('sha256')
.update(account || '')
.digest('hex');
this.pipeline = crypto
.createHash('sha256')
.update(pipeline || '')
.digest('hex');
}

host: string;
os: string;
result: string;
duration: number;
tokenPrefix: string;
tokenSuffix: string;
pattern: string;
Expand All @@ -154,7 +107,6 @@ export interface TelemetryEvent {
rulesWithInputWildcard: number;
rulesWithOutputPattern: number;
rulesWithNegativePattern: number;
duration: number;
tokenReplaced: number;
tokenFound: number;
fileProcessed: number;
Expand All @@ -171,5 +123,4 @@ export interface TelemetryEvent {
enableRecursion: boolean;
useLegacyEmptyFeature: boolean;
useDefaultValue: boolean;
os: string;
}
4 changes: 2 additions & 2 deletions tasks/ReplaceTokensV3/tests/L0.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ describe('ReplaceTokens v3 L0 suite', function () {

tr.stdout.should.include('telemetry sent');
tr.stdout.should.match(
/\{"name":"Microsoft\.ApplicationInsights\.Dev\.\*+\.Event","time":"[^"]+","iKey":"\*+","tags":\{"ai\.application\.ver":"3\.\d+\.\d+","ai\.cloud\.role":"server","ai\.internal\.sdkVersion":"replacetokens:1\.0\.0","ai\.operation\.id":"([^"]+)","ai\.operation\.name":"replacetokens-task","ai\.operation\.parentId":"\|\1","ai\.user\.accountId":"494d0aad9d06c4ddb51d5300620122ce55366a9382b3cc2835ed5f0e2e67b4d0","ai\.user\.authUserId":"b98ed03d3eec376dcc015365c1a944e3ebbcc33d30e3261af3f4e4abb107aa82"},"data":\{"baseType":"EventData","baseData":\{"ver":"2","name":"tokens\.replaced","properties":\{"preview":false,"pipelineType":"build","result":"failed","os":"Windows"}}}}/
/\[\{"account":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","pipeline":"b98ed03d3eec376dcc015365c1a944e3ebbcc33d30e3261af3f4e4abb107aa82","host":"server","os":"Windows","result":"failed","eventType":"TokensReplaced","application":"replacetokens-task","version":"3.0.0"}]/
);
},
tr,
Expand All @@ -192,7 +192,7 @@ describe('ReplaceTokens v3 L0 suite', function () {

tr.stdout.should.include('telemetry sent');
tr.stdout.should.match(
/\{"name":"Microsoft\.ApplicationInsights\.Dev\.\*+\.Event","time":"[^"]+","iKey":"\*+","tags":\{"ai\.application\.ver":"3\.\d+\.\d+","ai\.cloud\.role":"server","ai\.internal\.sdkVersion":"replacetokens:1\.0\.0","ai\.operation\.id":"([^"]+)","ai\.operation\.name":"replacetokens-task","ai\.operation\.parentId":"\|\1","ai\.user\.accountId":"494d0aad9d06c4ddb51d5300620122ce55366a9382b3cc2835ed5f0e2e67b4d0","ai\.user\.authUserId":"b98ed03d3eec376dcc015365c1a944e3ebbcc33d30e3261af3f4e4abb107aa82"},"data":\{"baseType":"EventData","baseData":\{"ver":"2","name":"tokens\.replaced","properties":\{"preview":false,"pipelineType":"build","result":"succeed","tokenPrefix":"#{","tokenSuffix":"}#","pattern":"#\\\\{\\\\s\*\(\(\?:\(\?!#\\\\{\)\(\?!\\\\s\*\\\\}#\)\.\)\*\)\\\\s\*\\\\}#","encoding":"auto","keepToken":false,"actionOnMissing":"warn","writeBOM":true,"verbosity":"normal","variableFiles":0,"rules":1,"rulesWithInputWildcard":0,"rulesWithOutputPattern":0,"rulesWithNegativePattern":0,"duration":\d+(?:\.\d+)?,"tokenReplaced":1,"tokenFound":1,"fileProcessed":1,"useLegacyPattern":false,"enableTransforms":false,"transformPrefix":"\(","transformSuffix":"\)","transformPattern":"\\\\s\*\(\.\*\)\\\\\(\\\\s\*\(\(\?:\(\?!\\\\\(\)\(\?!\\\\s\*\\\\\)\)\.\)\*\)\\\\s\*\\\\\)\\\\s\*","transformExecuted":0,"defaultValue":"","defaultValueReplaced":0,"actionOnNoFiles":"continue","inlineVariables":0,"enableRecursion":false,"useLegacyEmptyFeature":false,"useDefaultValue":false,"os":"Windows"}}}}/
/\[\{"account":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","pipeline":"b98ed03d3eec376dcc015365c1a944e3ebbcc33d30e3261af3f4e4abb107aa82","host":"server","os":"Windows","actionOnMissing":"warn","encoding":"auto","keepToken":false,"pattern":"#\\\\{\\\\s\*\(\(\?:\(\?!#\\\\{\)\(\?!\\\\s\*\\\\}#\)\.\)\*\)\\\\s\*\\\\}#","result":"success","rules":1,"rulesWithInputWildcard":0,"rulesWithNegativePattern":0,"rulesWithOutputPattern":0,"tokenPrefix":"#{","tokenSuffix":"}#","variableFiles":0,"verbosity":"normal","writeBOM":true,"useLegacyPattern":false,"enableTransforms":false,"transformPrefix":"\(","transformSuffix":"\)","transformPattern":"\\\\s\*\(\.\*\)\\\\\(\\\\s\*\(\(\?:\(\?!\\\\\(\)\(\?!\\\\s\*\\\\\)\)\.\)\*\)\\\\s\*\\\\\)\\\\s\*","defaultValue":"","actionOnNoFiles":"continue","inlineVariables":0,"enableRecursion":false,"useLegacyEmptyFeature":false,"useDefaultValue":false,"duration":\d+(?:\.\d+)?,"tokenReplaced":1,"tokenFound":1,"defaultValueReplaced":0,"fileProcessed":1,"transformExecuted":0,"eventType":"TokensReplaced","application":"replacetokens-task","version":"3.0.0"}]/
);
},
tr,
Expand Down
2 changes: 2 additions & 0 deletions tasks/ReplaceTokensV4/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# Changelog
## 4.4.2
- Change telemetry provider.

## 4.4.1
- Add agent OS in telemetry ([#5](https://github.com/qetza/replacetokens-task/issues/5)).
Expand Down
2 changes: 1 addition & 1 deletion tasks/ReplaceTokensV4/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ The following **anonymous** data is send:
- the **number of** _targetFiles_ entries having an output pattern
- the **number of** _variableFiles_ entries
- the **number of** _inlineVariables_ entries
- the task result (`succeed` or `failed`)
- the task result (`success` or `failed`)
- the task execution duration
- the outputs (_defaultValueCount_, _fileProcessedCount_, _tokenReplacedCount_, _tokenFoundCount_ and _transformExecutedCount_)

Expand Down
18 changes: 7 additions & 11 deletions tasks/ReplaceTokensV4/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import iconv = require('iconv-lite');
import jschardet = require('jschardet');
import path = require('path');
import os = require('os');
import crypto = require('crypto');
import trackEvent, { TelemetryEvent } from './telemetry';
import yaml = require('js-yaml');
import stripJsonComments from './strip-json-comments';
Expand Down Expand Up @@ -498,8 +497,11 @@ var normalize = function (p: string): string {

async function run() {
// initialize telemetry (outside of try as needed in catch and finally)
let telemetryEnabled: boolean = false;
let telemetryEvent: TelemetryEvent = {} as TelemetryEvent;
let telemetryEnabled = false;
let telemetryEvent = new TelemetryEvent(
tl.getVariable('ystem.collectionid'),
`${tl.getVariable('system.teamprojectid')}${tl.getVariable('system.definitionid')}`
);

let proxyUrl: string | undefined = undefined;
const config = tl.getHttpProxyConfiguration();
Expand All @@ -513,13 +515,7 @@ async function run() {
tl.getBoolInput('enableTelemetry', false) &&
['true', '1'].indexOf(process.env['REPLACETOKENS_TELEMETRY_OPTOUT'] || process.env['REPLACETOKENS_DISABLE_TELEMETRY']) === -1;

telemetryEvent.account = crypto.createHash('sha256').update(tl.getVariable('system.collectionid')).digest('hex');
telemetryEvent.pipeline = crypto
.createHash('sha256')
.update(tl.getVariable('system.teamprojectid') + tl.getVariable('system.definitionid'))
.digest('hex');
telemetryEvent.pipelineType = tl.getVariable('release.releaseid') ? 'release' : 'build';
telemetryEvent.serverType = !serverType || serverType.toLowerCase() !== 'hosted' ? 'server' : 'cloud';
telemetryEvent.host = !serverType || serverType.toLowerCase() !== 'hosted' ? 'server' : 'cloud';
telemetryEvent.os = (() => {
const os = tl.getVariable('Agent.OS');
switch (os) {
Expand Down Expand Up @@ -721,7 +717,7 @@ async function run() {
telemetryEvent.escapeType = options.escapeType;
telemetryEvent.keepToken = options.keepToken;
telemetryEvent.pattern = regex.source;
telemetryEvent.result = 'succeed';
telemetryEvent.result = 'success';
telemetryEvent.rules = rules.length;
telemetryEvent.rulesWithInputWildcard = ruleUsingInputWildcardCount;
telemetryEvent.rulesWithNegativePattern = ruleUsingNegativeInputPattern;
Expand Down
2 changes: 1 addition & 1 deletion tasks/ReplaceTokensV4/task.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"version": {
"Major": 4,
"Minor": 4,
"Patch": 1
"Patch": 2
},
"releaseNotes": "Added output variables (breaking change).<br/>Added token pattern dropdown (breaking change).",
"instanceNameFormat": "Replace tokens in $(targetFiles)",
Expand Down
Loading

0 comments on commit a5415f5

Please sign in to comment.