dd-trace 5.70.0 → 5.72.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/LICENSE-3rdparty.csv +5 -0
- package/index.d.ts +110 -1
- package/initialize.mjs +7 -1
- package/package.json +21 -2
- package/packages/datadog-instrumentations/src/anthropic.js +115 -0
- package/packages/datadog-instrumentations/src/azure-event-hubs.js +37 -0
- package/packages/datadog-instrumentations/src/azure-functions.js +3 -0
- package/packages/datadog-instrumentations/src/cucumber.js +7 -7
- package/packages/datadog-instrumentations/src/helpers/hooks.js +2 -0
- package/packages/datadog-instrumentations/src/jest.js +29 -36
- package/packages/datadog-instrumentations/src/mocha/main.js +8 -9
- package/packages/datadog-instrumentations/src/mocha/utils.js +1 -1
- package/packages/datadog-instrumentations/src/mocha/worker.js +2 -2
- package/packages/datadog-instrumentations/src/pg.js +1 -1
- package/packages/datadog-instrumentations/src/playwright.js +5 -5
- package/packages/datadog-instrumentations/src/vitest.js +8 -8
- package/packages/datadog-plugin-anthropic/src/index.js +17 -0
- package/packages/datadog-plugin-anthropic/src/tracing.js +30 -0
- package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/utils.js +73 -27
- package/packages/datadog-plugin-azure-event-hubs/src/index.js +15 -0
- package/packages/datadog-plugin-azure-event-hubs/src/producer.js +82 -0
- package/packages/datadog-plugin-azure-functions/src/index.js +37 -0
- package/packages/datadog-plugin-cucumber/src/index.js +3 -3
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +9 -9
- package/packages/datadog-plugin-jest/src/util.js +10 -2
- package/packages/datadog-plugin-mocha/src/index.js +2 -2
- package/packages/datadog-plugin-playwright/src/index.js +2 -2
- package/packages/datadog-plugin-vitest/src/index.js +2 -2
- package/packages/datadog-plugin-ws/src/server.js +5 -3
- package/packages/dd-trace/src/appsec/reporter.js +70 -21
- package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +1 -1
- package/packages/dd-trace/src/config.js +110 -26
- package/packages/dd-trace/src/config_defaults.js +14 -0
- package/packages/dd-trace/src/git_properties.js +90 -5
- package/packages/dd-trace/src/llmobs/plugins/anthropic.js +282 -0
- package/packages/dd-trace/src/llmobs/tagger.js +35 -0
- package/packages/dd-trace/src/noop/proxy.js +3 -0
- package/packages/dd-trace/src/openfeature/constants/constants.js +51 -0
- package/packages/dd-trace/src/openfeature/flagging_provider.js +45 -0
- package/packages/dd-trace/src/openfeature/index.js +77 -0
- package/packages/dd-trace/src/openfeature/noop.js +101 -0
- package/packages/dd-trace/src/openfeature/writers/base.js +181 -0
- package/packages/dd-trace/src/openfeature/writers/exposures.js +173 -0
- package/packages/dd-trace/src/openfeature/writers/util.js +43 -0
- package/packages/dd-trace/src/opentelemetry/logs/batch_log_processor.js +100 -0
- package/packages/dd-trace/src/opentelemetry/logs/index.js +87 -0
- package/packages/dd-trace/src/opentelemetry/logs/logger.js +77 -0
- package/packages/dd-trace/src/opentelemetry/logs/logger_provider.js +126 -0
- package/packages/dd-trace/src/opentelemetry/logs/otlp_http_log_exporter.js +173 -0
- package/packages/dd-trace/src/opentelemetry/logs/otlp_transformer.js +367 -0
- package/packages/dd-trace/src/opentelemetry/protos/common.proto +116 -0
- package/packages/dd-trace/src/opentelemetry/protos/logs.proto +226 -0
- package/packages/dd-trace/src/opentelemetry/protos/logs_service.proto +78 -0
- package/packages/dd-trace/src/opentelemetry/protos/protobuf_loader.js +48 -0
- package/packages/dd-trace/src/opentelemetry/protos/resource.proto +45 -0
- package/packages/dd-trace/src/plugins/ci_plugin.js +7 -6
- package/packages/dd-trace/src/plugins/index.js +2 -0
- package/packages/dd-trace/src/plugins/util/test.js +6 -5
- package/packages/dd-trace/src/profiling/config.js +21 -1
- package/packages/dd-trace/src/profiling/exporters/event_serializer.js +3 -2
- package/packages/dd-trace/src/profiling/profiler.js +44 -22
- package/packages/dd-trace/src/profiling/profilers/events.js +12 -3
- package/packages/dd-trace/src/profiling/profilers/space.js +35 -24
- package/packages/dd-trace/src/profiling/profilers/wall.js +14 -6
- package/packages/dd-trace/src/proxy.js +22 -1
- package/packages/dd-trace/src/remote_config/capabilities.js +2 -0
- package/packages/dd-trace/src/remote_config/index.js +3 -0
- package/packages/dd-trace/src/service-naming/schemas/v0/messaging.js +4 -0
- package/packages/dd-trace/src/service-naming/schemas/v1/messaging.js +8 -0
- package/packages/dd-trace/src/supported-configurations.json +18 -0
- package/packages/dd-trace/src/telemetry/telemetry.js +13 -1
- package/register.js +9 -1
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { SeverityNumber } = require('@opentelemetry/api-logs')
|
|
4
|
+
const { getProtobufTypes } = require('../protos/protobuf_loader')
|
|
5
|
+
const { trace } = require('@opentelemetry/api')
|
|
6
|
+
const log = require('../../log')
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @typedef {import('@opentelemetry/api').Attributes} Attributes
|
|
10
|
+
* @typedef {import('@opentelemetry/api-logs').LogRecord} LogRecord
|
|
11
|
+
* @typedef {import('@opentelemetry/resources').Resource} Resource
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
// Global severity mapping constant - no need to regenerate
|
|
15
|
+
const SEVERITY_MAP = {
|
|
16
|
+
[SeverityNumber.TRACE]: 'SEVERITY_NUMBER_TRACE',
|
|
17
|
+
[SeverityNumber.TRACE2]: 'SEVERITY_NUMBER_TRACE2',
|
|
18
|
+
[SeverityNumber.TRACE3]: 'SEVERITY_NUMBER_TRACE3',
|
|
19
|
+
[SeverityNumber.TRACE4]: 'SEVERITY_NUMBER_TRACE4',
|
|
20
|
+
[SeverityNumber.DEBUG]: 'SEVERITY_NUMBER_DEBUG',
|
|
21
|
+
[SeverityNumber.DEBUG2]: 'SEVERITY_NUMBER_DEBUG2',
|
|
22
|
+
[SeverityNumber.DEBUG3]: 'SEVERITY_NUMBER_DEBUG3',
|
|
23
|
+
[SeverityNumber.DEBUG4]: 'SEVERITY_NUMBER_DEBUG4',
|
|
24
|
+
[SeverityNumber.INFO]: 'SEVERITY_NUMBER_INFO',
|
|
25
|
+
[SeverityNumber.INFO2]: 'SEVERITY_NUMBER_INFO2',
|
|
26
|
+
[SeverityNumber.INFO3]: 'SEVERITY_NUMBER_INFO3',
|
|
27
|
+
[SeverityNumber.INFO4]: 'SEVERITY_NUMBER_INFO4',
|
|
28
|
+
[SeverityNumber.WARN]: 'SEVERITY_NUMBER_WARN',
|
|
29
|
+
[SeverityNumber.WARN2]: 'SEVERITY_NUMBER_WARN2',
|
|
30
|
+
[SeverityNumber.WARN3]: 'SEVERITY_NUMBER_WARN3',
|
|
31
|
+
[SeverityNumber.WARN4]: 'SEVERITY_NUMBER_WARN4',
|
|
32
|
+
[SeverityNumber.ERROR]: 'SEVERITY_NUMBER_ERROR',
|
|
33
|
+
[SeverityNumber.ERROR2]: 'SEVERITY_NUMBER_ERROR2',
|
|
34
|
+
[SeverityNumber.ERROR3]: 'SEVERITY_NUMBER_ERROR3',
|
|
35
|
+
[SeverityNumber.ERROR4]: 'SEVERITY_NUMBER_ERROR4',
|
|
36
|
+
[SeverityNumber.FATAL]: 'SEVERITY_NUMBER_FATAL',
|
|
37
|
+
[SeverityNumber.FATAL2]: 'SEVERITY_NUMBER_FATAL2',
|
|
38
|
+
[SeverityNumber.FATAL3]: 'SEVERITY_NUMBER_FATAL3',
|
|
39
|
+
[SeverityNumber.FATAL4]: 'SEVERITY_NUMBER_FATAL4'
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* OtlpTransformer transforms log records to OTLP format.
|
|
44
|
+
*
|
|
45
|
+
* This implementation follows the OTLP Logs Data Model specification:
|
|
46
|
+
* https://opentelemetry.io/docs/specs/otlp/#log-data-model
|
|
47
|
+
*
|
|
48
|
+
* @class OtlpTransformer
|
|
49
|
+
*/
|
|
50
|
+
class OtlpTransformer {
|
|
51
|
+
#resourceAttributes
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Creates a new OtlpTransformer instance.
|
|
55
|
+
*
|
|
56
|
+
* @param {Attributes} resourceAttributes - Resource attributes
|
|
57
|
+
* @param {string} protocol - OTLP protocol (http/protobuf or http/json)
|
|
58
|
+
*/
|
|
59
|
+
constructor (resourceAttributes, protocol) {
|
|
60
|
+
this.#resourceAttributes = this.#transformAttributes(resourceAttributes)
|
|
61
|
+
if (protocol === 'grpc') {
|
|
62
|
+
log.warn('OTLP gRPC protocol is not supported for logs. ' +
|
|
63
|
+
'Defaulting to http/protobuf. gRPC protobuf support may be added in a future release.')
|
|
64
|
+
protocol = 'http/protobuf'
|
|
65
|
+
}
|
|
66
|
+
this.protocol = protocol
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Transforms log records to OTLP format based on the configured protocol.
|
|
71
|
+
* @param {LogRecord[]} logRecords - Array of enriched log records to transform
|
|
72
|
+
* @returns {Buffer} Transformed log records in the appropriate format
|
|
73
|
+
*/
|
|
74
|
+
transformLogRecords (logRecords) {
|
|
75
|
+
// Use the configured protocol to determine serialization format
|
|
76
|
+
if (this.protocol === 'http/json') {
|
|
77
|
+
return this.#transformToJson(logRecords)
|
|
78
|
+
}
|
|
79
|
+
// Default to protobuf for http/protobuf or any other protocol
|
|
80
|
+
return this.#transformToProtobuf(logRecords)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Groups log records by instrumentation library (name and version).
|
|
85
|
+
* @param {LogRecord[]} logRecords - Array of log records to group
|
|
86
|
+
* @returns {Map<string, LogRecord[]>} Map of instrumentation library key to log records
|
|
87
|
+
* @private
|
|
88
|
+
*/
|
|
89
|
+
#groupByInstrumentationScope (logRecords) {
|
|
90
|
+
const grouped = new Map()
|
|
91
|
+
|
|
92
|
+
for (const record of logRecords) {
|
|
93
|
+
const instrumentationScope = record.instrumentationScope || { name: '', version: '0.0.0', schemaUrl: '' }
|
|
94
|
+
const key = `${instrumentationScope.name}@${instrumentationScope.version}@${instrumentationScope.schemaUrl}`
|
|
95
|
+
|
|
96
|
+
const group = grouped.get(key)
|
|
97
|
+
if (group === undefined) {
|
|
98
|
+
grouped.set(key, [record])
|
|
99
|
+
} else {
|
|
100
|
+
group.push(record)
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return grouped
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Transforms log records to protobuf format.
|
|
108
|
+
* @param {LogRecord[]} logRecords - Array of enriched log records to transform
|
|
109
|
+
* @returns {Buffer} Protobuf-encoded log records
|
|
110
|
+
* @private
|
|
111
|
+
*/
|
|
112
|
+
#transformToProtobuf (logRecords) {
|
|
113
|
+
const { protoLogsService } = getProtobufTypes()
|
|
114
|
+
// Create the OTLP LogsData structure
|
|
115
|
+
const logsData = {
|
|
116
|
+
resourceLogs: [{
|
|
117
|
+
resource: this.#transformResource(),
|
|
118
|
+
scopeLogs: this.#transformScope(logRecords),
|
|
119
|
+
}]
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Serialize to protobuf
|
|
123
|
+
const message = protoLogsService.create(logsData)
|
|
124
|
+
const buffer = protoLogsService.encode(message).finish()
|
|
125
|
+
|
|
126
|
+
return buffer
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Transforms log records to JSON format.
|
|
131
|
+
* @param {LogRecord[]} logRecords - Array of enriched log records to transform
|
|
132
|
+
* @returns {Buffer} JSON-encoded log records
|
|
133
|
+
* @private
|
|
134
|
+
*/
|
|
135
|
+
#transformToJson (logRecords) {
|
|
136
|
+
const logsData = {
|
|
137
|
+
resourceLogs: [{
|
|
138
|
+
resource: this.#transformResource(),
|
|
139
|
+
scopeLogs: this.#transformScope(logRecords)
|
|
140
|
+
}]
|
|
141
|
+
}
|
|
142
|
+
return Buffer.from(JSON.stringify(logsData))
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Creates scope logs grouped by instrumentation library.
|
|
147
|
+
* @param {LogRecord[]} logRecords - Array of log records to transform
|
|
148
|
+
* @returns {Object[]} Array of scope log objects
|
|
149
|
+
* @private
|
|
150
|
+
*/
|
|
151
|
+
#transformScope (logRecords) {
|
|
152
|
+
// Group log records by instrumentation library
|
|
153
|
+
const groupedRecords = this.#groupByInstrumentationScope(logRecords)
|
|
154
|
+
|
|
155
|
+
// Create scope logs for each instrumentation library
|
|
156
|
+
const scopeLogs = []
|
|
157
|
+
|
|
158
|
+
for (const records of groupedRecords.values()) {
|
|
159
|
+
const schemaUrl = records[0]?.instrumentationScope?.schemaUrl || ''
|
|
160
|
+
scopeLogs.push({
|
|
161
|
+
scope: {
|
|
162
|
+
name: records[0]?.instrumentationScope?.name || 'dd-trace-js',
|
|
163
|
+
version: records[0]?.instrumentationScope?.version || '',
|
|
164
|
+
// TODO: Support setting attributes on instrumentation scope
|
|
165
|
+
attributes: [],
|
|
166
|
+
droppedAttributesCount: 0
|
|
167
|
+
},
|
|
168
|
+
schemaUrl,
|
|
169
|
+
logRecords: records.map(record => this.#transformLogRecord(record))
|
|
170
|
+
})
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return scopeLogs
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Transforms resource attributes to OTLP resource format.
|
|
178
|
+
* @returns {Resource} OTLP resource object
|
|
179
|
+
* @private
|
|
180
|
+
*/
|
|
181
|
+
#transformResource () {
|
|
182
|
+
return {
|
|
183
|
+
attributes: this.#resourceAttributes,
|
|
184
|
+
droppedAttributesCount: 0
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Transforms a single log record to OTLP format.
|
|
190
|
+
* @param {LogRecord} logRecord - Log record to transform
|
|
191
|
+
* @returns {Object} OTLP log record object
|
|
192
|
+
* @private
|
|
193
|
+
*/
|
|
194
|
+
#transformLogRecord (logRecord) {
|
|
195
|
+
const timestamp = logRecord.timestamp
|
|
196
|
+
|
|
197
|
+
// Extract span context from the log record's context
|
|
198
|
+
const spanContext = this.#extractSpanContext(logRecord.context)
|
|
199
|
+
|
|
200
|
+
// Only timeUnixNano and body are required
|
|
201
|
+
const result = {
|
|
202
|
+
timeUnixNano: timestamp,
|
|
203
|
+
body: this.#transformBody(logRecord.body)
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// Add optional fields only if they are set
|
|
207
|
+
if (logRecord.observedTimestamp) {
|
|
208
|
+
result.observedTimeUnixNano = logRecord.observedTimestamp
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
if (logRecord.severityNumber !== undefined) {
|
|
212
|
+
result.severityNumber = this.#mapSeverityNumber(logRecord.severityNumber)
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
if (logRecord.severityText) {
|
|
216
|
+
result.severityText = logRecord.severityText
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
if (logRecord.attributes) {
|
|
220
|
+
result.attributes = this.#transformAttributes(logRecord.attributes)
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
if (spanContext?.traceFlags !== undefined) {
|
|
224
|
+
result.flags = spanContext.traceFlags
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// Only include traceId and spanId if they are valid (not empty, undefined, or all zeros)
|
|
228
|
+
if (spanContext?.traceId && spanContext.traceId !== '00000000000000000000000000000000') {
|
|
229
|
+
result.traceId = this.#hexToBytes(spanContext.traceId)
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
if (spanContext?.spanId && spanContext.spanId !== '0000000000000000') {
|
|
233
|
+
result.spanId = this.#hexToBytes(spanContext.spanId)
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
return result
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Extracts span context from the log record's context.
|
|
241
|
+
* @param {Object} logContext - The log record's context
|
|
242
|
+
* @returns {Object|null} Span context or null if not available
|
|
243
|
+
* @private
|
|
244
|
+
*/
|
|
245
|
+
#extractSpanContext (logContext) {
|
|
246
|
+
if (!logContext) return null
|
|
247
|
+
|
|
248
|
+
const activeSpan = trace.getSpan(logContext)
|
|
249
|
+
if (activeSpan) {
|
|
250
|
+
return activeSpan.spanContext()
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
return null
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Maps OpenTelemetry severity number to protobuf severity number.
|
|
258
|
+
* @param {number} severityNumber - OpenTelemetry severity number
|
|
259
|
+
* @returns {number} Protobuf severity number
|
|
260
|
+
* @private
|
|
261
|
+
*/
|
|
262
|
+
#mapSeverityNumber (severityNumber) {
|
|
263
|
+
const { protoSeverityNumber } = getProtobufTypes()
|
|
264
|
+
const severityName = SEVERITY_MAP[severityNumber] || 'SEVERITY_NUMBER_INFO'
|
|
265
|
+
return protoSeverityNumber.values[severityName]
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Converts a hex string to a Buffer.
|
|
270
|
+
* @param {string} hexString - Hex string to convert
|
|
271
|
+
* @returns {Buffer} Buffer containing the hex data
|
|
272
|
+
* @private
|
|
273
|
+
*/
|
|
274
|
+
#hexToBytes (hexString) {
|
|
275
|
+
const cleanHex = hexString ? (hexString.startsWith('0x') ? hexString.slice(2) : hexString) : ''
|
|
276
|
+
const paddedHex = cleanHex.length % 2 === 0 ? cleanHex : '0' + cleanHex
|
|
277
|
+
return Buffer.from(paddedHex, 'hex')
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Transforms log body to OTLP AnyValue format.
|
|
282
|
+
* @param {any} body - Log body to transform
|
|
283
|
+
* @returns {Object} OTLP AnyValue object
|
|
284
|
+
* @private
|
|
285
|
+
*/
|
|
286
|
+
#transformBody (body) {
|
|
287
|
+
if (typeof body === 'string') {
|
|
288
|
+
return {
|
|
289
|
+
stringValue: body
|
|
290
|
+
}
|
|
291
|
+
} else if (typeof body === 'number') {
|
|
292
|
+
if (Number.isInteger(body)) {
|
|
293
|
+
return { intValue: body }
|
|
294
|
+
}
|
|
295
|
+
return { doubleValue: body }
|
|
296
|
+
} else if (typeof body === 'boolean') {
|
|
297
|
+
return {
|
|
298
|
+
boolValue: body
|
|
299
|
+
}
|
|
300
|
+
} else if (body && typeof body === 'object') {
|
|
301
|
+
return {
|
|
302
|
+
kvlistValue: {
|
|
303
|
+
values: Object.entries(body).map(([key, value]) => ({
|
|
304
|
+
key,
|
|
305
|
+
value: this.#transformAnyValue(value)
|
|
306
|
+
}))
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
return {
|
|
311
|
+
stringValue: String(body)
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* Transforms attributes to OTLP KeyValue format.
|
|
317
|
+
* @param {Object} attributes - Attributes to transform
|
|
318
|
+
* @returns {Object[]} Array of OTLP KeyValue objects
|
|
319
|
+
* @private
|
|
320
|
+
*/
|
|
321
|
+
#transformAttributes (attributes) {
|
|
322
|
+
if (!attributes) {
|
|
323
|
+
return {}
|
|
324
|
+
}
|
|
325
|
+
return Object.entries(attributes).map(([key, value]) => ({
|
|
326
|
+
key,
|
|
327
|
+
value: this.#transformAnyValue(value)
|
|
328
|
+
}))
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* Transforms any value to OTLP AnyValue format.
|
|
333
|
+
* @param {any} value - Value to transform
|
|
334
|
+
* @returns {Object} OTLP AnyValue object
|
|
335
|
+
* @private
|
|
336
|
+
*/
|
|
337
|
+
#transformAnyValue (value) {
|
|
338
|
+
if (typeof value === 'string') {
|
|
339
|
+
return { stringValue: value }
|
|
340
|
+
} else if (typeof value === 'number') {
|
|
341
|
+
if (Number.isInteger(value)) {
|
|
342
|
+
return { intValue: value }
|
|
343
|
+
}
|
|
344
|
+
return { doubleValue: value }
|
|
345
|
+
} else if (typeof value === 'boolean') {
|
|
346
|
+
return { boolValue: value }
|
|
347
|
+
} else if (Array.isArray(value)) {
|
|
348
|
+
return {
|
|
349
|
+
arrayValue: {
|
|
350
|
+
values: value.map(v => this.#transformAnyValue(v))
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
} else if (value && typeof value === 'object') {
|
|
354
|
+
return {
|
|
355
|
+
kvlistValue: {
|
|
356
|
+
values: Object.entries(value).map(([k, v]) => ({
|
|
357
|
+
key: k,
|
|
358
|
+
value: this.#transformAnyValue(v)
|
|
359
|
+
}))
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
return { stringValue: String(value) }
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
module.exports = OtlpTransformer
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
// Vendored from: https://github.com/open-telemetry/opentelemetry-proto/blob/v1.7.0/opentelemetry/proto/logs/v1/common.proto
|
|
2
|
+
// Copyright 2019, OpenTelemetry Authors
|
|
3
|
+
//
|
|
4
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
// you may not use this file except in compliance with the License.
|
|
6
|
+
// You may obtain a copy of the License at
|
|
7
|
+
//
|
|
8
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
//
|
|
10
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
// See the License for the specific language governing permissions and
|
|
14
|
+
// limitations under the License.
|
|
15
|
+
|
|
16
|
+
syntax = "proto3";
|
|
17
|
+
|
|
18
|
+
package opentelemetry.proto.common.v1;
|
|
19
|
+
|
|
20
|
+
option csharp_namespace = "OpenTelemetry.Proto.Common.V1";
|
|
21
|
+
option java_multiple_files = true;
|
|
22
|
+
option java_package = "io.opentelemetry.proto.common.v1";
|
|
23
|
+
option java_outer_classname = "CommonProto";
|
|
24
|
+
option go_package = "go.opentelemetry.io/proto/otlp/common/v1";
|
|
25
|
+
|
|
26
|
+
// AnyValue is used to represent any type of attribute value. AnyValue may contain a
|
|
27
|
+
// primitive value such as a string or integer or it may contain an arbitrary nested
|
|
28
|
+
// object containing arrays, key-value lists and primitives.
|
|
29
|
+
message AnyValue {
|
|
30
|
+
// The value is one of the listed fields. It is valid for all values to be unspecified
|
|
31
|
+
// in which case this AnyValue is considered to be "empty".
|
|
32
|
+
oneof value {
|
|
33
|
+
string string_value = 1;
|
|
34
|
+
bool bool_value = 2;
|
|
35
|
+
int64 int_value = 3;
|
|
36
|
+
double double_value = 4;
|
|
37
|
+
ArrayValue array_value = 5;
|
|
38
|
+
KeyValueList kvlist_value = 6;
|
|
39
|
+
bytes bytes_value = 7;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// ArrayValue is a list of AnyValue messages. We need ArrayValue as a message
|
|
44
|
+
// since oneof in AnyValue does not allow repeated fields.
|
|
45
|
+
message ArrayValue {
|
|
46
|
+
// Array of values. The array may be empty (contain 0 elements).
|
|
47
|
+
repeated AnyValue values = 1;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// KeyValueList is a list of KeyValue messages. We need KeyValueList as a message
|
|
51
|
+
// since `oneof` in AnyValue does not allow repeated fields. Everywhere else where we need
|
|
52
|
+
// a list of KeyValue messages (e.g. in Span) we use `repeated KeyValue` directly to
|
|
53
|
+
// avoid unnecessary extra wrapping (which slows down the protocol). The 2 approaches
|
|
54
|
+
// are semantically equivalent.
|
|
55
|
+
message KeyValueList {
|
|
56
|
+
// A collection of key/value pairs of key-value pairs. The list may be empty (may
|
|
57
|
+
// contain 0 elements).
|
|
58
|
+
// The keys MUST be unique (it is not allowed to have more than one
|
|
59
|
+
// value with the same key).
|
|
60
|
+
repeated KeyValue values = 1;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// KeyValue is a key-value pair that is used to store Span attributes, Link
|
|
64
|
+
// attributes, etc.
|
|
65
|
+
message KeyValue {
|
|
66
|
+
string key = 1;
|
|
67
|
+
AnyValue value = 2;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// InstrumentationScope is a message representing the instrumentation scope information
|
|
71
|
+
// such as the fully qualified name and version.
|
|
72
|
+
message InstrumentationScope {
|
|
73
|
+
// An empty instrumentation scope name means the name is unknown.
|
|
74
|
+
string name = 1;
|
|
75
|
+
string version = 2;
|
|
76
|
+
|
|
77
|
+
// Additional attributes that describe the scope. [Optional].
|
|
78
|
+
// Attribute keys MUST be unique (it is not allowed to have more than one
|
|
79
|
+
// attribute with the same key).
|
|
80
|
+
repeated KeyValue attributes = 3;
|
|
81
|
+
uint32 dropped_attributes_count = 4;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// A reference to an Entity.
|
|
85
|
+
// Entity represents an object of interest associated with produced telemetry: e.g spans, metrics, profiles, or logs.
|
|
86
|
+
//
|
|
87
|
+
// Status: [Development]
|
|
88
|
+
message EntityRef {
|
|
89
|
+
// The Schema URL, if known. This is the identifier of the Schema that the entity data
|
|
90
|
+
// is recorded in. To learn more about Schema URL see
|
|
91
|
+
// https://opentelemetry.io/docs/specs/otel/schemas/#schema-url
|
|
92
|
+
//
|
|
93
|
+
// This schema_url applies to the data in this message and to the Resource attributes
|
|
94
|
+
// referenced by id_keys and description_keys.
|
|
95
|
+
// TODO: discuss if we are happy with this somewhat complicated definition of what
|
|
96
|
+
// the schema_url applies to.
|
|
97
|
+
//
|
|
98
|
+
// This field obsoletes the schema_url field in ResourceMetrics/ResourceSpans/ResourceLogs.
|
|
99
|
+
string schema_url = 1;
|
|
100
|
+
|
|
101
|
+
// Defines the type of the entity. MUST not change during the lifetime of the entity.
|
|
102
|
+
// For example: "service" or "host". This field is required and MUST not be empty
|
|
103
|
+
// for valid entities.
|
|
104
|
+
string type = 2;
|
|
105
|
+
|
|
106
|
+
// Attribute Keys that identify the entity.
|
|
107
|
+
// MUST not change during the lifetime of the entity. The Id must contain at least one attribute.
|
|
108
|
+
// These keys MUST exist in the containing {message}.attributes.
|
|
109
|
+
repeated string id_keys = 3;
|
|
110
|
+
|
|
111
|
+
// Descriptive (non-identifying) attribute keys of the entity.
|
|
112
|
+
// MAY change over the lifetime of the entity. MAY be empty.
|
|
113
|
+
// These attribute keys are not part of entity's identity.
|
|
114
|
+
// These keys MUST exist in the containing {message}.attributes.
|
|
115
|
+
repeated string description_keys = 4;
|
|
116
|
+
}
|