Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions tpu_raiden/telemetry/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Copyright 2026 Google LLC.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Copyright 2026 Google LLC

load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test")

package(default_visibility = ["//visibility:public"])

licenses(["notice"])

cc_library(
name = "metrics_api",
srcs = ["metrics_api.cc"],
hdrs = ["metrics_api.h"],
deps = [
"@com_google_absl//absl/base:core_headers",
"@com_google_absl//absl/base:no_destructor",
"@com_google_absl//absl/container:flat_hash_map",
"@com_google_absl//absl/strings",
"@com_google_absl//absl/synchronization",
"@com_google_absl//absl/types:span",
],
)

cc_test(
name = "metrics_api_test",
srcs = ["metrics_api_test.cc"],
deps = [
":metrics_api",
"@com_google_absl//absl/strings",
"@com_google_googletest//:gtest_main",
],
)

cc_library(
name = "metrics_3p_prometheus_exporter",
srcs = ["prometheus_exporter.cc"],
hdrs = ["prometheus_exporter.h"],
deps = [
":metrics_api",
"//third_party/prometheus_cpp_client:prometheus_client_core",
"@com_google_absl//absl/base:core_headers",
"@com_google_absl//absl/base:no_destructor",
"@com_google_absl//absl/container:flat_hash_map",
"@com_google_absl//absl/strings",
"@com_google_absl//absl/synchronization",
],
)

cc_test(
name = "prometheus_exporter_test",
srcs = ["prometheus_exporter_test.cc"],
deps = [
":metrics_3p_prometheus_exporter",
":metrics_api",
"@com_google_absl//absl/strings",
"@com_google_googletest//:gtest_main",
],
)
133 changes: 133 additions & 0 deletions tpu_raiden/telemetry/metrics_api.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
// Copyright 2026 Google LLC.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "tpu_raiden/telemetry/metrics_api.h"

#include <atomic>
#include <cstdint>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "absl/base/no_destructor.h"
#include "absl/container/flat_hash_map.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "absl/synchronization/mutex.h"

namespace tpu_raiden::telemetry {

absl::string_view GetMetricDescription(absl::string_view name) {
static const absl::NoDestructor<
absl::flat_hash_map<absl::string_view, absl::string_view>>
kDescriptionMap({
{metric_names::kSentBytesTotal,
"Total count of bytes sent over TPU Raiden interfaces."},
{metric_names::kReceivedBytesTotal,
"Total count of bytes received over TPU Raiden interfaces."},
{metric_names::kTransferDurationSeconds,
"Histogram of TPU Raiden transfer durations in seconds."},
{metric_names::kStageLatencySeconds,
"Histogram of TPU Raiden pipeline stage latencies in seconds."},
{metric_names::kActiveTransfers,
"Number of currently active TPU Raiden data transfers."},
{metric_names::kBufferOccupancyBytes,
"Gauge of TPU Raiden buffer occupancy in bytes."},
{metric_names::kTransferFailuresTotal,
"Total count of failed TPU Raiden data transfers."},
});

auto it = kDescriptionMap->find(name);
if (it != kDescriptionMap->end()) {
return it->second;
}
return name;
}

RaidenMetricStore& RaidenMetricStore::GetGlobalMetricStore() {
static absl::NoDestructor<RaidenMetricStore> global_store;
return *global_store;
}

void RaidenMetricStore::AddBackend(std::unique_ptr<MetricsBackend> backend) {
if (!backend) return;
absl::MutexLock lock(mutex_);
backends_.push_back(std::move(backend));
has_backends_.store(true, std::memory_order_release);
}

void RaidenMetricStore::ClearBackends() {
absl::MutexLock lock(mutex_);
has_backends_.store(false, std::memory_order_release);
backends_.clear();
}

bool RaidenMetricStore::HasBackends() const {
return has_backends_.load(std::memory_order_acquire);
}

void RaidenMetricStore::IncrementCounter(absl::string_view name,
LabelSpan labels, uint64_t val) const {
if (!has_backends_.load(std::memory_order_acquire)) return;
// TODO: Explore RCU optimization for lock-free reads.
absl::ReaderMutexLock lock(mutex_);
for (const auto& backend : backends_) {
backend->IncrementCounter(name, labels, val);
}
}

void RaidenMetricStore::SetGauge(absl::string_view name, LabelSpan labels,
double val) const {
if (!has_backends_.load(std::memory_order_acquire)) return;
absl::ReaderMutexLock lock(mutex_);
for (const auto& backend : backends_) {
backend->SetGauge(name, labels, val);
}
}

void RaidenMetricStore::ObserveHistogram(absl::string_view name,
LabelSpan labels, double val) const {
if (!has_backends_.load(std::memory_order_acquire)) return;
absl::ReaderMutexLock lock(mutex_);
for (const auto& backend : backends_) {
backend->ObserveHistogram(name, labels, val);
}
}

std::string RaidenMetricStore::GetTextSnapshot() const {
if (!has_backends_.load(std::memory_order_acquire)) return "";
absl::ReaderMutexLock lock(mutex_);
std::string result;
for (const auto& backend : backends_) {
absl::StrAppend(&result, backend->GetTextSnapshot());
}
return result;
}

} // namespace tpu_raiden::telemetry
135 changes: 135 additions & 0 deletions tpu_raiden/telemetry/metrics_api.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
// Copyright 2026 Google LLC.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Copyright 2026 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef THIRD_PARTY_TPU_RAIDEN_TPU_RAIDEN_TELEMETRY_METRICS_API_H_
#define THIRD_PARTY_TPU_RAIDEN_TPU_RAIDEN_TELEMETRY_METRICS_API_H_

#include <atomic>
#include <cstdint>
#include <memory>
#include <string>
#include <vector>

#include "absl/base/thread_annotations.h"
#include "absl/strings/string_view.h"
#include "absl/synchronization/mutex.h"
#include "absl/types/span.h"

namespace tpu_raiden::telemetry {

namespace metric_names {

inline constexpr absl::string_view kSentBytesTotal = "sent_bytes_total";
inline constexpr absl::string_view kReceivedBytesTotal = "received_bytes_total";
inline constexpr absl::string_view kTransferDurationSeconds =
"transfer_duration_seconds";
inline constexpr absl::string_view kStageLatencySeconds =
"stage_latency_seconds";
inline constexpr absl::string_view kActiveTransfers = "active_transfers";
inline constexpr absl::string_view kBufferOccupancyBytes =
"buffer_occupancy_bytes";
inline constexpr absl::string_view kTransferFailuresTotal =
"transfer_failures_total";

} // namespace metric_names

// Returns the common human-readable description for a given metric name,
// falling back to the metric name itself if unmapped. This description is
// common across all metric exporter backends (e.g., Prometheus and Streamz).
absl::string_view GetMetricDescription(absl::string_view name);

// Structure defining a metric key-value label pair.
struct MetricLabel {
absl::string_view key;
absl::string_view value;
};

// Allocation-free label view span type definition
using LabelSpan = absl::Span<const MetricLabel>;

// Abstract Dual-Backend Interface
class MetricsBackend {
public:
MetricsBackend() = default;
MetricsBackend(const MetricsBackend&) = delete;
MetricsBackend& operator=(const MetricsBackend&) = delete;
MetricsBackend(MetricsBackend&&) = delete;
MetricsBackend& operator=(MetricsBackend&&) = delete;

virtual ~MetricsBackend() = default;

virtual void IncrementCounter(absl::string_view name, LabelSpan labels,
uint64_t val) const = 0;

virtual void SetGauge(absl::string_view name, LabelSpan labels,
double val) const = 0;

virtual void ObserveHistogram(absl::string_view name, LabelSpan labels,
double val) const = 0;

virtual std::string GetTextSnapshot() const = 0;
};

// Central Telemetry Facade for managing metrics across registered backends.
// This class is thread-safe for all concurrent operations.
class RaidenMetricStore {
public:
static RaidenMetricStore& GetGlobalMetricStore();

RaidenMetricStore() = default;
~RaidenMetricStore() = default;

RaidenMetricStore(const RaidenMetricStore&) = delete;
RaidenMetricStore& operator=(const RaidenMetricStore&) = delete;
RaidenMetricStore(RaidenMetricStore&&) = delete;
RaidenMetricStore& operator=(RaidenMetricStore&&) = delete;

void AddBackend(std::unique_ptr<MetricsBackend> backend);
void ClearBackends();
bool HasBackends() const;

void IncrementCounter(absl::string_view name, LabelSpan labels,
uint64_t val = 1) const;

void SetGauge(absl::string_view name, LabelSpan labels, double val) const;

void ObserveHistogram(absl::string_view name, LabelSpan labels,
double val) const;

std::string GetTextSnapshot() const;

private:
mutable absl::Mutex mutex_;
std::vector<std::unique_ptr<MetricsBackend>> backends_
ABSL_GUARDED_BY(mutex_);
std::atomic<bool> has_backends_{false};
};

} // namespace tpu_raiden::telemetry

#endif // THIRD_PARTY_TPU_RAIDEN_TPU_RAIDEN_TELEMETRY_METRICS_API_H_
Loading
Loading