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.
Files changed (72) hide show
  1. package/LICENSE-3rdparty.csv +5 -0
  2. package/index.d.ts +110 -1
  3. package/initialize.mjs +7 -1
  4. package/package.json +21 -2
  5. package/packages/datadog-instrumentations/src/anthropic.js +115 -0
  6. package/packages/datadog-instrumentations/src/azure-event-hubs.js +37 -0
  7. package/packages/datadog-instrumentations/src/azure-functions.js +3 -0
  8. package/packages/datadog-instrumentations/src/cucumber.js +7 -7
  9. package/packages/datadog-instrumentations/src/helpers/hooks.js +2 -0
  10. package/packages/datadog-instrumentations/src/jest.js +29 -36
  11. package/packages/datadog-instrumentations/src/mocha/main.js +8 -9
  12. package/packages/datadog-instrumentations/src/mocha/utils.js +1 -1
  13. package/packages/datadog-instrumentations/src/mocha/worker.js +2 -2
  14. package/packages/datadog-instrumentations/src/pg.js +1 -1
  15. package/packages/datadog-instrumentations/src/playwright.js +5 -5
  16. package/packages/datadog-instrumentations/src/vitest.js +8 -8
  17. package/packages/datadog-plugin-anthropic/src/index.js +17 -0
  18. package/packages/datadog-plugin-anthropic/src/tracing.js +30 -0
  19. package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/utils.js +73 -27
  20. package/packages/datadog-plugin-azure-event-hubs/src/index.js +15 -0
  21. package/packages/datadog-plugin-azure-event-hubs/src/producer.js +82 -0
  22. package/packages/datadog-plugin-azure-functions/src/index.js +37 -0
  23. package/packages/datadog-plugin-cucumber/src/index.js +3 -3
  24. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +9 -9
  25. package/packages/datadog-plugin-jest/src/util.js +10 -2
  26. package/packages/datadog-plugin-mocha/src/index.js +2 -2
  27. package/packages/datadog-plugin-playwright/src/index.js +2 -2
  28. package/packages/datadog-plugin-vitest/src/index.js +2 -2
  29. package/packages/datadog-plugin-ws/src/server.js +5 -3
  30. package/packages/dd-trace/src/appsec/reporter.js +70 -21
  31. package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +1 -1
  32. package/packages/dd-trace/src/config.js +110 -26
  33. package/packages/dd-trace/src/config_defaults.js +14 -0
  34. package/packages/dd-trace/src/git_properties.js +90 -5
  35. package/packages/dd-trace/src/llmobs/plugins/anthropic.js +282 -0
  36. package/packages/dd-trace/src/llmobs/tagger.js +35 -0
  37. package/packages/dd-trace/src/noop/proxy.js +3 -0
  38. package/packages/dd-trace/src/openfeature/constants/constants.js +51 -0
  39. package/packages/dd-trace/src/openfeature/flagging_provider.js +45 -0
  40. package/packages/dd-trace/src/openfeature/index.js +77 -0
  41. package/packages/dd-trace/src/openfeature/noop.js +101 -0
  42. package/packages/dd-trace/src/openfeature/writers/base.js +181 -0
  43. package/packages/dd-trace/src/openfeature/writers/exposures.js +173 -0
  44. package/packages/dd-trace/src/openfeature/writers/util.js +43 -0
  45. package/packages/dd-trace/src/opentelemetry/logs/batch_log_processor.js +100 -0
  46. package/packages/dd-trace/src/opentelemetry/logs/index.js +87 -0
  47. package/packages/dd-trace/src/opentelemetry/logs/logger.js +77 -0
  48. package/packages/dd-trace/src/opentelemetry/logs/logger_provider.js +126 -0
  49. package/packages/dd-trace/src/opentelemetry/logs/otlp_http_log_exporter.js +173 -0
  50. package/packages/dd-trace/src/opentelemetry/logs/otlp_transformer.js +367 -0
  51. package/packages/dd-trace/src/opentelemetry/protos/common.proto +116 -0
  52. package/packages/dd-trace/src/opentelemetry/protos/logs.proto +226 -0
  53. package/packages/dd-trace/src/opentelemetry/protos/logs_service.proto +78 -0
  54. package/packages/dd-trace/src/opentelemetry/protos/protobuf_loader.js +48 -0
  55. package/packages/dd-trace/src/opentelemetry/protos/resource.proto +45 -0
  56. package/packages/dd-trace/src/plugins/ci_plugin.js +7 -6
  57. package/packages/dd-trace/src/plugins/index.js +2 -0
  58. package/packages/dd-trace/src/plugins/util/test.js +6 -5
  59. package/packages/dd-trace/src/profiling/config.js +21 -1
  60. package/packages/dd-trace/src/profiling/exporters/event_serializer.js +3 -2
  61. package/packages/dd-trace/src/profiling/profiler.js +44 -22
  62. package/packages/dd-trace/src/profiling/profilers/events.js +12 -3
  63. package/packages/dd-trace/src/profiling/profilers/space.js +35 -24
  64. package/packages/dd-trace/src/profiling/profilers/wall.js +14 -6
  65. package/packages/dd-trace/src/proxy.js +22 -1
  66. package/packages/dd-trace/src/remote_config/capabilities.js +2 -0
  67. package/packages/dd-trace/src/remote_config/index.js +3 -0
  68. package/packages/dd-trace/src/service-naming/schemas/v0/messaging.js +4 -0
  69. package/packages/dd-trace/src/service-naming/schemas/v1/messaging.js +8 -0
  70. package/packages/dd-trace/src/supported-configurations.json +18 -0
  71. package/packages/dd-trace/src/telemetry/telemetry.js +13 -1
  72. 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
+ }