Skip to content

Commit

Permalink
impl(otel): copy service resource labels into metric labels
Browse files Browse the repository at this point in the history
  • Loading branch information
IcySteam committed Nov 22, 2024
1 parent aa062cf commit 1775a3e
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 1 deletion.
54 changes: 53 additions & 1 deletion google/cloud/opentelemetry/internal/time_series.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

#include "absl/types/optional.h"
#include "google/cloud/opentelemetry/internal/time_series.h"
#include "google/cloud/opentelemetry/internal/monitored_resource.h"
#include "google/cloud/internal/absl_str_replace_quiet.h"
Expand All @@ -20,14 +21,30 @@
#include <opentelemetry/common/attribute_value.h>
#include <opentelemetry/sdk/metrics/data/metric_data.h>
#include <opentelemetry/sdk/metrics/export/metric_producer.h>
#include <opentelemetry/sdk/resource/semantic_conventions.h>
#include <cctype>
#include <string>
#include <unordered_map>
#include <vector>

namespace google {
namespace cloud {
namespace otel_internal {
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_BEGIN
namespace {

namespace sc = opentelemetry::sdk::resource::SemanticConventions;

struct OTelKeyMatch {
std::vector<std::string> otel_keys;
absl::optional<std::string> fallback = absl::nullopt;
};

std::unordered_map<std::string, OTelKeyMatch> const kExtraLabelsLookup = {
{"service_name", {{sc::kServiceName}}},
{"service_namespace", {{sc::kServiceNamespace}}},
{"service_instance_id", {{sc::kServiceInstanceId}}}};

google::protobuf::Timestamp ToProtoTimestamp(
opentelemetry::common::SystemTimestamp ts) {
return internal::ToProtoTimestamp(
Expand Down Expand Up @@ -215,7 +232,7 @@ std::vector<google::monitoring::v3::TimeSeries> ToTimeSeries(
}
}
}
return tss;
return WithExtraLabels(data, tss);
}

std::vector<google::monitoring::v3::CreateTimeSeriesRequest> ToRequests(
Expand All @@ -236,6 +253,41 @@ std::vector<google::monitoring::v3::CreateTimeSeriesRequest> ToRequests(
return requests;
}

std::vector<google::monitoring::v3::TimeSeries> WithExtraLabels(
opentelemetry::sdk::metrics::ResourceMetrics const& data,
std::vector<google::monitoring::v3::TimeSeries>& tss) {
if (!data.resource_) {
return tss;
}

opentelemetry::sdk::resource::ResourceAttributes const& attributes =
data.resource_->GetAttributes();
for (auto const& kv : kExtraLabelsLookup) {
auto const& oks = kv.second.otel_keys;
auto found = std::find_first_of(
oks.begin(), oks.end(), attributes.begin(), attributes.end(),
[](auto const& key, auto const& attr) { return key == attr.first; });

std::string value;
if (found != oks.end()) {
value = AsString(attributes.at(*found));
} else if (kv.second.fallback) {
value = *kv.second.fallback;
}
if (value.empty()) {
continue;
}

for (auto& ts : tss) {
auto& labels = *((*ts.mutable_metric()).mutable_labels());
if (labels.find(kv.first) == labels.end()) {
labels[kv.first] = value;
}
}
}
return tss;
}

GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
} // namespace otel_internal
} // namespace cloud
Expand Down
15 changes: 15 additions & 0 deletions google/cloud/opentelemetry/internal/time_series.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <google/api/monitored_resource.pb.h>
#include <google/monitoring/v3/metric_service.pb.h>
#include <opentelemetry/sdk/metrics/metric_reader.h>
#include <opentelemetry/sdk/resource/resource.h>
#include <functional>
#include <string>

Expand Down Expand Up @@ -89,6 +90,20 @@ std::vector<google::monitoring::v3::CreateTimeSeriesRequest> ToRequests(
std::string const& project, google::api::MonitoredResource const& mr_proto,
std::vector<google::monitoring::v3::TimeSeries> tss);

/**
* Copy some resource labels into metric labels.
*
* Some resource labels need to be copied into metric labels as they are not
* directly accepted by Google Cloud Monitoring as resource labels.
*
* For example, service resource labels need to be copied into metric labels.
* See:
* https://github.com/GoogleCloudPlatform/opentelemetry-operations-go/blob/main/exporter/collector/breaking-changes.md#labels
*/
std::vector<google::monitoring::v3::TimeSeries> WithExtraLabels(
opentelemetry::sdk::metrics::ResourceMetrics const& data,
std::vector<google::monitoring::v3::TimeSeries>& tss);

GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
} // namespace otel_internal
} // namespace cloud
Expand Down

0 comments on commit 1775a3e

Please sign in to comment.