1212// See the License for the specific language governing permissions and
1313// limitations under the License.
1414
15+ #include " absl/types/optional.h"
1516#include " google/cloud/opentelemetry/internal/time_series.h"
1617#include " google/cloud/opentelemetry/internal/monitored_resource.h"
1718#include " google/cloud/internal/absl_str_replace_quiet.h"
2021#include < opentelemetry/common/attribute_value.h>
2122#include < opentelemetry/sdk/metrics/data/metric_data.h>
2223#include < opentelemetry/sdk/metrics/export/metric_producer.h>
24+ #include < opentelemetry/sdk/resource/semantic_conventions.h>
2325#include < cctype>
26+ #include < string>
27+ #include < unordered_map>
28+ #include < vector>
2429
2530namespace google {
2631namespace cloud {
2732namespace otel_internal {
2833GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
2934namespace {
3035
36+ namespace sc = opentelemetry::sdk::resource::SemanticConventions;
37+
38+ struct OTelKeyMatch {
39+ std::vector<std::string> otel_keys;
40+ absl::optional<std::string> fallback = absl::nullopt ;
41+ };
42+
43+ std::unordered_map<std::string, OTelKeyMatch> const kExtraLabelsLookup = {
44+ {" service_name" , {{sc::kServiceName }}},
45+ {" service_namespace" , {{sc::kServiceNamespace }}},
46+ {" service_instance_id" , {{sc::kServiceInstanceId }}}};
47+
3148google::protobuf::Timestamp ToProtoTimestamp (
3249 opentelemetry::common::SystemTimestamp ts) {
3350 return internal::ToProtoTimestamp (
@@ -215,7 +232,7 @@ std::vector<google::monitoring::v3::TimeSeries> ToTimeSeries(
215232 }
216233 }
217234 }
218- return tss;
235+ return WithExtraLabels (data, tss) ;
219236}
220237
221238std::vector<google::monitoring::v3::CreateTimeSeriesRequest> ToRequests (
@@ -236,6 +253,41 @@ std::vector<google::monitoring::v3::CreateTimeSeriesRequest> ToRequests(
236253 return requests;
237254}
238255
256+ std::vector<google::monitoring::v3::TimeSeries> WithExtraLabels (
257+ opentelemetry::sdk::metrics::ResourceMetrics const & data,
258+ std::vector<google::monitoring::v3::TimeSeries>& tss) {
259+ if (!data.resource_ ) {
260+ return tss;
261+ }
262+
263+ opentelemetry::sdk::resource::ResourceAttributes const & attributes =
264+ data.resource_ ->GetAttributes ();
265+ for (auto const & kv : kExtraLabelsLookup ) {
266+ auto const & oks = kv.second .otel_keys ;
267+ auto found = std::find_first_of (
268+ oks.begin (), oks.end (), attributes.begin (), attributes.end (),
269+ [](auto const & key, auto const & attr) { return key == attr.first ; });
270+
271+ std::string value;
272+ if (found != oks.end ()) {
273+ value = AsString (attributes.at (*found));
274+ } else if (kv.second .fallback ) {
275+ value = *kv.second .fallback ;
276+ }
277+ if (value.empty ()) {
278+ continue ;
279+ }
280+
281+ for (auto & ts : tss) {
282+ auto & labels = *((*ts.mutable_metric ()).mutable_labels ());
283+ if (labels.find (kv.first ) == labels.end ()) {
284+ labels[kv.first ] = value;
285+ }
286+ }
287+ }
288+ return tss;
289+ }
290+
239291GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
240292} // namespace otel_internal
241293} // namespace cloud
0 commit comments