dd-trace 2.32.0 → 2.34.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.
Files changed (80) hide show
  1. package/index.d.ts +8 -1
  2. package/package.json +4 -3
  3. package/packages/datadog-instrumentations/src/helpers/register.js +4 -0
  4. package/packages/datadog-instrumentations/src/jest.js +20 -17
  5. package/packages/datadog-instrumentations/src/mocha.js +8 -4
  6. package/packages/datadog-instrumentations/src/next.js +6 -1
  7. package/packages/datadog-instrumentations/src/pg.js +3 -4
  8. package/packages/datadog-instrumentations/src/playwright.js +11 -1
  9. package/packages/datadog-plugin-amqp10/src/consumer.js +3 -1
  10. package/packages/datadog-plugin-amqp10/src/producer.js +3 -1
  11. package/packages/datadog-plugin-amqplib/src/client.js +3 -4
  12. package/packages/datadog-plugin-amqplib/src/consumer.js +3 -1
  13. package/packages/datadog-plugin-amqplib/src/producer.js +3 -1
  14. package/packages/datadog-plugin-aws-sdk/src/base.js +3 -0
  15. package/packages/datadog-plugin-aws-sdk/src/services/cloudwatchlogs.js +2 -1
  16. package/packages/datadog-plugin-aws-sdk/src/services/dynamodb.js +4 -2
  17. package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +4 -3
  18. package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +2 -1
  19. package/packages/datadog-plugin-aws-sdk/src/services/lambda.js +1 -0
  20. package/packages/datadog-plugin-aws-sdk/src/services/redshift.js +2 -1
  21. package/packages/datadog-plugin-aws-sdk/src/services/s3.js +2 -1
  22. package/packages/datadog-plugin-aws-sdk/src/services/sns.js +8 -1
  23. package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +7 -1
  24. package/packages/datadog-plugin-google-cloud-pubsub/src/client.js +3 -4
  25. package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +3 -1
  26. package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +3 -1
  27. package/packages/datadog-plugin-http/src/client.js +2 -1
  28. package/packages/datadog-plugin-http2/src/client.js +2 -1
  29. package/packages/datadog-plugin-jest/src/util.js +10 -1
  30. package/packages/datadog-plugin-kafkajs/src/consumer.js +6 -1
  31. package/packages/datadog-plugin-kafkajs/src/producer.js +3 -1
  32. package/packages/datadog-plugin-pg/src/index.js +5 -5
  33. package/packages/datadog-plugin-rhea/src/consumer.js +3 -1
  34. package/packages/datadog-plugin-rhea/src/producer.js +5 -1
  35. package/packages/dd-trace/src/appsec/iast/analyzers/command-injection-analyzer.js +2 -1
  36. package/packages/dd-trace/src/appsec/iast/analyzers/ldap-injection-analyzer.js +2 -1
  37. package/packages/dd-trace/src/appsec/iast/analyzers/path-traversal-analyzer.js +22 -5
  38. package/packages/dd-trace/src/appsec/iast/analyzers/sql-injection-analyzer.js +40 -4
  39. package/packages/dd-trace/src/appsec/iast/analyzers/weak-cipher-analyzer.js +2 -1
  40. package/packages/dd-trace/src/appsec/iast/analyzers/weak-hash-analyzer.js +2 -1
  41. package/packages/dd-trace/src/appsec/iast/index.js +1 -1
  42. package/packages/dd-trace/src/appsec/iast/path-line.js +2 -1
  43. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/range-utils.js +37 -0
  44. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/command-sensitive-analyzer.js +29 -0
  45. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/ldap-sensitive-analyzer.js +35 -0
  46. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/sql-sensitive-analyzer.js +95 -0
  47. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +144 -0
  48. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/index.js +113 -0
  49. package/packages/dd-trace/src/appsec/iast/vulnerabilities.js +8 -0
  50. package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +4 -76
  51. package/packages/dd-trace/src/config.js +59 -25
  52. package/packages/dd-trace/src/constants.js +3 -1
  53. package/packages/dd-trace/src/encode/agentless-ci-visibility.js +14 -4
  54. package/packages/dd-trace/src/git_metadata_tagger.js +17 -0
  55. package/packages/dd-trace/src/git_properties.js +32 -0
  56. package/packages/dd-trace/src/plugin_manager.js +0 -2
  57. package/packages/dd-trace/src/plugins/client.js +2 -3
  58. package/packages/dd-trace/src/plugins/consumer.js +2 -17
  59. package/packages/dd-trace/src/plugins/incoming.js +7 -0
  60. package/packages/dd-trace/src/plugins/{outbound.js → outgoing.js} +2 -2
  61. package/packages/dd-trace/src/plugins/producer.js +2 -17
  62. package/packages/dd-trace/src/plugins/server.js +2 -2
  63. package/packages/dd-trace/src/plugins/tracing.js +0 -11
  64. package/packages/dd-trace/src/plugins/util/ci.js +62 -7
  65. package/packages/dd-trace/src/plugins/util/tags.js +5 -1
  66. package/packages/dd-trace/src/plugins/util/test.js +34 -17
  67. package/packages/dd-trace/src/profiling/constants.js +0 -1
  68. package/packages/dd-trace/src/profiling/profilers/space.js +1 -3
  69. package/packages/dd-trace/src/proxy.js +4 -0
  70. package/packages/dd-trace/src/serverless.js +25 -0
  71. package/packages/dd-trace/src/span_processor.js +3 -0
  72. package/packages/dd-trace/src/telemetry/send-data.js +13 -3
  73. package/packages/dd-trace/src/tracer.js +3 -2
  74. package/version.js +9 -0
  75. package/packages/dd-trace/src/plugins/inbound.js +0 -7
  76. package/packages/dd-trace/src/service-naming/index.js +0 -41
  77. package/packages/dd-trace/src/service-naming/schemas/definition.js +0 -28
  78. package/packages/dd-trace/src/service-naming/schemas/index.js +0 -6
  79. package/packages/dd-trace/src/service-naming/schemas/v0.js +0 -66
  80. package/packages/dd-trace/src/service-naming/schemas/v1.js +0 -58
@@ -1,5 +1,6 @@
1
1
  const { MANUAL_KEEP } = require('../../../../../ext/tags')
2
2
  const LRU = require('lru-cache')
3
+ const vulnerabilitiesFormatter = require('./vulnerabilities-formatter')
3
4
  const VULNERABILITIES_KEY = 'vulnerabilities'
4
5
  const IAST_JSON_TAG_KEY = '_dd.iast.json'
5
6
  const VULNERABILITY_HASHES_MAX_SIZE = 1000
@@ -60,57 +61,6 @@ function isValidVulnerability (vulnerability) {
60
61
  vulnerability.location && vulnerability.location.spanId
61
62
  }
62
63
 
63
- function formatEvidence (evidence, sourcesIndexes) {
64
- if (!evidence.ranges) {
65
- return { value: evidence.value }
66
- }
67
-
68
- const valueParts = []
69
- let fromIndex = 0
70
- evidence.ranges.forEach((range, rangeIndex) => {
71
- if (fromIndex < range.start) {
72
- valueParts.push({ value: evidence.value.substring(fromIndex, range.start) })
73
- }
74
- valueParts.push({ value: evidence.value.substring(range.start, range.end), source: sourcesIndexes[rangeIndex] })
75
- fromIndex = range.end
76
- })
77
- if (fromIndex < evidence.value.length) {
78
- valueParts.push({ value: evidence.value.substring(fromIndex) })
79
- }
80
- return { valueParts }
81
- }
82
-
83
- function extractSourcesFromVulnerability (vulnerability) {
84
- if (!vulnerability.evidence.ranges) {
85
- return []
86
- }
87
- return vulnerability.evidence.ranges.map(range => (
88
- {
89
- origin: range.iinfo.type,
90
- name: range.iinfo.parameterName,
91
- value: range.iinfo.parameterValue
92
- }
93
- ))
94
- }
95
-
96
- function jsonVulnerabilityFromVulnerability (vulnerability, sourcesIndexes) {
97
- const jsonVulnerability = {
98
- type: vulnerability.type,
99
- hash: vulnerability.hash,
100
- evidence: formatEvidence(vulnerability.evidence, sourcesIndexes),
101
- location: {
102
- spanId: vulnerability.location.spanId
103
- }
104
- }
105
- if (vulnerability.location.path) {
106
- jsonVulnerability.location.path = vulnerability.location.path
107
- }
108
- if (vulnerability.location.line) {
109
- jsonVulnerability.location.line = vulnerability.location.line
110
- }
111
- return jsonVulnerability
112
- }
113
-
114
64
  function sendVulnerabilities (vulnerabilities, rootSpan) {
115
65
  if (vulnerabilities && vulnerabilities.length) {
116
66
  let span = rootSpan
@@ -124,31 +74,8 @@ function sendVulnerabilities (vulnerabilities, rootSpan) {
124
74
  }
125
75
 
126
76
  if (span && span.addTags) {
127
- const jsonToSend = {
128
- sources: [],
129
- vulnerabilities: []
130
- }
131
-
132
- deduplicateVulnerabilities(vulnerabilities).forEach((vulnerability) => {
133
- if (isValidVulnerability(vulnerability)) {
134
- const sourcesIndexes = []
135
- const vulnerabilitySources = extractSourcesFromVulnerability(vulnerability)
136
- vulnerabilitySources.forEach((source) => {
137
- let sourceIndex = jsonToSend.sources.findIndex(
138
- existingSource =>
139
- existingSource.origin === source.origin &&
140
- existingSource.name === source.name &&
141
- existingSource.value === source.value
142
- )
143
- if (sourceIndex === -1) {
144
- sourceIndex = jsonToSend.sources.length
145
- jsonToSend.sources.push(source)
146
- }
147
- sourcesIndexes.push(sourceIndex)
148
- })
149
- jsonToSend.vulnerabilities.push(jsonVulnerabilityFromVulnerability(vulnerability, sourcesIndexes))
150
- }
151
- })
77
+ const validAndDedupVulnerabilities = deduplicateVulnerabilities(vulnerabilities).filter(isValidVulnerability)
78
+ const jsonToSend = vulnerabilitiesFormatter.toJson(validAndDedupVulnerabilities)
152
79
 
153
80
  if (jsonToSend.vulnerabilities.length > 0) {
154
81
  const tags = {}
@@ -194,6 +121,7 @@ function deduplicateVulnerabilities (vulnerabilities) {
194
121
 
195
122
  function start (config, _tracer) {
196
123
  deduplicationEnabled = config.iast.deduplicationEnabled
124
+ vulnerabilitiesFormatter.setRedactVulnerabilities(config.iast.redactionEnabled)
197
125
  if (deduplicationEnabled) {
198
126
  startClearCacheTimer()
199
127
  }
@@ -2,13 +2,15 @@
2
2
 
3
3
  const fs = require('fs')
4
4
  const os = require('os')
5
+ const uuid = require('crypto-randomuuid')
5
6
  const URL = require('url').URL
6
7
  const log = require('./log')
7
8
  const pkg = require('./pkg')
8
9
  const coalesce = require('koalas')
9
10
  const tagger = require('./tagger')
10
11
  const { isTrue, isFalse } = require('./util')
11
- const uuid = require('crypto-randomuuid')
12
+ const { GIT_REPOSITORY_URL, GIT_COMMIT_SHA } = require('./plugins/util/tags')
13
+ const { getGitMetadataFromGitProperties } = require('./git_properties')
12
14
 
13
15
  const fromEntries = Object.fromEntries || (entries =>
14
16
  entries.reduce((obj, [k, v]) => Object.assign(obj, { [k]: v }), {}))
@@ -31,19 +33,6 @@ function safeJsonParse (input) {
31
33
  }
32
34
  }
33
35
 
34
- const namingVersions = ['v0', 'v1']
35
- const defaultVersion = 'v0'
36
-
37
- function validateNamingVersion (versionString) {
38
- if (!namingVersions.includes(versionString)) {
39
- log.warn(
40
- `Unexpected input for config.spanAttributeSchema, picked default ${defaultVersion}`
41
- )
42
- return defaultVersion
43
- }
44
- return versionString
45
- }
46
-
47
36
  // Shallow clone with property name remapping
48
37
  function remapify (input, mappings) {
49
38
  if (!input) return
@@ -169,6 +158,8 @@ class Config {
169
158
  process.env.DD_SERVICE_NAME ||
170
159
  this.tags.service ||
171
160
  process.env.AWS_LAMBDA_FUNCTION_NAME ||
161
+ process.env.FUNCTION_NAME || // Google Cloud Function Name set by deprecated runtimes
162
+ process.env.K_SERVICE || // Google Cloud Function Name set by newer runtimes
172
163
  pkg.name ||
173
164
  'node'
174
165
  const DD_SERVICE_MAPPING = coalesce(
@@ -193,9 +184,18 @@ class Config {
193
184
  process.env.DD_TRACE_STARTUP_LOGS,
194
185
  false
195
186
  )
187
+
188
+ const inAWSLambda = process.env.AWS_LAMBDA_FUNCTION_NAME !== undefined
189
+
190
+ const isDeprecatedGCPFunction = process.env.FUNCTION_NAME !== undefined && process.env.GCP_PROJECT !== undefined
191
+ const isNewerGCPFunction = process.env.K_SERVICE !== undefined && process.env.FUNCTION_TARGET !== undefined
192
+ const isGCPFunction = isDeprecatedGCPFunction || isNewerGCPFunction
193
+
194
+ const inServerlessEnvironment = inAWSLambda || isGCPFunction
195
+
196
196
  const DD_TRACE_TELEMETRY_ENABLED = coalesce(
197
197
  process.env.DD_TRACE_TELEMETRY_ENABLED,
198
- !process.env.AWS_LAMBDA_FUNCTION_NAME
198
+ !inServerlessEnvironment
199
199
  )
200
200
  const DD_TELEMETRY_DEBUG_ENABLED = coalesce(
201
201
  process.env.DD_TELEMETRY_DEBUG_ENABLED,
@@ -270,9 +270,7 @@ class Config {
270
270
  process.env.DD_TRACE_EXPERIMENTAL_GET_RUM_DATA_ENABLED,
271
271
  false
272
272
  )
273
- const DD_TRACE_SPAN_ATTRIBUTE_SCHEMA = validateNamingVersion(
274
- process.env.DD_TRACE_SPAN_ATTRIBUTE_SCHEMA
275
- )
273
+
276
274
  const DD_TRACE_X_DATADOG_TAGS_MAX_LENGTH = coalesce(
277
275
  process.env.DD_TRACE_X_DATADOG_TAGS_MAX_LENGTH,
278
276
  '512'
@@ -281,7 +279,7 @@ class Config {
281
279
  const DD_TRACE_STATS_COMPUTATION_ENABLED = coalesce(
282
280
  options.stats,
283
281
  process.env.DD_TRACE_STATS_COMPUTATION_ENABLED,
284
- false
282
+ isGCPFunction
285
283
  )
286
284
 
287
285
  const DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED = coalesce(
@@ -348,12 +346,10 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
348
346
  maybeFile(process.env.DD_APPSEC_HTTP_BLOCKED_TEMPLATE_JSON)
349
347
  )
350
348
 
351
- const inAWSLambda = process.env.AWS_LAMBDA_FUNCTION_NAME !== undefined
352
-
353
349
  const remoteConfigOptions = options.remoteConfig || {}
354
350
  const DD_REMOTE_CONFIGURATION_ENABLED = coalesce(
355
351
  process.env.DD_REMOTE_CONFIGURATION_ENABLED && isTrue(process.env.DD_REMOTE_CONFIGURATION_ENABLED),
356
- !inAWSLambda
352
+ !inServerlessEnvironment
357
353
  )
358
354
  const DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS = coalesce(
359
355
  parseInt(remoteConfigOptions.pollInterval),
@@ -400,11 +396,22 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
400
396
  true
401
397
  )
402
398
 
399
+ const DD_IAST_REDACTION_ENABLED = coalesce(
400
+ iastOptions && iastOptions.redactionEnabled,
401
+ !isFalse(process.env.DD_IAST_REDACTION_ENABLED),
402
+ true
403
+ )
404
+
403
405
  const DD_CIVISIBILITY_GIT_UPLOAD_ENABLED = coalesce(
404
406
  process.env.DD_CIVISIBILITY_GIT_UPLOAD_ENABLED,
405
407
  true
406
408
  )
407
409
 
410
+ const DD_TRACE_GIT_METADATA_ENABLED = coalesce(
411
+ process.env.DD_TRACE_GIT_METADATA_ENABLED,
412
+ true
413
+ )
414
+
408
415
  const ingestion = options.ingestion || {}
409
416
  const dogstatsd = coalesce(options.dogstatsd, {})
410
417
  const sampler = {
@@ -436,7 +443,7 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
436
443
  })
437
444
  }
438
445
 
439
- const defaultFlushInterval = inAWSLambda ? 0 : 2000
446
+ const defaultFlushInterval = inServerlessEnvironment ? 0 : 2000
440
447
 
441
448
  this.tracing = !isFalse(DD_TRACING_ENABLED)
442
449
  this.dbmPropagationMode = DD_DBM_PROPAGATION_MODE
@@ -479,7 +486,6 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
479
486
  sourceMap: !isFalse(DD_PROFILING_SOURCE_MAP),
480
487
  exporters: DD_PROFILING_EXPORTERS
481
488
  }
482
- this.spanAttributeSchema = DD_TRACE_SPAN_ATTRIBUTE_SCHEMA
483
489
  this.lookup = options.lookup
484
490
  this.startupLogs = isTrue(DD_TRACE_STARTUP_LOGS)
485
491
  // Disabled for CI Visibility's agentless
@@ -510,7 +516,8 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
510
516
  requestSampling: DD_IAST_REQUEST_SAMPLING,
511
517
  maxConcurrentRequests: DD_IAST_MAX_CONCURRENT_REQUESTS,
512
518
  maxContextOperations: DD_IAST_MAX_CONTEXT_OPERATIONS,
513
- deduplicationEnabled: DD_IAST_DEDUPLICATION_ENABLED
519
+ deduplicationEnabled: DD_IAST_DEDUPLICATION_ENABLED,
520
+ redactionEnabled: DD_IAST_REDACTION_ENABLED
514
521
  }
515
522
 
516
523
  this.isCiVisibility = isTrue(DD_IS_CIVISIBILITY)
@@ -519,6 +526,31 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
519
526
  this.isGitUploadEnabled = this.isCiVisibility &&
520
527
  (this.isIntelligentTestRunnerEnabled && !isFalse(DD_CIVISIBILITY_GIT_UPLOAD_ENABLED))
521
528
 
529
+ this.gitMetadataEnabled = isTrue(DD_TRACE_GIT_METADATA_ENABLED)
530
+
531
+ if (this.gitMetadataEnabled) {
532
+ this.repositoryUrl = coalesce(
533
+ process.env.DD_GIT_REPOSITORY_URL,
534
+ this.tags[GIT_REPOSITORY_URL]
535
+ )
536
+ this.commitSHA = coalesce(
537
+ process.env.DD_GIT_COMMIT_SHA,
538
+ this.tags[GIT_COMMIT_SHA]
539
+ )
540
+ if (!this.repositoryUrl || !this.commitSHA) {
541
+ const DD_GIT_PROPERTIES_FILE = coalesce(
542
+ process.env.DD_GIT_PROPERTIES_FILE,
543
+ `${process.cwd()}/git.properties`
544
+ )
545
+ const gitPropertiesString = maybeFile(DD_GIT_PROPERTIES_FILE)
546
+ if (gitPropertiesString) {
547
+ const { commitSHA, repositoryUrl } = getGitMetadataFromGitProperties(gitPropertiesString)
548
+ this.commitSHA = this.commitSHA || commitSHA
549
+ this.repositoryUrl = this.repositoryUrl || repositoryUrl
550
+ }
551
+ }
552
+ }
553
+
522
554
  this.stats = {
523
555
  enabled: isTrue(DD_TRACE_STATS_COMPUTATION_ENABLED)
524
556
  }
@@ -526,6 +558,8 @@ ken|consumer_?(?:id|key|secret)|sign(?:ed|ature)?|auth(?:entication|orization)?)
526
558
  this.traceId128BitGenerationEnabled = isTrue(DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED)
527
559
  this.traceId128BitLoggingEnabled = isTrue(DD_TRACE_128_BIT_TRACEID_LOGGING_ENABLED)
528
560
 
561
+ this.isGCPFunction = isGCPFunction
562
+
529
563
  tagger.add(this.tags, {
530
564
  service: this.service,
531
565
  env: this.env,
@@ -25,5 +25,7 @@ module.exports = {
25
25
  ERROR_MESSAGE: 'error.message',
26
26
  ERROR_STACK: 'error.stack',
27
27
  COMPONENT: 'component',
28
- CLIENT_PORT_KEY: 'network.destination.port'
28
+ CLIENT_PORT_KEY: 'network.destination.port',
29
+ SCI_REPOSITORY_URL: '_dd.git.repository_url',
30
+ SCI_COMMIT_SHA: '_dd.git.commit.sha'
29
31
  }
@@ -129,12 +129,17 @@ class AgentlessCiVisibilityEncoder extends AgentEncoder {
129
129
  _encodeEventContent (bytes, content) {
130
130
  const keysLength = Object.keys(content).length
131
131
 
132
+ let totalKeysLength = keysLength
132
133
  if (content.meta.test_session_id) {
133
- this._encodeMapPrefix(bytes, keysLength + 3)
134
- } else {
135
- this._encodeMapPrefix(bytes, keysLength)
134
+ totalKeysLength = totalKeysLength + 1
136
135
  }
137
-
136
+ if (content.meta.test_module_id) {
137
+ totalKeysLength = totalKeysLength + 1
138
+ }
139
+ if (content.meta.test_suite_id) {
140
+ totalKeysLength = totalKeysLength + 1
141
+ }
142
+ this._encodeMapPrefix(bytes, totalKeysLength)
138
143
  if (content.type) {
139
144
  this._encodeString(bytes, 'type')
140
145
  this._encodeString(bytes, content.type)
@@ -170,15 +175,20 @@ class AgentlessCiVisibilityEncoder extends AgentEncoder {
170
175
  this._encodeString(bytes, 'test_session_id')
171
176
  this._encodeId(bytes, id(content.meta.test_session_id, 10))
172
177
  delete content.meta.test_session_id
178
+ }
173
179
 
180
+ if (content.meta.test_module_id) {
174
181
  this._encodeString(bytes, 'test_module_id')
175
182
  this._encodeId(bytes, id(content.meta.test_module_id, 10))
176
183
  delete content.meta.test_module_id
184
+ }
177
185
 
186
+ if (content.meta.test_suite_id) {
178
187
  this._encodeString(bytes, 'test_suite_id')
179
188
  this._encodeId(bytes, id(content.meta.test_suite_id, 10))
180
189
  delete content.meta.test_suite_id
181
190
  }
191
+
182
192
  this._encodeString(bytes, 'meta')
183
193
  this._encodeMap(bytes, content.meta)
184
194
  this._encodeString(bytes, 'metrics')
@@ -0,0 +1,17 @@
1
+ const { SCI_COMMIT_SHA, SCI_REPOSITORY_URL } = require('./constants')
2
+
3
+ class GitMetadataTagger {
4
+ constructor (config) {
5
+ this._config = config
6
+ }
7
+
8
+ tagGitMetadata (spanContext) {
9
+ if (this._config.gitMetadataEnabled) {
10
+ // These tags are added only to the local root span
11
+ spanContext._trace.tags[SCI_COMMIT_SHA] = this._config.commitSHA
12
+ spanContext._trace.tags[SCI_REPOSITORY_URL] = this._config.repositoryUrl
13
+ }
14
+ }
15
+ }
16
+
17
+ module.exports = GitMetadataTagger
@@ -0,0 +1,32 @@
1
+ const commitSHARegex = /git\.commit\.sha=([a-f\d]{40})/
2
+ const repositoryUrlRegex = /git\.repository_url=([\w\d:@/.-]+)/
3
+
4
+ function getGitMetadataFromGitProperties (gitPropertiesString) {
5
+ if (!gitPropertiesString) {
6
+ return {}
7
+ }
8
+ const commitSHAMatch = gitPropertiesString.match(commitSHARegex)
9
+ const repositoryUrlMatch = gitPropertiesString.match(repositoryUrlRegex)
10
+
11
+ const repositoryUrl = repositoryUrlMatch ? repositoryUrlMatch[1] : undefined
12
+ let parsedUrl = repositoryUrl
13
+
14
+ if (repositoryUrl) {
15
+ try {
16
+ // repository URLs can contain username and password, so we want to filter those out
17
+ parsedUrl = new URL(repositoryUrl)
18
+ if (parsedUrl.password) {
19
+ parsedUrl = `${parsedUrl.origin}${parsedUrl.pathname}`
20
+ }
21
+ } catch (e) {
22
+ // if protocol isn't https, no password will be used
23
+ }
24
+ }
25
+
26
+ return {
27
+ commitSHA: commitSHAMatch ? commitSHAMatch[1] : undefined,
28
+ repositoryUrl: parsedUrl
29
+ }
30
+ }
31
+
32
+ module.exports = { getGitMetadataFromGitProperties }
@@ -4,7 +4,6 @@ const { channel } = require('../../diagnostics_channel')
4
4
  const { isFalse } = require('./util')
5
5
  const plugins = require('./plugins')
6
6
  const log = require('./log')
7
- const Nomenclature = require('./service-naming')
8
7
 
9
8
  const loadChannel = channel('dd-trace:instrumentation:load')
10
9
 
@@ -97,7 +96,6 @@ module.exports = class PluginManager {
97
96
  // like instrumenter.enable()
98
97
  configure (config = {}) {
99
98
  this._tracerConfig = config
100
- Nomenclature.configure(config)
101
99
 
102
100
  for (const name in pluginClasses) {
103
101
  this.loadPlugin(name)
@@ -1,10 +1,9 @@
1
1
  'use strict'
2
2
 
3
- const OutboundPlugin = require('./outbound')
3
+ const OutgoingPlugin = require('./outgoing')
4
4
 
5
- class ClientPlugin extends OutboundPlugin {
5
+ class ClientPlugin extends OutgoingPlugin {
6
6
  static get operation () { return 'request' }
7
- static get kind () { return 'client' }
8
7
  }
9
8
 
10
9
  module.exports = ClientPlugin
@@ -1,24 +1,9 @@
1
1
  'use strict'
2
2
 
3
- const InboundPlugin = require('./inbound')
3
+ const IncomingPlugin = require('./incoming')
4
4
 
5
- class ConsumerPlugin extends InboundPlugin {
5
+ class ConsumerPlugin extends IncomingPlugin {
6
6
  static get operation () { return 'receive' }
7
- static get kind () { return 'consumer' }
8
- static get type () { return 'messaging' }
9
-
10
- startSpan (options) {
11
- const spanDefaults = {
12
- service: this.config.service || this.serviceName(),
13
- kind: this.constructor.kind
14
- }
15
- Object.keys(spanDefaults).forEach(
16
- key => {
17
- if (!options[key]) options[key] = spanDefaults[key]
18
- }
19
- )
20
- return super.startSpan(this.operationName(), options)
21
- }
22
7
  }
23
8
 
24
9
  module.exports = ConsumerPlugin
@@ -0,0 +1,7 @@
1
+ 'use strict'
2
+
3
+ const TracingPlugin = require('./tracing')
4
+
5
+ class IncomingPlugin extends TracingPlugin {}
6
+
7
+ module.exports = IncomingPlugin
@@ -4,7 +4,7 @@ const { CLIENT_PORT_KEY } = require('../constants')
4
4
  const TracingPlugin = require('./tracing')
5
5
 
6
6
  // TODO: Exit span on finish when AsyncResource instances are removed.
7
- class OutboundPlugin extends TracingPlugin {
7
+ class OutgoingPlugin extends TracingPlugin {
8
8
  constructor (...args) {
9
9
  super(...args)
10
10
 
@@ -29,4 +29,4 @@ class OutboundPlugin extends TracingPlugin {
29
29
  }
30
30
  }
31
31
 
32
- module.exports = OutboundPlugin
32
+ module.exports = OutgoingPlugin
@@ -1,24 +1,9 @@
1
1
  'use strict'
2
2
 
3
- const OutboundPlugin = require('./outbound')
3
+ const OutgoingPlugin = require('./outgoing')
4
4
 
5
- class ProducerPlugin extends OutboundPlugin {
5
+ class ProducerPlugin extends OutgoingPlugin {
6
6
  static get operation () { return 'publish' }
7
- static get kind () { return 'producer' }
8
- static get type () { return 'messaging' }
9
-
10
- startSpan (options) {
11
- const spanDefaults = {
12
- service: this.config.service || this.serviceName(),
13
- kind: this.constructor.kind
14
- }
15
- Object.keys(spanDefaults).forEach(
16
- key => {
17
- if (!options[key]) options[key] = spanDefaults[key]
18
- }
19
- )
20
- return super.startSpan(this.operationName(), options)
21
- }
22
7
  }
23
8
 
24
9
  module.exports = ProducerPlugin
@@ -1,8 +1,8 @@
1
1
  'use strict'
2
2
 
3
- const InboundPlugin = require('./inbound')
3
+ const IncomingPlugin = require('./incoming')
4
4
 
5
- class ServerPlugin extends InboundPlugin {
5
+ class ServerPlugin extends IncomingPlugin {
6
6
  static get operation () { return 'request' }
7
7
  }
8
8
 
@@ -4,7 +4,6 @@ const Plugin = require('./plugin')
4
4
  const { storage } = require('../../../datadog-core')
5
5
  const analyticsSampler = require('../analytics_sampler')
6
6
  const { COMPONENT } = require('../constants')
7
- const Nomenclature = require('../service-naming')
8
7
 
9
8
  class TracingPlugin extends Plugin {
10
9
  constructor (...args) {
@@ -32,16 +31,6 @@ class TracingPlugin extends Plugin {
32
31
  return store && store.span
33
32
  }
34
33
 
35
- serviceName (serviceArgs) {
36
- const { type, id, kind } = this.constructor
37
- return Nomenclature.serviceName(type, kind, id, serviceArgs)
38
- }
39
-
40
- operationName (opNameArgs) {
41
- const { type, id, kind } = this.constructor
42
- return Nomenclature.opName(type, kind, id, opNameArgs)
43
- }
44
-
45
34
  configure (config) {
46
35
  return super.configure({
47
36
  ...config,
@@ -20,7 +20,9 @@ const {
20
20
  CI_STAGE_NAME,
21
21
  CI_ENV_VARS,
22
22
  GIT_COMMIT_COMMITTER_NAME,
23
- GIT_COMMIT_COMMITTER_EMAIL
23
+ GIT_COMMIT_COMMITTER_EMAIL,
24
+ CI_NODE_LABELS,
25
+ CI_NODE_NAME
24
26
  } = require('./tags')
25
27
 
26
28
  // Receives a string with the form 'John Doe <john.doe@gmail.com>'
@@ -108,7 +110,9 @@ module.exports = {
108
110
  GIT_COMMIT: JENKINS_GIT_COMMIT,
109
111
  GIT_URL: JENKINS_GIT_REPOSITORY_URL,
110
112
  GIT_URL_1: JENKINS_GIT_REPOSITORY_URL_1,
111
- DD_CUSTOM_TRACE_ID
113
+ DD_CUSTOM_TRACE_ID,
114
+ NODE_NAME,
115
+ NODE_LABELS
112
116
  } = env
113
117
 
114
118
  tags = {
@@ -119,7 +123,18 @@ module.exports = {
119
123
  [GIT_COMMIT_SHA]: JENKINS_GIT_COMMIT,
120
124
  [GIT_REPOSITORY_URL]: JENKINS_GIT_REPOSITORY_URL || JENKINS_GIT_REPOSITORY_URL_1,
121
125
  [CI_WORKSPACE_PATH]: WORKSPACE,
122
- [CI_ENV_VARS]: JSON.stringify({ DD_CUSTOM_TRACE_ID })
126
+ [CI_ENV_VARS]: JSON.stringify({ DD_CUSTOM_TRACE_ID }),
127
+ [CI_NODE_NAME]: NODE_NAME
128
+ }
129
+
130
+ if (NODE_LABELS) {
131
+ let nodeLabels
132
+ try {
133
+ nodeLabels = JSON.stringify(NODE_LABELS.split(' '))
134
+ tags[CI_NODE_LABELS] = nodeLabels
135
+ } catch (e) {
136
+ // ignore errors
137
+ }
123
138
  }
124
139
 
125
140
  const isTag = JENKINS_GIT_BRANCH && JENKINS_GIT_BRANCH.includes('tags/')
@@ -159,7 +174,9 @@ module.exports = {
159
174
  CI_COMMIT_TIMESTAMP,
160
175
  CI_COMMIT_AUTHOR,
161
176
  CI_PROJECT_URL: GITLAB_PROJECT_URL,
162
- CI_JOB_ID: GITLAB_CI_JOB_ID
177
+ CI_JOB_ID: GITLAB_CI_JOB_ID,
178
+ CI_RUNNER_ID,
179
+ CI_RUNNER_TAGS
163
180
  } = env
164
181
 
165
182
  const { name, email } = parseEmailAndName(CI_COMMIT_AUTHOR)
@@ -186,7 +203,9 @@ module.exports = {
186
203
  CI_PROJECT_URL: GITLAB_PROJECT_URL,
187
204
  CI_PIPELINE_ID: GITLAB_PIPELINE_ID,
188
205
  CI_JOB_ID: GITLAB_CI_JOB_ID
189
- })
206
+ }),
207
+ [CI_NODE_LABELS]: CI_RUNNER_TAGS,
208
+ [CI_NODE_NAME]: CI_RUNNER_ID
190
209
  }
191
210
  }
192
211
 
@@ -448,9 +467,17 @@ module.exports = {
448
467
  BUILDKITE_BUILD_CHECKOUT_PATH,
449
468
  BUILDKITE_BUILD_AUTHOR,
450
469
  BUILDKITE_BUILD_AUTHOR_EMAIL,
451
- BUILDKITE_MESSAGE
470
+ BUILDKITE_MESSAGE,
471
+ BUILDKITE_AGENT_ID
452
472
  } = env
453
473
 
474
+ const extraTags = Object.keys(env).filter(envVar =>
475
+ envVar.startsWith('BUILDKITE_AGENT_META_DATA_')
476
+ ).map((metadataKey) => {
477
+ const key = metadataKey.replace('BUILDKITE_AGENT_META_DATA_', '').toLowerCase()
478
+ return `${key}:${env[metadataKey]}`
479
+ })
480
+
454
481
  tags = {
455
482
  [CI_PROVIDER_NAME]: 'buildkite',
456
483
  [CI_PIPELINE_ID]: BUILDKITE_BUILD_ID,
@@ -469,7 +496,9 @@ module.exports = {
469
496
  [CI_ENV_VARS]: JSON.stringify({
470
497
  BUILDKITE_BUILD_ID,
471
498
  BUILDKITE_JOB_ID
472
- })
499
+ }),
500
+ [CI_NODE_NAME]: BUILDKITE_AGENT_ID,
501
+ [CI_NODE_LABELS]: JSON.stringify(extraTags)
473
502
  }
474
503
  }
475
504
 
@@ -546,6 +575,32 @@ module.exports = {
546
575
  }
547
576
  }
548
577
 
578
+ if (env.CF_BUILD_ID) {
579
+ const {
580
+ CF_BUILD_ID,
581
+ CF_PIPELINE_NAME,
582
+ CF_BUILD_URL,
583
+ CF_STEP_NAME,
584
+ CF_BRANCH
585
+ } = env
586
+ tags = {
587
+ [CI_PROVIDER_NAME]: 'codefresh',
588
+ [CI_PIPELINE_ID]: CF_BUILD_ID,
589
+ [CI_PIPELINE_NAME]: CF_PIPELINE_NAME,
590
+ [CI_PIPELINE_URL]: CF_BUILD_URL,
591
+ [CI_JOB_NAME]: CF_STEP_NAME,
592
+ [CI_ENV_VARS]: JSON.stringify({
593
+ CF_BUILD_ID
594
+ })
595
+ }
596
+
597
+ const isTag = CF_BRANCH && CF_BRANCH.includes('tags/')
598
+ const refKey = isTag ? GIT_TAG : GIT_BRANCH
599
+ const ref = normalizeRef(CF_BRANCH)
600
+
601
+ tags[refKey] = ref
602
+ }
603
+
549
604
  normalizeTag(tags, CI_WORKSPACE_PATH, resolveTilde)
550
605
  normalizeTag(tags, GIT_REPOSITORY_URL, filterSensitiveInfoFromRepository)
551
606
  normalizeTag(tags, GIT_BRANCH, normalizeRef)
@@ -19,6 +19,8 @@ const CI_WORKSPACE_PATH = 'ci.workspace_path'
19
19
  const CI_JOB_URL = 'ci.job.url'
20
20
  const CI_JOB_NAME = 'ci.job.name'
21
21
  const CI_STAGE_NAME = 'ci.stage.name'
22
+ const CI_NODE_NAME = 'ci.node.name'
23
+ const CI_NODE_LABELS = 'ci.node.labels'
22
24
 
23
25
  const CI_ENV_VARS = '_dd.ci.env_vars'
24
26
 
@@ -43,5 +45,7 @@ module.exports = {
43
45
  CI_JOB_URL,
44
46
  CI_JOB_NAME,
45
47
  CI_STAGE_NAME,
46
- CI_ENV_VARS
48
+ CI_ENV_VARS,
49
+ CI_NODE_NAME,
50
+ CI_NODE_LABELS
47
51
  }