Line data Source code
1 : // Copyright The OpenTelemetry Authors
2 : // SPDX-License-Identifier: Apache-2.0
3 :
4 : library;
5 :
6 : import 'package:dartastic_opentelemetry_api/dartastic_opentelemetry_api.dart';
7 : import 'package:meta/meta.dart';
8 :
9 : import '../otel.dart';
10 :
11 : part 'resource_create.dart';
12 :
13 : /// Represents a resource, which captures identifying information about the entities
14 : /// for which signals (stats, traces, and logs) are reported.
15 : ///
16 : /// A Resource is an immutable collection of attributes that provide information
17 : /// about the entity producing telemetry. Resources are a core concept of OpenTelemetry's
18 : /// identity model.
19 : ///
20 : /// More information:
21 : /// https://opentelemetry.io/docs/specs/otel/resource/sdk/
22 : ///
23 : /// Note: Per [OTEP 0265](https://github.com/open-telemetry/opentelemetry-specification/blob/main/oteps/0265-event-vision.md),
24 : /// span events are being deprecated and will be replaced by the Logging API.
25 : @immutable
26 : class Resource {
27 : final Attributes _attributes;
28 : final String? _schemaUrl;
29 :
30 : /// An empty resource with no attributes.
31 : ///
32 : /// This is a convenience constant for when no resource attributes are needed.
33 270 : static final Resource empty = Resource._(OTel.attributesFromMap({}));
34 :
35 : /// Gets the attributes describing this resource.
36 256 : Attributes get attributes => _attributes;
37 :
38 : /// Gets the schema URL for this resource's attributes, if any.
39 4 : String? get schemaUrl => _schemaUrl;
40 :
41 : /// Private constructor for creating Resource instances.
42 : ///
43 : /// Resources should be created through the [OTel.resource] method
44 : /// or [ResourceCreate.create] method, not directly.
45 128 : Resource._(Attributes attributes, [String? schemaUrl])
46 : : _attributes = attributes,
47 : _schemaUrl = schemaUrl;
48 :
49 : /// Merges this resource with another resource.
50 : ///
51 : /// The resulting resource contains the combined attributes of both resources.
52 : /// If there are attributes with the same key, the attributes from the other
53 : /// resource will take precedence.
54 : ///
55 : /// For schema URLs, the following rules apply:
56 : /// - If one schema URL is empty, use the non-empty one
57 : /// - If both schema URLs are the same, use that schema URL
58 : /// - If both schema URLs are different and non-empty, use the other resource's schema URL
59 : ///
60 : /// @param other The resource to merge with this resource
61 : /// @return A new resource with the merged attributes
62 54 : Resource merge(Resource other) {
63 54 : final mergedMap = <String, Object>{};
64 :
65 : // Add current attributes
66 215 : _attributes.toMap().forEach((key, value) {
67 106 : mergedMap[key] = value.value;
68 : });
69 :
70 : // Add other resource's attributes (they take precedence)
71 216 : other._attributes.toMap().forEach((key, value) {
72 108 : mergedMap[key] = value.value;
73 : });
74 :
75 : // Handle schema URL merging according to spec
76 : String? mergedSchemaUrl;
77 56 : if (_schemaUrl == null || _schemaUrl!.isEmpty) {
78 54 : mergedSchemaUrl = other._schemaUrl;
79 3 : } else if (other._schemaUrl == null || other._schemaUrl!.isEmpty) {
80 1 : mergedSchemaUrl = _schemaUrl;
81 3 : } else if (_schemaUrl == other._schemaUrl) {
82 1 : mergedSchemaUrl = _schemaUrl;
83 : } else {
84 : // Schema URLs are different and non-empty - this is a merging error
85 : // The spec says the result is implementation-specific
86 : // We'll choose to use the updating resource's schema URL
87 1 : mergedSchemaUrl = other._schemaUrl;
88 : }
89 :
90 54 : final result = Resource._(
91 54 : OTel.attributesFromMap(mergedMap),
92 : mergedSchemaUrl,
93 : );
94 :
95 54 : if (OTelLog.isDebug()) {
96 54 : OTelLog.debug('Resource merge result attributes:');
97 216 : result._attributes.toList().forEach((attr) {
98 216 : if (attr.key == 'tenant_id' || attr.key == 'service.name') {
99 208 : OTelLog.debug(' ${attr.key}: ${attr.value}');
100 : }
101 : });
102 : }
103 :
104 : return result;
105 : }
106 : }
|