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