IMetrics.h#
Fully qualified name: omni/observability/IMetrics.h
File members: omni/observability/IMetrics.h
// SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: LicenseRef-NvidiaProprietary
//
// NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
// property and proprietary rights in and to this material, related
// documentation and any modifications thereto. Any use, reproduction,
// disclosure or distribution of this material and related documentation
// without an express license agreement from NVIDIA CORPORATION or
// its affiliates is strictly prohibited.
#pragma once
#include <omni/otel/Observer.h>
#include <omni/observability/IObservability.h>
#include <carb/ObjectUtils.h>
#include <carb/Framework.h>
#include <array>
namespace omni
{
namespace observability
{
using Attribute = omni::otel::Attribute;
template <class ValueType>
using InstrumentObserver = omni::otel::InstrumentObserver<ValueType>;
template <class ValueType>
using ObservableInstrumentCallback = omni::otel::ObservableInstrumentCallback<ValueType>;
class IMeter;
template <class ValueType>
class ICounter;
template <class ValueType>
class IHistogram;
template <class ValueType>
class IUpDownCounter;
class IObservableInstrument;
class IMeter : public carb::IObject
{
public:
virtual ~IMeter() = default;
// The functions below are provided for ABI stability and return raw pointers. These are lower-level functions;
// namespace-scope create functions that return \ref carb::ObjectPtr should be preferred for better object lifetime
// safety.
virtual ICounter<std::uint64_t>* createCounter_uint64_t(carb::cpp::string_view name,
carb::cpp::string_view description,
carb::cpp::string_view unit) noexcept = 0;
virtual ICounter<double>* createCounter_double(carb::cpp::string_view name,
carb::cpp::string_view description,
carb::cpp::string_view unit) noexcept = 0;
virtual IUpDownCounter<std::int64_t>* createUpDownCounter_int64_t(carb::cpp::string_view name,
carb::cpp::string_view description,
carb::cpp::string_view unit) noexcept = 0;
virtual IUpDownCounter<double>* createUpDownCounter_double(carb::cpp::string_view name,
carb::cpp::string_view description,
carb::cpp::string_view unit) noexcept = 0;
virtual IHistogram<std::uint64_t>* createHistogram_uint64_t(carb::cpp::string_view name,
carb::cpp::string_view description,
carb::cpp::string_view unit) noexcept = 0;
virtual IHistogram<double>* createHistogram_double(carb::cpp::string_view name,
carb::cpp::string_view description,
carb::cpp::string_view unit) noexcept = 0;
virtual IObservableInstrument* createObservableCounter_int64_t(ObservableInstrumentCallback<std::int64_t> callback,
void* context,
carb::cpp::string_view name,
carb::cpp::string_view description,
carb::cpp::string_view unit) noexcept = 0;
virtual IObservableInstrument* createObservableCounter_double(ObservableInstrumentCallback<double> callback,
void* context,
carb::cpp::string_view name,
carb::cpp::string_view description,
carb::cpp::string_view unit) noexcept = 0;
virtual IObservableInstrument* createObservableUpDownCounter_int64_t(ObservableInstrumentCallback<std::int64_t> callback,
void* context,
carb::cpp::string_view name,
carb::cpp::string_view description,
carb::cpp::string_view unit) noexcept = 0;
virtual IObservableInstrument* createObservableUpDownCounter_double(ObservableInstrumentCallback<double> callback,
void* context,
carb::cpp::string_view name,
carb::cpp::string_view description,
carb::cpp::string_view unit) noexcept = 0;
template <class ValueType>
ICounter<ValueType>* createCounter(carb::cpp::string_view name,
carb::cpp::string_view description,
carb::cpp::string_view unit = "") noexcept;
template <class ValueType>
IUpDownCounter<ValueType>* createUpDownCounter(carb::cpp::string_view name,
carb::cpp::string_view description,
carb::cpp::string_view unit = "") noexcept;
template <class ValueType>
IHistogram<ValueType>* createHistogram(carb::cpp::string_view name,
carb::cpp::string_view description,
carb::cpp::string_view unit = "") noexcept;
template <class ValueType>
IObservableInstrument* createObservableCounter(ObservableInstrumentCallback<ValueType> callback,
void* context,
carb::cpp::string_view name,
carb::cpp::string_view description,
carb::cpp::string_view unit = "") noexcept;
template <class ValueType>
IObservableInstrument* createObservableUpDownCounter(ObservableInstrumentCallback<ValueType> callback,
void* context,
carb::cpp::string_view name,
carb::cpp::string_view description,
carb::cpp::string_view unit = "") noexcept;
};
#ifndef DOXYGEN_BUILD
template <>
inline ICounter<std::uint64_t>* IMeter::createCounter<std::uint64_t>(carb::cpp::string_view name,
carb::cpp::string_view description,
carb::cpp::string_view unit) noexcept
{
return createCounter_uint64_t(name, description, unit);
}
template <>
inline ICounter<double>* IMeter::createCounter<double>(carb::cpp::string_view name,
carb::cpp::string_view description,
carb::cpp::string_view unit) noexcept
{
return createCounter_double(name, description, unit);
}
template <>
inline IUpDownCounter<std::int64_t>* IMeter::createUpDownCounter<std::int64_t>(carb::cpp::string_view name,
carb::cpp::string_view description,
carb::cpp::string_view unit) noexcept
{
return createUpDownCounter_int64_t(name, description, unit);
}
template <>
inline IUpDownCounter<double>* IMeter::createUpDownCounter<double>(carb::cpp::string_view name,
carb::cpp::string_view description,
carb::cpp::string_view unit) noexcept
{
return createUpDownCounter_double(name, description, unit);
}
template <>
inline IHistogram<std::uint64_t>* IMeter::createHistogram<std::uint64_t>(carb::cpp::string_view name,
carb::cpp::string_view description,
carb::cpp::string_view unit) noexcept
{
return createHistogram_uint64_t(name, description, unit);
}
template <>
inline IHistogram<double>* IMeter::createHistogram<double>(carb::cpp::string_view name,
carb::cpp::string_view description,
carb::cpp::string_view unit) noexcept
{
return createHistogram_double(name, description, unit);
}
template <>
inline IObservableInstrument* IMeter::createObservableCounter<std::int64_t>(ObservableInstrumentCallback<std::int64_t> callback,
void* context,
carb::cpp::string_view name,
carb::cpp::string_view description,
carb::cpp::string_view unit) noexcept
{
return createObservableCounter_int64_t(callback, context, name, description, unit);
}
template <>
inline IObservableInstrument* IMeter::createObservableCounter<double>(ObservableInstrumentCallback<double> callback,
void* context,
carb::cpp::string_view name,
carb::cpp::string_view description,
carb::cpp::string_view unit) noexcept
{
return createObservableCounter_double(callback, context, name, description, unit);
}
template <>
inline IObservableInstrument* IMeter::createObservableUpDownCounter<std::int64_t>(
ObservableInstrumentCallback<std::int64_t> callback,
void* context,
carb::cpp::string_view name,
carb::cpp::string_view description,
carb::cpp::string_view unit) noexcept
{
return createObservableUpDownCounter_int64_t(callback, context, name, description, unit);
}
template <>
inline IObservableInstrument* IMeter::createObservableUpDownCounter<double>(ObservableInstrumentCallback<double> callback,
void* context,
carb::cpp::string_view name,
carb::cpp::string_view description,
carb::cpp::string_view unit) noexcept
{
return createObservableUpDownCounter_double(callback, context, name, description, unit);
}
#endif
template <class ValueType_>
class ICounter : public carb::IObject
{
public:
using ValueType = ValueType_;
virtual ~ICounter() = default;
virtual void addArr(ValueType value, const Attribute attributes[], std::size_t attributeCount) noexcept = 0;
template <class T, class... A>
void add(T value, A&&... a) noexcept
{
const std::array<Attribute, sizeof...(A)> attrs = { Attribute(std::forward<A>(a))... };
this->addArr(value, attrs.data(), sizeof...(A));
}
template <class T>
void add(T value, std::initializer_list<Attribute> attributes) noexcept
{
this->addArr(value, attributes.begin(), attributes.size());
}
};
template <class ValueType_>
class IUpDownCounter : public carb::IObject
{
public:
using ValueType = ValueType_;
virtual ~IUpDownCounter() = default;
virtual void addArr(ValueType value, const Attribute attributes[], std::size_t attributeCount) noexcept = 0;
template <class T, class... A>
void add(T value, A&&... a) noexcept
{
const std::array<Attribute, sizeof...(A)> attrs = { Attribute(std::forward<A>(a))... };
this->addArr(value, attrs.data(), sizeof...(A));
}
template <class T>
void add(T value, std::initializer_list<Attribute> attributes) noexcept
{
this->addArr(value, attributes.begin(), attributes.size());
}
};
template <class ValueType_>
class IHistogram : public carb::IObject
{
public:
using ValueType = ValueType_;
virtual ~IHistogram() = default;
virtual void recordArr(ValueType value, const Attribute attributes[], std::size_t attributeCount) noexcept = 0;
template <class T, class... A>
void record(T value, A&&... a) noexcept
{
const std::array<Attribute, sizeof...(A)> attrs = { Attribute(std::forward<A>(a))... };
this->recordArr(value, attrs.data(), sizeof...(A));
}
template <class T>
void record(T value, std::initializer_list<Attribute> attributes) noexcept
{
this->recordArr(value, attributes.begin(), attributes.size());
}
};
class IObservableInstrument : public carb::IObject
{
public:
virtual ~IObservableInstrument() = default;
};
// Factory functions for creating instruments
template <class ValueType>
carb::ObjectPtr<ICounter<ValueType>> createCounter(const carb::ObjectPtr<IMeter>& meter,
carb::cpp::string_view name,
carb::cpp::string_view description,
carb::cpp::string_view unit = "")
{
if (!meter)
return {};
return carb::stealObject(meter->createCounter<ValueType>(name, description, unit));
}
template <class ValueType>
carb::ObjectPtr<IUpDownCounter<ValueType>> createUpDownCounter(const carb::ObjectPtr<IMeter>& meter,
carb::cpp::string_view name,
carb::cpp::string_view description,
carb::cpp::string_view unit = "")
{
if (!meter)
return {};
return carb::stealObject(meter->createUpDownCounter<ValueType>(name, description, unit));
}
template <class ValueType>
carb::ObjectPtr<IHistogram<ValueType>> createHistogram(const carb::ObjectPtr<IMeter>& meter,
carb::cpp::string_view name,
carb::cpp::string_view description,
carb::cpp::string_view unit = "")
{
if (!meter)
return {};
return carb::stealObject(meter->createHistogram<ValueType>(name, description, unit));
}
template <class ValueType>
carb::ObjectPtr<IObservableInstrument> createObservableCounter(const carb::ObjectPtr<IMeter>& meter,
ObservableInstrumentCallback<ValueType> callback,
void* context,
carb::cpp::string_view name,
carb::cpp::string_view description,
carb::cpp::string_view unit = "")
{
if (!meter)
return {};
return carb::stealObject(meter->createObservableCounter<ValueType>(callback, context, name, description, unit));
}
template <class ValueType>
carb::ObjectPtr<IObservableInstrument> createObservableUpDownCounter(const carb::ObjectPtr<IMeter>& meter,
ObservableInstrumentCallback<ValueType> callback,
void* context,
carb::cpp::string_view name,
carb::cpp::string_view description,
carb::cpp::string_view unit = "")
{
if (!meter)
return {};
return carb::stealObject(meter->createObservableUpDownCounter<ValueType>(callback, context, name, description, unit));
}
// Convenience functions for using instruments
template <class ValueType, class T, class... A>
void add(const carb::ObjectPtr<ICounter<ValueType>>& counter, T value, A&&... a) noexcept
{
if (counter)
counter->add(value, std::forward<A>(a)...);
}
template <class ValueType, class T>
void add(const carb::ObjectPtr<ICounter<ValueType>>& counter, T value, std::initializer_list<Attribute> attributes) noexcept
{
if (counter)
counter->add(value, attributes);
}
template <class ValueType, class T>
void addArr(const carb::ObjectPtr<ICounter<ValueType>>& counter,
T value,
const Attribute attributes[],
std::size_t attributeCount) noexcept
{
if (counter)
counter->addArr(value, attributes, attributeCount);
}
template <class ValueType, class T, class... A>
void add(const carb::ObjectPtr<IUpDownCounter<ValueType>>& upDownCounter, T value, A&&... a) noexcept
{
if (upDownCounter)
upDownCounter->add(value, std::forward<A>(a)...);
}
template <class ValueType, class T>
void add(const carb::ObjectPtr<IUpDownCounter<ValueType>>& upDownCounter,
T value,
std::initializer_list<Attribute> attributes) noexcept
{
if (upDownCounter)
upDownCounter->add(value, attributes);
}
template <class ValueType, class T>
void addArr(const carb::ObjectPtr<IUpDownCounter<ValueType>>& upDownCounter,
T value,
const Attribute attributes[],
std::size_t attributeCount) noexcept
{
if (upDownCounter)
upDownCounter->addArr(value, attributes, attributeCount);
}
template <class ValueType, class T, class... A>
void record(const carb::ObjectPtr<IHistogram<ValueType>>& histogram, T value, A&&... a) noexcept
{
if (histogram)
histogram->record(value, std::forward<A>(a)...);
}
template <class ValueType, class T>
void record(const carb::ObjectPtr<IHistogram<ValueType>>& histogram,
T value,
std::initializer_list<Attribute> attributes) noexcept
{
if (histogram)
histogram->record(value, attributes);
}
template <class ValueType, class T>
void recordArr(const carb::ObjectPtr<IHistogram<ValueType>>& histogram,
T value,
const Attribute attributes[],
std::size_t attributeCount) noexcept
{
if (histogram)
histogram->recordArr(value, attributes, attributeCount);
}
} // namespace observability
} // namespace omni