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+ struct OTelKeyMatch {
37+ std::vector<std::string> otel_keys;
38+ absl::optional<std::string> fallback = absl::nullopt ;
39+ };
40+
41+ std::unordered_map<std::string, OTelKeyMatch> const kExtraLabelsLookup = {
42+ {" service_name" ,
43+ {{opentelemetry::sdk::resource::SemanticConventions::kServiceName }}},
44+ {" service_namespace" ,
45+ {{opentelemetry::sdk::resource::SemanticConventions::kServiceNamespace }}},
46+ {" service_instance_id" ,
47+ {{opentelemetry::sdk::resource::SemanticConventions::
48+ kServiceInstanceId }}}};
49+
3150google::protobuf::Timestamp ToProtoTimestamp (
3251 opentelemetry::common::SystemTimestamp ts) {
3352 return internal::ToProtoTimestamp (
@@ -215,7 +234,7 @@ std::vector<google::monitoring::v3::TimeSeries> ToTimeSeries(
215234 }
216235 }
217236 }
218- return tss;
237+ return WithExtraLabels (data, tss) ;
219238}
220239
221240std::vector<google::monitoring::v3::CreateTimeSeriesRequest> ToRequests (
@@ -236,6 +255,41 @@ std::vector<google::monitoring::v3::CreateTimeSeriesRequest> ToRequests(
236255 return requests;
237256}
238257
258+ std::vector<google::monitoring::v3::TimeSeries> WithExtraLabels (
259+ opentelemetry::sdk::metrics::ResourceMetrics const & data,
260+ std::vector<google::monitoring::v3::TimeSeries>& tss) {
261+ if (!data.resource_ ) {
262+ return tss;
263+ }
264+
265+ opentelemetry::sdk::resource::ResourceAttributes const & attributes =
266+ data.resource_ ->GetAttributes ();
267+ for (auto const & kv : kExtraLabelsLookup ) {
268+ auto const & oks = kv.second .otel_keys ;
269+ auto found = std::find_first_of (
270+ oks.begin (), oks.end (), attributes.begin (), attributes.end (),
271+ [](auto const & key, auto const & attr) { return key == attr.first ; });
272+
273+ std::string value;
274+ if (found != oks.end ()) {
275+ value = AsString (attributes.at (*found));
276+ } else if (kv.second .fallback ) {
277+ value = *kv.second .fallback ;
278+ }
279+ if (value.empty ()) {
280+ continue ;
281+ }
282+
283+ for (auto & ts : tss) {
284+ auto & labels = *((*ts.mutable_metric ()).mutable_labels ());
285+ if (labels.find (kv.first ) == labels.end ()) {
286+ labels[kv.first ] = value;
287+ }
288+ }
289+ }
290+ return tss;
291+ }
292+
239293GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
240294} // namespace otel_internal
241295} // namespace cloud
0 commit comments