diff --git a/include/triton/core/tritonserver.h b/include/triton/core/tritonserver.h index ef5a45d6a..d9701e890 100644 --- a/include/triton/core/tritonserver.h +++ b/include/triton/core/tritonserver.h @@ -64,6 +64,7 @@ struct TRITONSERVER_Server; struct TRITONSERVER_ServerOptions; struct TRITONSERVER_Metric; struct TRITONSERVER_MetricFamily; +struct TRITONSERVER_MetricArgs; /// /// TRITONSERVER API Version @@ -91,7 +92,7 @@ struct TRITONSERVER_MetricFamily; /// } /// #define TRITONSERVER_API_VERSION_MAJOR 1 -#define TRITONSERVER_API_VERSION_MINOR 33 +#define TRITONSERVER_API_VERSION_MINOR 34 /// Get the TRITONBACKEND API version supported by the Triton shared /// library. This value can be compared against the @@ -2615,7 +2616,8 @@ TRITONSERVER_DECLSPEC struct TRITONSERVER_Error* TRITONSERVER_ServerInferAsync( /// typedef enum TRITONSERVER_metrickind_enum { TRITONSERVER_METRIC_KIND_COUNTER, - TRITONSERVER_METRIC_KIND_GAUGE + TRITONSERVER_METRIC_KIND_GAUGE, + TRITONSERVER_METRIC_KIND_HISTOGRAM } TRITONSERVER_MetricKind; /// Create a new metric family object. The caller takes ownership of the @@ -2644,6 +2646,44 @@ TRITONSERVER_DECLSPEC struct TRITONSERVER_Error* TRITONSERVER_MetricFamilyNew( TRITONSERVER_DECLSPEC struct TRITONSERVER_Error* TRITONSERVER_MetricFamilyDelete(struct TRITONSERVER_MetricFamily* family); +/// Get the TRITONSERVER_MetricKind of the metric family. +/// +/// \param family The metric family object to query. +/// \param kind Returns the TRITONSERVER_MetricKind of metric. +/// \return a TRITONSERVER_Error indicating success or failure. +TRITONSERVER_DECLSPEC struct TRITONSERVER_Error* +TRITONSERVER_GetMetricFamilyKind( + struct TRITONSERVER_MetricFamily* family, TRITONSERVER_MetricKind* kind); + +/// Create a new metric args object. The caller takes ownership of the +/// TRITONSERVER_MetricArgs object and must call TRITONSERVER_MetricArgsDelete +/// to release the object. +/// +/// \param args Returns the new metric args object. +/// \return a TRITONSERVER_Error indicating success or failure. +TRITONSERVER_DECLSPEC struct TRITONSERVER_Error* TRITONSERVER_MetricArgsNew( + struct TRITONSERVER_MetricArgs** args); + +/// Set metric args with histogram metric parameter. +/// +/// \param args The metric args object to set. +/// \param buckets The array of bucket boundaries for the expected range of +/// observed values. +/// +/// \param buckets_count The number of bucket boundaries. +/// \return a TRITONSERVER_Error indicating success or failure. +TRITONSERVER_DECLSPEC struct TRITONSERVER_Error* +TRITONSERVER_MetricArgsSetHistogram( + struct TRITONSERVER_MetricArgs* args, const double* buckets, + const uint64_t buckets_count); + +/// Delete a metric args object. +/// +/// \param args The metric args object. +/// \return a TRITONSERVER_Error indicating success or failure. +TRITONSERVER_DECLSPEC struct TRITONSERVER_Error* TRITONSERVER_MetricArgsDelete( + struct TRITONSERVER_MetricArgs* args); + /// Create a new metric object. The caller takes ownership of the /// TRITONSERVER_Metric object and must call /// TRITONSERVER_MetricDelete to release the object. The caller is also @@ -2661,6 +2701,28 @@ TRITONSERVER_DECLSPEC struct TRITONSERVER_Error* TRITONSERVER_MetricNew( struct TRITONSERVER_MetricFamily* family, const struct TRITONSERVER_Parameter** labels, const uint64_t label_count); +/// Create a new metric object. The caller takes ownership of the +/// TRITONSERVER_Metric object and must call +/// TRITONSERVER_MetricDelete to release the object. The caller is also +/// responsible for ownership of the labels passed in. +/// Each label can be deleted immediately after creating the metric with +/// TRITONSERVER_ParameterDelete if not re-using the labels. +/// Metric args can be deleted immediately after creating the metric with +/// TRITONSERVER_MetricArgsDelete if not re-using the metric args. +/// +/// \param metric Returns the new metric object. +/// \param family The metric family to add this new metric to. +/// \param labels The array of labels to associate with this new metric. +/// \param label_count The number of labels. +/// \param args Metric args that store additional arguments to construct +/// particular metric types, e.g. histogram. +/// \return a TRITONSERVER_Error indicating success or failure. +TRITONSERVER_DECLSPEC struct TRITONSERVER_Error* TRITONSERVER_MetricNewWithArgs( + struct TRITONSERVER_Metric** metric, + struct TRITONSERVER_MetricFamily* family, + const struct TRITONSERVER_Parameter** labels, const uint64_t label_count, + const struct TRITONSERVER_MetricArgs* args); + /// Delete a metric object. /// All TRITONSERVER_Metric* objects should be deleted BEFORE their /// corresponding TRITONSERVER_MetricFamily* objects have been deleted. @@ -2705,7 +2767,17 @@ TRITONSERVER_DECLSPEC struct TRITONSERVER_Error* TRITONSERVER_MetricIncrement( TRITONSERVER_DECLSPEC struct TRITONSERVER_Error* TRITONSERVER_MetricSet( struct TRITONSERVER_Metric* metric, double value); -/// Get the TRITONSERVER_MetricKind of metric and its corresponding family. +/// Sample an observation and count it to the appropriate bucket of a metric. +/// Supports metrics of kind TRITONSERVER_METRIC_KIND_HISTOGRAM and returns +/// TRITONSERVER_ERROR_UNSUPPORTED for unsupported TRITONSERVER_MetricKind. +/// +/// \param metric The metric object to update. +/// \param value The amount for metric to sample observation. +/// \return a TRITONSERVER_Error indicating success or failure. +TRITONSERVER_DECLSPEC struct TRITONSERVER_Error* TRITONSERVER_MetricObserve( + struct TRITONSERVER_Metric* metric, double value); + +/// Get the TRITONSERVER_MetricKind of metric of its corresponding family. /// /// \param metric The metric object to query. /// \param kind Returns the TRITONSERVER_MetricKind of metric. diff --git a/src/metric_family.cc b/src/metric_family.cc index 8132eab25..13fa23ca3 100644 --- a/src/metric_family.cc +++ b/src/metric_family.cc @@ -1,4 +1,5 @@ -// Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// Copyright (c) 2022-2024, NVIDIA CORPORATION & AFFILIATES. All rights +// reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions @@ -54,6 +55,12 @@ MetricFamily::MetricFamily( .Help(description) .Register(*registry)); break; + case TRITONSERVER_METRIC_KIND_HISTOGRAM: + family_ = reinterpret_cast(&prometheus::BuildHistogram() + .Name(name) + .Help(description) + .Register(*registry)); + break; default: throw std::invalid_argument( "Unsupported kind passed to MetricFamily constructor."); @@ -63,11 +70,17 @@ MetricFamily::MetricFamily( } void* -MetricFamily::Add(std::map label_map, Metric* metric) +MetricFamily::Add( + std::map label_map, Metric* metric, + const TritonServerMetricArgs* args) { void* prom_metric = nullptr; switch (kind_) { case TRITONSERVER_METRIC_KIND_COUNTER: { + if (args != nullptr) { + throw std::invalid_argument( + "Unexpected args found in counter Metric constructor."); + } auto counter_family_ptr = reinterpret_cast*>(family_); auto counter_ptr = &counter_family_ptr->Add(label_map); @@ -75,12 +88,31 @@ MetricFamily::Add(std::map label_map, Metric* metric) break; } case TRITONSERVER_METRIC_KIND_GAUGE: { + if (args != nullptr) { + throw std::invalid_argument( + "Unexpected args found in gauge Metric constructor."); + } auto gauge_family_ptr = reinterpret_cast*>(family_); auto gauge_ptr = &gauge_family_ptr->Add(label_map); prom_metric = reinterpret_cast(gauge_ptr); break; } + case TRITONSERVER_METRIC_KIND_HISTOGRAM: { + if (args == nullptr) { + throw std::invalid_argument( + "Bucket boundaries not found in Metric args."); + } + if (args->kind() != TRITONSERVER_METRIC_KIND_HISTOGRAM) { + throw std::invalid_argument("Metric args not set to histogram kind."); + } + auto histogram_family_ptr = + reinterpret_cast*>(family_); + auto histogram_ptr = + &histogram_family_ptr->Add(label_map, args->buckets()); + prom_metric = reinterpret_cast(histogram_ptr); + break; + } default: throw std::invalid_argument( "Unsupported family kind passed to Metric constructor."); @@ -134,6 +166,14 @@ MetricFamily::Remove(void* prom_metric, Metric* metric) gauge_family_ptr->Remove(gauge_ptr); break; } + case TRITONSERVER_METRIC_KIND_HISTOGRAM: { + auto histogram_family_ptr = + reinterpret_cast*>(family_); + auto histogram_ptr = + reinterpret_cast(prom_metric); + histogram_family_ptr->Remove(histogram_ptr); + break; + } default: // Invalid kind should be caught in constructor LOG_ERROR << "Unsupported kind in Metric destructor."; @@ -169,7 +209,8 @@ MetricFamily::~MetricFamily() // Metric::Metric( TRITONSERVER_MetricFamily* family, - std::vector labels) + std::vector labels, + const TritonServerMetricArgs* args) { family_ = reinterpret_cast(family); kind_ = family_->Kind(); @@ -188,7 +229,7 @@ Metric::Metric( std::string(reinterpret_cast(param->ValuePointer())); } - metric_ = family_->Add(label_map, this); + metric_ = family_->Add(label_map, this, args); } Metric::~Metric() @@ -235,6 +276,11 @@ Metric::Value(double* value) *value = gauge_ptr->Value(); break; } + case TRITONSERVER_METRIC_KIND_HISTOGRAM: { + return TRITONSERVER_ErrorNew( + TRITONSERVER_ERROR_UNSUPPORTED, + "TRITONSERVER_METRIC_KIND_HISTOGRAM does not support Value"); + } default: return TRITONSERVER_ErrorNew( TRITONSERVER_ERROR_UNSUPPORTED, @@ -279,6 +325,11 @@ Metric::Increment(double value) } break; } + case TRITONSERVER_METRIC_KIND_HISTOGRAM: { + return TRITONSERVER_ErrorNew( + TRITONSERVER_ERROR_UNSUPPORTED, + "TRITONSERVER_METRIC_KIND_HISTOGRAM does not support Increment"); + } default: return TRITONSERVER_ErrorNew( TRITONSERVER_ERROR_UNSUPPORTED, @@ -308,6 +359,45 @@ Metric::Set(double value) gauge_ptr->Set(value); break; } + case TRITONSERVER_METRIC_KIND_HISTOGRAM: { + return TRITONSERVER_ErrorNew( + TRITONSERVER_ERROR_UNSUPPORTED, + "TRITONSERVER_METRIC_KIND_HISTOGRAM does not support Set"); + } + default: + return TRITONSERVER_ErrorNew( + TRITONSERVER_ERROR_UNSUPPORTED, + "Unsupported TRITONSERVER_MetricKind"); + } + + return nullptr; // Success +} + +TRITONSERVER_Error* +Metric::Observe(double value) +{ + if (metric_ == nullptr) { + return TRITONSERVER_ErrorNew( + TRITONSERVER_ERROR_INTERNAL, + "Could not set metric value. Metric has been invalidated."); + } + + switch (kind_) { + case TRITONSERVER_METRIC_KIND_COUNTER: { + return TRITONSERVER_ErrorNew( + TRITONSERVER_ERROR_UNSUPPORTED, + "TRITONSERVER_METRIC_KIND_COUNTER does not support Observe"); + } + case TRITONSERVER_METRIC_KIND_GAUGE: { + return TRITONSERVER_ErrorNew( + TRITONSERVER_ERROR_UNSUPPORTED, + "TRITONSERVER_METRIC_KIND_GAUGE does not support Observe"); + } + case TRITONSERVER_METRIC_KIND_HISTOGRAM: { + auto histogram_ptr = reinterpret_cast(metric_); + histogram_ptr->Observe(value); + break; + } default: return TRITONSERVER_ErrorNew( TRITONSERVER_ERROR_UNSUPPORTED, diff --git a/src/metric_family.h b/src/metric_family.h index b5d09d864..2ea13eeda 100644 --- a/src/metric_family.h +++ b/src/metric_family.h @@ -1,4 +1,5 @@ -// Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// Copyright (c) 2022-2024, NVIDIA CORPORATION & AFFILIATES. All rights +// reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions @@ -27,6 +28,7 @@ #ifdef TRITON_ENABLE_METRICS +#include #include #include #include @@ -37,6 +39,29 @@ namespace triton { namespace core { +// +// TritonServerMetricArgs +// +// Implementation for TRITONSERVER_MetricArgs. +// +class TritonServerMetricArgs { + public: + TritonServerMetricArgs() = default; + + void* SetHistogramArgs(const double* buckets, uint64_t bucket_count) + { + kind_ = TRITONSERVER_METRIC_KIND_HISTOGRAM; + buckets_ = std::vector(buckets, buckets + bucket_count); + return nullptr; + } + TRITONSERVER_MetricKind kind() const { return kind_; } + const std::vector& buckets() const { return buckets_; } + + private: + TRITONSERVER_MetricKind kind_; + std::vector buckets_; +}; + // // Implementation for TRITONSERVER_MetricFamily. // @@ -50,7 +75,9 @@ class MetricFamily { void* Family() const { return family_; } TRITONSERVER_MetricKind Kind() const { return kind_; } - void* Add(std::map label_map, Metric* metric); + void* Add( + std::map label_map, Metric* metric, + const TritonServerMetricArgs* args); void Remove(void* prom_metric, Metric* metric); int NumMetrics() @@ -86,7 +113,8 @@ class Metric { public: Metric( TRITONSERVER_MetricFamily* family, - std::vector labels); + std::vector labels, + const TritonServerMetricArgs* args); ~Metric(); MetricFamily* Family() const { return family_; } @@ -95,6 +123,7 @@ class Metric { TRITONSERVER_Error* Value(double* value); TRITONSERVER_Error* Increment(double value); TRITONSERVER_Error* Set(double value); + TRITONSERVER_Error* Observe(double value); // If a MetricFamily is deleted before its dependent Metric, we want to // invalidate the references so we don't access invalid memory. diff --git a/src/metrics.h b/src/metrics.h index 2abec1cf3..6d08ad168 100644 --- a/src/metrics.h +++ b/src/metrics.h @@ -1,4 +1,4 @@ -// Copyright 2018-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// Copyright 2018-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions @@ -35,6 +35,7 @@ #include "prometheus/counter.h" #include "prometheus/gauge.h" +#include "prometheus/histogram.h" #include "prometheus/registry.h" #include "prometheus/serializer.h" #include "prometheus/summary.h" diff --git a/src/test/metrics_api_test.cc b/src/test/metrics_api_test.cc index 3356493a3..ea9d63a9e 100644 --- a/src/test/metrics_api_test.cc +++ b/src/test/metrics_api_test.cc @@ -1,4 +1,5 @@ -// Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// Copyright (c) 2022-2024, NVIDIA CORPORATION & AFFILIATES. All rights +// reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions @@ -232,6 +233,89 @@ MetricAPIHelper(TRITONSERVER_Metric* metric, TRITONSERVER_MetricKind kind) TRITONSERVER_ErrorDelete(err); } +// Calculate the cumulative_counts vector based on data and buckets. +std::vector +GetCumulativeCounts( + const std::vector& data, const std::vector& buckets) +{ + std::vector cumulative_counts(buckets.size() + 1, 0); + for (double datum : data) { + int i = 0; + for (; i < buckets.size(); ++i) { + if (datum <= buckets[i]) { + cumulative_counts[i]++; + break; + } + } + if (i == buckets.size()) { + cumulative_counts[i]++; + } + } + + for (int i = 1; i < cumulative_counts.size(); ++i) { + cumulative_counts[i] += cumulative_counts[i - 1]; + } + return cumulative_counts; +} + +void +HistogramAPIHelper( + TRITONSERVER_Server* server, TRITONSERVER_Metric* metric, + std::vector buckets, std::string metric_name, + std::string labels_str) +{ + // Observe data + std::vector data{0.05, 1.5, 6.0}; + double sum = 0.0; + for (auto datum : data) { + FAIL_TEST_IF_ERR( + TRITONSERVER_MetricObserve(metric, datum), "observe metric value"); + sum += datum; + } + std::vector cumulative_counts = + GetCumulativeCounts(data, buckets); + + // Collect formatted output + std::string metrics_str; + GetMetrics(server, &metrics_str); + + // All strings in this function are generated from ostringstream to make sure + // there is no trailing zeros. For example, std::to_string(7.55) is "7.550000" + // which is inconsistent with prometheus text_serializer output "7.55". + + // custom_histogram_example_count{example1="histogram_label1",example2="histogram_label2"} + // 3 + std::ostringstream count_ss; + count_ss << metric_name << "_count{" << labels_str << "} " << data.size(); + ASSERT_EQ(NumMetricMatches(server, count_ss.str()), 1); + + // custom_histogram_example_sum{example1="histogram_label1",example2="histogram_label2"} + // 7.55 + std::ostringstream sum_ss; + sum_ss << metric_name << "_sum{" << labels_str << "} " << sum; + ASSERT_EQ(NumMetricMatches(server, sum_ss.str()), 1); + + // custom_histogram_example_bucket{example1="histogram_label1",example2="histogram_label2" + std::ostringstream bucket_partial_ss; + bucket_partial_ss << metric_name << "_bucket{" << labels_str; + ASSERT_EQ( + NumMetricMatches(server, bucket_partial_ss.str()), + cumulative_counts.size()); + for (uint64_t i = 0; i < cumulative_counts.size(); ++i) { + // custom_histogram_example_bucket{example1="histogram_label1",example2="histogram_label2",le="0.1"} + // 1 + std::ostringstream le_ss; + if (i < buckets.size()) { + le_ss << "\"" << buckets[i] << "\""; + } else { + le_ss << "\"+Inf\""; + } + std::ostringstream bucket_ss; + bucket_ss << metric_name << "_bucket{" << labels_str + << ",le=" << le_ss.str() << "} " << cumulative_counts[i]; + ASSERT_EQ(NumMetricMatches(server, bucket_ss.str()), 1); + } +} // Test Fixture class MetricsApiTest : public ::testing::Test { @@ -364,6 +448,123 @@ TEST_F(MetricsApiTest, TestGaugeEndToEnd) ASSERT_EQ(NumMetricMatches(server_, description), 0); } +// Test end-to-end flow of Generic Metrics API for Histogram metric +TEST_F(MetricsApiTest, TestHistogramEndToEnd) +{ + // Create metric family + TRITONSERVER_MetricFamily* family; + TRITONSERVER_MetricKind kind = TRITONSERVER_METRIC_KIND_HISTOGRAM; + const char* name = "custom_histogram_example"; + const char* description = + "this is an example histogram metric added via API."; + FAIL_TEST_IF_ERR( + TRITONSERVER_MetricFamilyNew(&family, kind, name, description), + "Creating new metric family"); + + // Create metric + TRITONSERVER_Metric* metric; + // Create labels + std::vector labels; + labels.emplace_back(TRITONSERVER_ParameterNew( + "example1", TRITONSERVER_PARAMETER_STRING, "histogram_label1")); + labels.emplace_back(TRITONSERVER_ParameterNew( + "example2", TRITONSERVER_PARAMETER_STRING, "histogram_label2")); + // Create metric args + std::vector buckets = {0.1, 1.0, 2.5, 5.0, 10.0}; + TRITONSERVER_MetricArgs* args; + FAIL_TEST_IF_ERR( + TRITONSERVER_MetricArgsNew(&args), "Creating new metric args"); + FAIL_TEST_IF_ERR( + TRITONSERVER_MetricArgsSetHistogram(args, buckets.data(), buckets.size()), + "setting histogram metric args"); + + FAIL_TEST_IF_ERR( + TRITONSERVER_MetricNewWithArgs( + &metric, family, labels.data(), labels.size(), args), + "Creating new metric"); + for (const auto label : labels) { + TRITONSERVER_ParameterDelete(const_cast(label)); + } + FAIL_TEST_IF_ERR(TRITONSERVER_MetricArgsDelete(args), "delete metric args"); + + // Run through metric APIs and assert correctness + std::string labels_str = + "example1=\"histogram_label1\",example2=\"histogram_label2\""; + HistogramAPIHelper(server_, metric, buckets, name, labels_str); + + // Assert custom metric is reported and found in output + ASSERT_EQ(NumMetricMatches(server_, description), 1); + + // Cleanup + FAIL_TEST_IF_ERR(TRITONSERVER_MetricDelete(metric), "delete metric"); + FAIL_TEST_IF_ERR( + TRITONSERVER_MetricFamilyDelete(family), "delete metric family"); + + // Assert custom metric/family is unregistered and no longer in output + ASSERT_EQ(NumMetricMatches(server_, description), 0); +} + +// Test create a histogram metric without creating metric arguments +TEST_F(MetricsApiTest, TestHistogramNoMetricArgs) +{ + // Create metric family + TRITONSERVER_MetricFamily* family; + TRITONSERVER_MetricKind kind = TRITONSERVER_METRIC_KIND_HISTOGRAM; + const char* name = "no_metric_args"; + const char* description = "no metric args description"; + FAIL_TEST_IF_ERR( + TRITONSERVER_MetricFamilyNew(&family, kind, name, description), + "Creating new metric family"); + + // MetricArgs not created + TRITONSERVER_MetricArgs* args = nullptr; + // Create metric + std::vector labels; + TRITONSERVER_Metric* metric = nullptr; + auto err = TRITONSERVER_MetricNewWithArgs( + &metric, family, labels.data(), labels.size(), args); + EXPECT_THAT( + TRITONSERVER_ErrorMessage(err), + HasSubstr("Bucket boundaries not found in Metric args")); + + // Cleanup + FAIL_TEST_IF_ERR(TRITONSERVER_MetricArgsDelete(args), "delete metric args"); + FAIL_TEST_IF_ERR( + TRITONSERVER_MetricFamilyDelete(family), "delete metric family"); +} + +// Test create a histogram metric without setting metric arguments +TEST_F(MetricsApiTest, TestHistogramMetricArgsNotset) +{ + // Create metric family + TRITONSERVER_MetricFamily* family; + TRITONSERVER_MetricKind kind = TRITONSERVER_METRIC_KIND_HISTOGRAM; + const char* name = "metric_args_not_set"; + const char* description = "metric args not set description"; + FAIL_TEST_IF_ERR( + TRITONSERVER_MetricFamilyNew(&family, kind, name, description), + "Creating new metric family"); + + // Create metric args object without setting it + TRITONSERVER_MetricArgs* args; + FAIL_TEST_IF_ERR( + TRITONSERVER_MetricArgsNew(&args), "Creating new metric args"); + + // Create metric + std::vector labels; + TRITONSERVER_Metric* metric = nullptr; + auto err = TRITONSERVER_MetricNewWithArgs( + &metric, family, labels.data(), labels.size(), args); + EXPECT_THAT( + TRITONSERVER_ErrorMessage(err), + HasSubstr("Metric args not set to histogram kind")); + + // Cleanup + FAIL_TEST_IF_ERR(TRITONSERVER_MetricArgsDelete(args), "delete metric args"); + FAIL_TEST_IF_ERR( + TRITONSERVER_MetricFamilyDelete(family), "delete metric family"); +} + // Test that a duplicate metric family can't be added // with a conflicting type/kind TEST_F(MetricsApiTest, TestDupeMetricFamilyDiffKind) diff --git a/src/tritonserver.cc b/src/tritonserver.cc index 82642d5dc..67343a730 100644 --- a/src/tritonserver.cc +++ b/src/tritonserver.cc @@ -3365,6 +3365,61 @@ TRITONSERVER_MetricFamilyDelete(TRITONSERVER_MetricFamily* family) #endif // TRITON_ENABLE_METRICS } +TRITONSERVER_Error* +TRITONSERVER_GetMetricFamilyKind( + TRITONSERVER_MetricFamily* family, TRITONSERVER_MetricKind* kind) +{ +#ifdef TRITON_ENABLE_METRICS + *kind = reinterpret_cast(family)->Kind(); + return nullptr; // Success +#else + return TRITONSERVER_ErrorNew( + TRITONSERVER_ERROR_UNSUPPORTED, "metrics not supported"); +#endif // TRITON_ENABLE_METRICS +} + +TRITONSERVER_Error* +TRITONSERVER_MetricArgsNew(TRITONSERVER_MetricArgs** args) +{ +#ifdef TRITON_ENABLE_METRICS + tc::TritonServerMetricArgs* largs = new tc::TritonServerMetricArgs(); + *args = reinterpret_cast(largs); + return nullptr; // Success +#else + *args = nullptr; + return TRITONSERVER_ErrorNew( + TRITONSERVER_ERROR_UNSUPPORTED, "metrics not supported"); +#endif // TRITON_ENABLE_METRICS +} + +TRITONSERVER_Error* +TRITONSERVER_MetricArgsSetHistogram( + TRITONSERVER_MetricArgs* args, const double* buckets, + const uint64_t buckets_count) +{ +#ifdef TRITON_ENABLE_METRICS + auto largs = reinterpret_cast(args); + largs->SetHistogramArgs(buckets, buckets_count); + return nullptr; // Success +#else + return TRITONSERVER_ErrorNew( + TRITONSERVER_ERROR_UNSUPPORTED, "metrics not supported"); +#endif // TRITON_ENABLE_METRICS +} + +TRITONSERVER_Error* +TRITONSERVER_MetricArgsDelete(TRITONSERVER_MetricArgs* args) +{ +#ifdef TRITON_ENABLE_METRICS + auto largs = reinterpret_cast(args); + delete largs; + return nullptr; // success +#else + return TRITONSERVER_ErrorNew( + TRITONSERVER_ERROR_UNSUPPORTED, "metrics not supported"); +#endif // TRITON_ENABLE_METRICS +} + // // TRITONSERVER_Metric // @@ -3373,6 +3428,24 @@ TRITONSERVER_MetricNew( TRITONSERVER_Metric** metric, TRITONSERVER_MetricFamily* family, const TRITONSERVER_Parameter** labels, const uint64_t label_count) { +#ifdef TRITON_ENABLE_METRICS + return TRITONSERVER_MetricNewWithArgs( + metric, family, labels, label_count, nullptr); +#else + return TRITONSERVER_ErrorNew( + TRITONSERVER_ERROR_UNSUPPORTED, "metrics not supported"); +#endif // TRITON_ENABLE_METRICS +} + +// +// TRITONSERVER_MetricGeneric +// +TRITONSERVER_Error* +TRITONSERVER_MetricNewWithArgs( + TRITONSERVER_Metric** metric, TRITONSERVER_MetricFamily* family, + const TRITONSERVER_Parameter** labels, const uint64_t label_count, + const TRITONSERVER_MetricArgs* args) +{ #ifdef TRITON_ENABLE_METRICS std::vector labels_vec; for (size_t i = 0; i < label_count; i++) { @@ -3381,8 +3454,9 @@ TRITONSERVER_MetricNew( } try { - *metric = reinterpret_cast( - new tc::Metric(family, labels_vec)); + *metric = reinterpret_cast(new tc::Metric( + family, labels_vec, + reinterpret_cast(args))); } catch (std::invalid_argument const& ex) { // Catch invalid kinds passed to constructor @@ -3450,6 +3524,17 @@ TRITONSERVER_MetricSet(TRITONSERVER_Metric* metric, double value) #endif // TRITON_ENABLE_METRICS } +TRITONSERVER_Error* +TRITONSERVER_MetricObserve(TRITONSERVER_Metric* metric, double value) +{ +#ifdef TRITON_ENABLE_METRICS + return reinterpret_cast(metric)->Observe(value); +#else + return TRITONSERVER_ErrorNew( + TRITONSERVER_ERROR_UNSUPPORTED, "metrics not supported"); +#endif // TRITON_ENABLE_METRICS +} + TRITONSERVER_Error* TRITONSERVER_GetMetricKind( TRITONSERVER_Metric* metric, TRITONSERVER_MetricKind* kind) diff --git a/src/tritonserver_stub.cc b/src/tritonserver_stub.cc index cd1e03e15..5cdb65c3c 100644 --- a/src/tritonserver_stub.cc +++ b/src/tritonserver_stub.cc @@ -1080,6 +1080,11 @@ TRITONSERVER_MetricNew() { } +TRITONAPI_DECLSPEC void +TRITONSERVER_MetricNewWithArgs() +{ +} + TRITONAPI_DECLSPEC void TRITONSERVER_MetricDelete() { @@ -1100,6 +1105,11 @@ TRITONSERVER_MetricSet() { } +TRITONAPI_DECLSPEC void +TRITONSERVER_MetricObserve() +{ +} + TRITONAPI_DECLSPEC void TRITONSERVER_GetMetricKind() {