dd-trace 2.12.2 → 2.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -2
- package/packages/datadog-instrumentations/index.js +1 -52
- package/packages/datadog-instrumentations/src/helpers/hooks.js +68 -0
- package/packages/datadog-instrumentations/src/helpers/instrument.js +5 -34
- package/packages/datadog-instrumentations/src/helpers/instrumentations.js +3 -0
- package/packages/datadog-instrumentations/src/helpers/register.js +59 -0
- package/packages/datadog-plugin-mocha/src/index.js +2 -2
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +220 -0
- package/packages/dd-trace/src/config.js +6 -0
- package/packages/dd-trace/src/{profiling/exporters → exporters/common}/form-data.js +0 -0
- package/packages/dd-trace/src/id.js +16 -13
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +6 -6
- package/packages/dd-trace/src/plugin_manager.js +95 -65
- package/packages/dd-trace/src/plugins/index.js +57 -45
- package/packages/dd-trace/src/plugins/util/ci.js +34 -9
- package/packages/dd-trace/src/plugins/util/git.js +52 -2
- package/packages/dd-trace/src/plugins/util/tags.js +4 -1
- package/packages/dd-trace/src/profiling/exporters/agent.js +1 -1
- package/packages/dd-trace/src/proxy.js +15 -8
- package/packages/dd-trace/src/startup-log.js +8 -19
- package/packages/dd-trace/src/telemetry.js +1 -14
- package/scripts/install_plugin_modules.js +17 -26
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dd-trace",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.13.0",
|
|
4
4
|
"description": "Datadog APM tracing client for JavaScript",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"typings": "index.d.ts",
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
"@datadog/native-appsec": "^1.2.1",
|
|
62
62
|
"@datadog/native-metrics": "^1.4.2",
|
|
63
63
|
"@datadog/pprof": "^1.0.2",
|
|
64
|
-
"@datadog/sketches-js": "^
|
|
64
|
+
"@datadog/sketches-js": "^2.0.0",
|
|
65
65
|
"@types/node": ">=12",
|
|
66
66
|
"crypto-randomuuid": "^1.0.0",
|
|
67
67
|
"diagnostics_channel": "^1.1.0",
|
|
@@ -1,54 +1,3 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
require('./src/
|
|
4
|
-
require('./src/amqp10')
|
|
5
|
-
require('./src/aws-sdk')
|
|
6
|
-
require('./src/bluebird')
|
|
7
|
-
require('./src/bunyan')
|
|
8
|
-
require('./src/cassandra-driver')
|
|
9
|
-
require('./src/connect')
|
|
10
|
-
require('./src/couchbase')
|
|
11
|
-
require('./src/cucumber')
|
|
12
|
-
require('./src/dns')
|
|
13
|
-
require('./src/elasticsearch')
|
|
14
|
-
require('./src/express')
|
|
15
|
-
require('./src/fastify')
|
|
16
|
-
require('./src/find-my-way')
|
|
17
|
-
require('./src/generic-pool')
|
|
18
|
-
require('./src/google-cloud-pubsub')
|
|
19
|
-
require('./src/graphql')
|
|
20
|
-
require('./src/grpc')
|
|
21
|
-
require('./src/hapi')
|
|
22
|
-
require('./src/http')
|
|
23
|
-
require('./src/http2')
|
|
24
|
-
require('./src/ioredis')
|
|
25
|
-
require('./src/jest')
|
|
26
|
-
require('./src/kafkajs')
|
|
27
|
-
require('./src/knex')
|
|
28
|
-
require('./src/koa')
|
|
29
|
-
require('./src/memcached')
|
|
30
|
-
require('./src/microgateway-core')
|
|
31
|
-
require('./src/moleculer')
|
|
32
|
-
require('./src/mongodb-core')
|
|
33
|
-
require('./src/mongoose')
|
|
34
|
-
require('./src/mysql')
|
|
35
|
-
require('./src/mysql2')
|
|
36
|
-
require('./src/mocha')
|
|
37
|
-
require('./src/net')
|
|
38
|
-
require('./src/next')
|
|
39
|
-
require('./src/oracledb')
|
|
40
|
-
require('./src/paperplane')
|
|
41
|
-
require('./src/pino')
|
|
42
|
-
require('./src/pg')
|
|
43
|
-
require('./src/promise')
|
|
44
|
-
require('./src/promise-js')
|
|
45
|
-
require('./src/q')
|
|
46
|
-
require('./src/redis')
|
|
47
|
-
require('./src/restify')
|
|
48
|
-
require('./src/router')
|
|
49
|
-
require('./src/rhea')
|
|
50
|
-
require('./src/sharedb')
|
|
51
|
-
require('./src/tedious')
|
|
52
|
-
require('./src/when')
|
|
53
|
-
require('./src/winston')
|
|
54
|
-
require('./src/limitd-client')
|
|
3
|
+
require('./src/helpers/register')
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
'@cucumber/cucumber': () => require('../cucumber'),
|
|
5
|
+
'@elastic/elasticsearch': () => require('../elasticsearch'),
|
|
6
|
+
'@elastic/transport': () => require('../elasticsearch'),
|
|
7
|
+
'@google-cloud/pubsub': () => require('../google-cloud-pubsub'),
|
|
8
|
+
'@grpc/grpc-js': () => require('../grpc'),
|
|
9
|
+
'@hapi/hapi': () => require('../hapi'),
|
|
10
|
+
'@koa/router': () => require('../koa'),
|
|
11
|
+
'@node-redis/client': () => require('../redis'),
|
|
12
|
+
'amqp10': () => require('../amqp10'),
|
|
13
|
+
'amqplib': () => require('../amqplib'),
|
|
14
|
+
'aws-sdk': () => require('../aws-sdk'),
|
|
15
|
+
'bluebird': () => require('../bluebird'),
|
|
16
|
+
'bunyan': () => require('../bunyan'),
|
|
17
|
+
'cassandra-driver': () => require('../cassandra-driver'),
|
|
18
|
+
'connect': () => require('../connect'),
|
|
19
|
+
'couchbase': () => require('../couchbase'),
|
|
20
|
+
'cypress': () => require('../cypress'),
|
|
21
|
+
'dns': () => require('../dns'),
|
|
22
|
+
'elasticsearch': () => require('../elasticsearch'),
|
|
23
|
+
'express': () => require('../express'),
|
|
24
|
+
'fastify': () => require('../fastify'),
|
|
25
|
+
'find-my-way': () => require('../find-my-way'),
|
|
26
|
+
'graphql': () => require('../graphql'),
|
|
27
|
+
'grpc': () => require('../grpc'),
|
|
28
|
+
'hapi': () => require('../hapi'),
|
|
29
|
+
'http': () => require('../http'),
|
|
30
|
+
'http2': () => require('../http2'),
|
|
31
|
+
'https': () => require('../http'),
|
|
32
|
+
'ioredis': () => require('../ioredis'),
|
|
33
|
+
'jest-environment-node': () => require('../jest'),
|
|
34
|
+
'jest-environment-jsdom': () => require('../jest'),
|
|
35
|
+
'jest-jasmine2': () => require('../jest'),
|
|
36
|
+
'koa': () => require('../koa'),
|
|
37
|
+
'koa-router': () => require('../koa'),
|
|
38
|
+
'kafkajs': () => require('../kafkajs'),
|
|
39
|
+
'limitd-client': () => require('../limitd-client'),
|
|
40
|
+
'memcached': () => require('../memcached'),
|
|
41
|
+
'microgateway-core': () => require('../microgateway-core'),
|
|
42
|
+
'mocha': () => require('../mocha'),
|
|
43
|
+
'mocha-each': () => require('../mocha'),
|
|
44
|
+
'moleculer': () => require('../moleculer'),
|
|
45
|
+
'mongodb': () => require('../mongodb-core'),
|
|
46
|
+
'mongodb-core': () => require('../mongodb-core'),
|
|
47
|
+
'mongoose': () => require('../mongoose'),
|
|
48
|
+
'mysql': () => require('../mysql'),
|
|
49
|
+
'mysql2': () => require('../mysql2'),
|
|
50
|
+
'net': () => require('../net'),
|
|
51
|
+
'next': () => require('../next'),
|
|
52
|
+
'oracledb': () => require('../oracledb'),
|
|
53
|
+
'paperplane': () => require('../paperplane'),
|
|
54
|
+
'pg': () => require('../pg'),
|
|
55
|
+
'pino': () => require('../pino'),
|
|
56
|
+
'pino-pretty': () => require('../pino'),
|
|
57
|
+
'promise-js': () => require('../promise-js'),
|
|
58
|
+
'promise': () => require('../promise'),
|
|
59
|
+
'q': () => require('../q'),
|
|
60
|
+
'redis': () => require('../redis'),
|
|
61
|
+
'restify': () => require('../restify'),
|
|
62
|
+
'rhea': () => require('../rhea'),
|
|
63
|
+
'router': () => require('../router'),
|
|
64
|
+
'sharedb': () => require('../sharedb'),
|
|
65
|
+
'tedious': () => require('../tedious'),
|
|
66
|
+
'when': () => require('../when'),
|
|
67
|
+
'winston': () => require('../winston')
|
|
68
|
+
}
|
|
@@ -1,16 +1,12 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const dc = require('diagnostics_channel')
|
|
4
|
-
const path = require('path')
|
|
5
4
|
const semver = require('semver')
|
|
6
|
-
const
|
|
7
|
-
const requirePackageJson = require('../../../dd-trace/src/require-package-json')
|
|
5
|
+
const instrumentations = require('./instrumentations')
|
|
8
6
|
const { AsyncResource } = require('async_hooks')
|
|
9
|
-
const log = require('../../../dd-trace/src/log')
|
|
10
7
|
|
|
11
|
-
const pathSepExpr = new RegExp(`\\${path.sep}`, 'g')
|
|
12
8
|
const channelMap = {}
|
|
13
|
-
exports.channel = function
|
|
9
|
+
exports.channel = function (name) {
|
|
14
10
|
const maybe = channelMap[name]
|
|
15
11
|
if (maybe) return maybe
|
|
16
12
|
const ch = dc.channel(name)
|
|
@@ -19,36 +15,11 @@ exports.channel = function channel (name) {
|
|
|
19
15
|
}
|
|
20
16
|
|
|
21
17
|
exports.addHook = function addHook ({ name, versions, file }, hook) {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
Hook([name], (moduleExports, moduleName, moduleBaseDir) => {
|
|
25
|
-
moduleName = moduleName.replace(pathSepExpr, '/')
|
|
26
|
-
|
|
27
|
-
if (moduleName !== fullFilename || !matchVersion(getVersion(moduleBaseDir), versions)) {
|
|
28
|
-
return moduleExports
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
try {
|
|
32
|
-
return hook(moduleExports)
|
|
33
|
-
} catch (e) {
|
|
34
|
-
log.error(e)
|
|
35
|
-
return moduleExports
|
|
36
|
-
}
|
|
37
|
-
})
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
function matchVersion (version, ranges) {
|
|
41
|
-
return !version || (ranges && ranges.some(range => semver.satisfies(semver.coerce(version), range)))
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
function getVersion (moduleBaseDir) {
|
|
45
|
-
if (moduleBaseDir) {
|
|
46
|
-
return requirePackageJson(moduleBaseDir, module).version
|
|
18
|
+
if (!instrumentations[name]) {
|
|
19
|
+
instrumentations[name] = []
|
|
47
20
|
}
|
|
48
|
-
}
|
|
49
21
|
|
|
50
|
-
|
|
51
|
-
return [name, file].filter(val => val).join('/')
|
|
22
|
+
instrumentations[name].push({ name, versions, file, hook })
|
|
52
23
|
}
|
|
53
24
|
|
|
54
25
|
// AsyncResource.bind exists and binds `this` properly only from 17.8.0 and up.
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { channel } = require('diagnostics_channel')
|
|
4
|
+
const path = require('path')
|
|
5
|
+
const semver = require('semver')
|
|
6
|
+
const Hook = require('./hook')
|
|
7
|
+
const requirePackageJson = require('../../../dd-trace/src/require-package-json')
|
|
8
|
+
const log = require('../../../dd-trace/src/log')
|
|
9
|
+
|
|
10
|
+
const hooks = require('./hooks')
|
|
11
|
+
const instrumentations = require('./instrumentations')
|
|
12
|
+
const names = Object.keys(hooks)
|
|
13
|
+
const pathSepExpr = new RegExp(`\\${path.sep}`, 'g')
|
|
14
|
+
|
|
15
|
+
const loadChannel = channel('dd-trace:instrumentation:load')
|
|
16
|
+
|
|
17
|
+
// TODO: make this more efficient
|
|
18
|
+
|
|
19
|
+
for (const packageName of names) {
|
|
20
|
+
Hook([packageName], (moduleExports, moduleName, moduleBaseDir) => {
|
|
21
|
+
moduleName = moduleName.replace(pathSepExpr, '/')
|
|
22
|
+
|
|
23
|
+
hooks[packageName]()
|
|
24
|
+
|
|
25
|
+
for (const { name, file, versions, hook } of instrumentations[packageName]) {
|
|
26
|
+
const fullFilename = filename(name, file)
|
|
27
|
+
|
|
28
|
+
if (moduleName === fullFilename) {
|
|
29
|
+
const version = getVersion(moduleBaseDir)
|
|
30
|
+
|
|
31
|
+
if (matchVersion(version, versions)) {
|
|
32
|
+
try {
|
|
33
|
+
loadChannel.publish({ name, version, file })
|
|
34
|
+
|
|
35
|
+
moduleExports = hook(moduleExports)
|
|
36
|
+
} catch (e) {
|
|
37
|
+
log.error(e)
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return moduleExports
|
|
44
|
+
})
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function matchVersion (version, ranges) {
|
|
48
|
+
return !version || (ranges && ranges.some(range => semver.satisfies(semver.coerce(version), range)))
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function getVersion (moduleBaseDir) {
|
|
52
|
+
if (moduleBaseDir) {
|
|
53
|
+
return requirePackageJson(moduleBaseDir, module).version
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function filename (name, file) {
|
|
58
|
+
return [name, file].filter(val => val).join('/')
|
|
59
|
+
}
|
|
@@ -161,12 +161,12 @@ class MochaPlugin extends Plugin {
|
|
|
161
161
|
const testSuiteSpan = this._testSuites.get(test.parent)
|
|
162
162
|
|
|
163
163
|
if (testSuiteSpan) {
|
|
164
|
-
const testSuiteId = testSuiteSpan.context()._spanId.toString(
|
|
164
|
+
const testSuiteId = testSuiteSpan.context()._spanId.toString(16)
|
|
165
165
|
testSuiteTags[TEST_SUITE_ID] = testSuiteId
|
|
166
166
|
}
|
|
167
167
|
|
|
168
168
|
if (this.testSessionSpan) {
|
|
169
|
-
const testSessionId = this.testSessionSpan.context()._traceId.toString(
|
|
169
|
+
const testSessionId = this.testSessionSpan.context()._traceId.toString(16)
|
|
170
170
|
testSuiteTags[TEST_SESSION_ID] = testSessionId
|
|
171
171
|
testSuiteTags[TEST_COMMAND] = this.command
|
|
172
172
|
}
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
|
|
2
|
+
const fs = require('fs')
|
|
3
|
+
const https = require('https')
|
|
4
|
+
const path = require('path')
|
|
5
|
+
|
|
6
|
+
const FormData = require('../../../exporters/common/form-data')
|
|
7
|
+
|
|
8
|
+
const log = require('../../../log')
|
|
9
|
+
const {
|
|
10
|
+
getLatestCommits,
|
|
11
|
+
getRepositoryUrl,
|
|
12
|
+
generatePackFilesForCommits,
|
|
13
|
+
getCommitsToUpload
|
|
14
|
+
} = require('../../../plugins/util/git')
|
|
15
|
+
|
|
16
|
+
const isValidSha = (sha) => /[0-9a-f]{40}/.test(sha)
|
|
17
|
+
|
|
18
|
+
function sanitizeCommits (commits) {
|
|
19
|
+
return commits.map(({ id: commitSha, type }) => {
|
|
20
|
+
if (type !== 'commit') {
|
|
21
|
+
throw new Error('Invalid commit response')
|
|
22
|
+
}
|
|
23
|
+
const sanitizedCommit = commitSha.replace(/[^0-9a-f]+/g, '')
|
|
24
|
+
if (sanitizedCommit !== commitSha || !isValidSha(sanitizedCommit)) {
|
|
25
|
+
throw new Error('Invalid commit format')
|
|
26
|
+
}
|
|
27
|
+
return sanitizedCommit
|
|
28
|
+
})
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function getCommonRequestOptions (url) {
|
|
32
|
+
return {
|
|
33
|
+
method: 'POST',
|
|
34
|
+
headers: {
|
|
35
|
+
'dd-api-key': process.env.DATADOG_API_KEY || process.env.DD_API_KEY
|
|
36
|
+
},
|
|
37
|
+
timeout: 15000,
|
|
38
|
+
protocol: url.protocol,
|
|
39
|
+
hostname: url.hostname,
|
|
40
|
+
port: url.port
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* This function posts the SHAs of the commits of the last month
|
|
46
|
+
* The response are the commits for which the backend already has information
|
|
47
|
+
* This response is used to know which commits can be ignored from there on
|
|
48
|
+
*/
|
|
49
|
+
function getCommitsToExclude ({ url, repositoryUrl }, callback) {
|
|
50
|
+
const latestCommits = getLatestCommits()
|
|
51
|
+
const [headCommit] = latestCommits
|
|
52
|
+
|
|
53
|
+
const commonOptions = getCommonRequestOptions(url)
|
|
54
|
+
|
|
55
|
+
const options = {
|
|
56
|
+
...commonOptions,
|
|
57
|
+
headers: {
|
|
58
|
+
...commonOptions.headers,
|
|
59
|
+
'Content-Type': 'application/json'
|
|
60
|
+
},
|
|
61
|
+
path: '/api/v2/git/repository/search_commits'
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const localCommitData = JSON.stringify({
|
|
65
|
+
meta: {
|
|
66
|
+
repository_url: repositoryUrl
|
|
67
|
+
},
|
|
68
|
+
data: latestCommits.map(commit => ({
|
|
69
|
+
id: commit,
|
|
70
|
+
type: 'commit'
|
|
71
|
+
}))
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
const request = https.request(options, (res) => {
|
|
75
|
+
let responseData = ''
|
|
76
|
+
|
|
77
|
+
res.on('data', chunk => { responseData += chunk })
|
|
78
|
+
res.on('end', () => {
|
|
79
|
+
if (res.statusCode === 200) {
|
|
80
|
+
let commitsToExclude
|
|
81
|
+
try {
|
|
82
|
+
commitsToExclude = sanitizeCommits(JSON.parse(responseData).data)
|
|
83
|
+
} catch (e) {
|
|
84
|
+
callback(new Error(`Can't parse response: ${e.message}`))
|
|
85
|
+
return
|
|
86
|
+
}
|
|
87
|
+
callback(null, commitsToExclude, headCommit)
|
|
88
|
+
} else {
|
|
89
|
+
const error = new Error(`Error getting commits: ${res.statusCode} ${res.statusMessage}`)
|
|
90
|
+
callback(error)
|
|
91
|
+
}
|
|
92
|
+
})
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
request.write(localCommitData)
|
|
96
|
+
request.on('error', callback)
|
|
97
|
+
|
|
98
|
+
request.end()
|
|
99
|
+
|
|
100
|
+
return request
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* This function uploads a git packfile
|
|
105
|
+
*/
|
|
106
|
+
function uploadPackFile ({ url, packFileToUpload, repositoryUrl, headCommit }, callback) {
|
|
107
|
+
const form = new FormData()
|
|
108
|
+
|
|
109
|
+
const pushedSha = JSON.stringify({
|
|
110
|
+
data: {
|
|
111
|
+
id: headCommit,
|
|
112
|
+
type: 'commit'
|
|
113
|
+
},
|
|
114
|
+
meta: {
|
|
115
|
+
repository_url: repositoryUrl
|
|
116
|
+
}
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
form.append('pushedSha', pushedSha, { contentType: 'application/json' })
|
|
120
|
+
|
|
121
|
+
try {
|
|
122
|
+
const packFileContent = fs.readFileSync(packFileToUpload)
|
|
123
|
+
// The original filename includes a random prefix, so we remove it here
|
|
124
|
+
const [, filename] = path.basename(packFileToUpload).split('-')
|
|
125
|
+
form.append('packfile', packFileContent, {
|
|
126
|
+
filename,
|
|
127
|
+
contentType: 'application/octet-stream'
|
|
128
|
+
})
|
|
129
|
+
} catch (e) {
|
|
130
|
+
callback(new Error(`Error reading packfile: ${packFileToUpload}`))
|
|
131
|
+
return
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const commonOptions = getCommonRequestOptions(url)
|
|
135
|
+
|
|
136
|
+
const options = {
|
|
137
|
+
...commonOptions,
|
|
138
|
+
path: '/api/v2/git/repository/packfile',
|
|
139
|
+
headers: {
|
|
140
|
+
...commonOptions.headers,
|
|
141
|
+
...form.getHeaders()
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const req = https.request(options, res => {
|
|
146
|
+
res.on('data', () => {})
|
|
147
|
+
res.on('end', () => {
|
|
148
|
+
if (res.statusCode === 204) {
|
|
149
|
+
callback(null)
|
|
150
|
+
} else {
|
|
151
|
+
const error = new Error(`Error uploading packfiles: ${res.statusCode} ${res.statusMessage}`)
|
|
152
|
+
error.status = res.statusCode
|
|
153
|
+
|
|
154
|
+
callback(error)
|
|
155
|
+
}
|
|
156
|
+
})
|
|
157
|
+
})
|
|
158
|
+
|
|
159
|
+
req.on('error', err => {
|
|
160
|
+
callback(err)
|
|
161
|
+
})
|
|
162
|
+
form.pipe(req)
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* This function uploads git metadata to CI Visibility's backend.
|
|
167
|
+
*/
|
|
168
|
+
function sendGitMetadata (site, callback) {
|
|
169
|
+
const url = new URL(`https://api.${site}`)
|
|
170
|
+
|
|
171
|
+
const repositoryUrl = getRepositoryUrl()
|
|
172
|
+
|
|
173
|
+
getCommitsToExclude({ url, repositoryUrl }, (err, commitsToExclude, headCommit) => {
|
|
174
|
+
if (err) {
|
|
175
|
+
callback(err)
|
|
176
|
+
return
|
|
177
|
+
}
|
|
178
|
+
const commitsToUpload = getCommitsToUpload(commitsToExclude)
|
|
179
|
+
|
|
180
|
+
if (!commitsToUpload.length) {
|
|
181
|
+
log.debug('No commits to upload')
|
|
182
|
+
callback(null)
|
|
183
|
+
return
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
const packFilesToUpload = generatePackFilesForCommits(commitsToUpload)
|
|
187
|
+
|
|
188
|
+
let packFileIndex = 0
|
|
189
|
+
// This uploads packfiles sequentially
|
|
190
|
+
const uploadPackFileCallback = (err) => {
|
|
191
|
+
if (err || packFileIndex === packFilesToUpload.length) {
|
|
192
|
+
callback(err)
|
|
193
|
+
return
|
|
194
|
+
}
|
|
195
|
+
return uploadPackFile(
|
|
196
|
+
{
|
|
197
|
+
packFileToUpload: packFilesToUpload[packFileIndex++],
|
|
198
|
+
url,
|
|
199
|
+
repositoryUrl,
|
|
200
|
+
headCommit
|
|
201
|
+
},
|
|
202
|
+
uploadPackFileCallback
|
|
203
|
+
)
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
uploadPackFile(
|
|
207
|
+
{
|
|
208
|
+
url,
|
|
209
|
+
packFileToUpload: packFilesToUpload[packFileIndex++],
|
|
210
|
+
repositoryUrl,
|
|
211
|
+
headCommit
|
|
212
|
+
},
|
|
213
|
+
uploadPackFileCallback
|
|
214
|
+
)
|
|
215
|
+
})
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
module.exports = {
|
|
219
|
+
sendGitMetadata
|
|
220
|
+
}
|
|
@@ -174,6 +174,11 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
|
|
|
174
174
|
|[\\-]{5}BEGIN[a-z\\s]+PRIVATE\\sKEY[\\-]{5}[^\\-]+[\\-]{5}END[a-z\\s]+PRIVATE\\sKEY|ssh-rsa\\s*[a-z0-9\\/\\.+]{100,}`
|
|
175
175
|
)
|
|
176
176
|
|
|
177
|
+
const DD_CIVISIBILITY_GIT_UPLOAD_ENABLED = coalesce(
|
|
178
|
+
process.env.DD_CIVISIBILITY_GIT_UPLOAD_ENABLED,
|
|
179
|
+
false
|
|
180
|
+
)
|
|
181
|
+
|
|
177
182
|
const sampler = (options.experimental && options.experimental.sampler) || {}
|
|
178
183
|
const ingestion = options.ingestion || {}
|
|
179
184
|
const dogstatsd = coalesce(options.dogstatsd, {})
|
|
@@ -248,6 +253,7 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
|
|
|
248
253
|
obfuscatorKeyRegex: DD_APPSEC_OBFUSCATION_PARAMETER_KEY_REGEXP,
|
|
249
254
|
obfuscatorValueRegex: DD_APPSEC_OBFUSCATION_PARAMETER_VALUE_REGEXP
|
|
250
255
|
}
|
|
256
|
+
this.isGitUploadEnabled = isTrue(DD_CIVISIBILITY_GIT_UPLOAD_ENABLED)
|
|
251
257
|
|
|
252
258
|
tagger.add(this.tags, {
|
|
253
259
|
service: this.service,
|
|
File without changes
|
|
@@ -14,17 +14,17 @@ let batch = 0
|
|
|
14
14
|
|
|
15
15
|
// Internal representation of a trace or span ID.
|
|
16
16
|
class Identifier {
|
|
17
|
-
constructor (value, radix) {
|
|
17
|
+
constructor (value, radix = 16) {
|
|
18
18
|
this._isUint64BE = true // msgpack-lite compatibility
|
|
19
|
-
this._buffer =
|
|
20
|
-
?
|
|
21
|
-
:
|
|
19
|
+
this._buffer = radix === 16
|
|
20
|
+
? createBuffer(value)
|
|
21
|
+
: fromString(value, radix)
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
toString (radix) {
|
|
25
|
-
return
|
|
26
|
-
?
|
|
27
|
-
:
|
|
24
|
+
toString (radix = 16) {
|
|
25
|
+
return radix === 16
|
|
26
|
+
? toHexString(this._buffer)
|
|
27
|
+
: toNumberString(this._buffer, radix)
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
toBuffer () {
|
|
@@ -49,10 +49,13 @@ function createBuffer (value) {
|
|
|
49
49
|
if (value === '0') return zeroId
|
|
50
50
|
if (!value) return pseudoRandom()
|
|
51
51
|
|
|
52
|
-
const size = Math.ceil(value.length /
|
|
53
|
-
const
|
|
52
|
+
const size = Math.ceil(value.length / 16) * 16
|
|
53
|
+
const bytes = size / 2
|
|
54
|
+
const buffer = new Array(bytes)
|
|
54
55
|
|
|
55
|
-
|
|
56
|
+
value = value.padStart(size, '0')
|
|
57
|
+
|
|
58
|
+
for (let i = 0; i < bytes; i++) {
|
|
56
59
|
buffer[i] = parseInt(value.substring(i * 2, i * 2 + 2), 16)
|
|
57
60
|
}
|
|
58
61
|
|
|
@@ -100,8 +103,8 @@ function fromString (str, raddix) {
|
|
|
100
103
|
|
|
101
104
|
// Convert a buffer to a numerical string.
|
|
102
105
|
function toNumberString (buffer, radix) {
|
|
103
|
-
let high = readInt32(buffer,
|
|
104
|
-
let low = readInt32(buffer, 4)
|
|
106
|
+
let high = readInt32(buffer, buffer.length - 8)
|
|
107
|
+
let low = readInt32(buffer, buffer.length - 4)
|
|
105
108
|
let str = ''
|
|
106
109
|
|
|
107
110
|
radix = radix || 10
|
|
@@ -82,8 +82,8 @@ class TextMapPropagator {
|
|
|
82
82
|
_injectB3 (spanContext, carrier) {
|
|
83
83
|
if (!this._config.experimental.b3) return
|
|
84
84
|
|
|
85
|
-
carrier[b3TraceKey] = spanContext._traceId.toString(
|
|
86
|
-
carrier[b3SpanKey] = spanContext._spanId.toString(
|
|
85
|
+
carrier[b3TraceKey] = spanContext._traceId.toString(16)
|
|
86
|
+
carrier[b3SpanKey] = spanContext._spanId.toString(16)
|
|
87
87
|
carrier[b3SampledKey] = spanContext._sampling.priority >= AUTO_KEEP ? '1' : '0'
|
|
88
88
|
|
|
89
89
|
if (spanContext._sampling.priority > AUTO_KEEP) {
|
|
@@ -91,7 +91,7 @@ class TextMapPropagator {
|
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
if (spanContext._parentId) {
|
|
94
|
-
carrier[b3ParentKey] = spanContext._parentId.toString(
|
|
94
|
+
carrier[b3ParentKey] = spanContext._parentId.toString(16)
|
|
95
95
|
}
|
|
96
96
|
}
|
|
97
97
|
|
|
@@ -99,8 +99,8 @@ class TextMapPropagator {
|
|
|
99
99
|
if (!this._config.experimental.traceparent) return
|
|
100
100
|
|
|
101
101
|
const sampling = spanContext._sampling.priority >= AUTO_KEEP ? '01' : '00'
|
|
102
|
-
const traceId = spanContext._traceId.toString(
|
|
103
|
-
const spanId = spanContext._spanId.toString(
|
|
102
|
+
const traceId = spanContext._traceId.toString(16).padStart(32, '0')
|
|
103
|
+
const spanId = spanContext._spanId.toString(16).padStart(16, '0')
|
|
104
104
|
carrier[traceparentKey] = `01-${traceId}-${spanId}-${sampling}`
|
|
105
105
|
}
|
|
106
106
|
|
|
@@ -129,7 +129,7 @@ class TextMapPropagator {
|
|
|
129
129
|
const b3 = this._extractB3Headers(carrier)
|
|
130
130
|
const debug = b3[b3FlagsKey] === '1'
|
|
131
131
|
const priority = this._getPriority(b3[b3SampledKey], debug)
|
|
132
|
-
const spanContext = this._extractGenericContext(b3, b3TraceKey, b3SpanKey)
|
|
132
|
+
const spanContext = this._extractGenericContext(b3, b3TraceKey, b3SpanKey, 16)
|
|
133
133
|
|
|
134
134
|
if (priority !== undefined) {
|
|
135
135
|
if (!spanContext) {
|