|
1 | | -# Copyright 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. |
| 1 | +# Copyright 2023-2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved. |
2 | 2 | # |
3 | 3 | # Redistribution and use in source and binary forms, with or without |
4 | 4 | # modification, are permitted provided that the following conditions |
@@ -74,6 +74,96 @@ def _metric_api_helper(self, metric, kind): |
74 | 74 | self.assertEqual(metric.value(), value) |
75 | 75 | logger.log_info("Set metric to : {}".format(metric.value())) |
76 | 76 |
|
| 77 | + # Test observe value |
| 78 | + observe = 0.05 |
| 79 | + # Counter and gauge do not support observe |
| 80 | + with self.assertRaises(pb_utils.TritonModelException): |
| 81 | + metric.observe(observe) |
| 82 | + |
| 83 | + def _histogram_api_helper(self, metric, name, labels): |
| 84 | + def histogram_str_builder(name, type, labels, value, le=None): |
| 85 | + if type == "count" or type == "sum": |
| 86 | + return f"{name}_{type}{{{labels}}} {value}" |
| 87 | + elif type == "bucket": |
| 88 | + return f'{name}_bucket{{{labels},le="{le}"}} {value}' |
| 89 | + else: |
| 90 | + raise |
| 91 | + |
| 92 | + # Adding logger to test if custom metrics and logging work together |
| 93 | + # as they use the same message queue. |
| 94 | + logger = pb_utils.Logger |
| 95 | + |
| 96 | + # All values should be 0.0 before the test |
| 97 | + metrics = self._get_metrics() |
| 98 | + self.assertIn(histogram_str_builder(name, "count", labels, "0"), metrics) |
| 99 | + self.assertIn(histogram_str_builder(name, "sum", labels, "0"), metrics) |
| 100 | + self.assertIn( |
| 101 | + histogram_str_builder(name, "bucket", labels, "0", le="0.1"), metrics |
| 102 | + ) |
| 103 | + self.assertIn( |
| 104 | + histogram_str_builder(name, "bucket", labels, "0", le="1"), metrics |
| 105 | + ) |
| 106 | + self.assertIn( |
| 107 | + histogram_str_builder(name, "bucket", labels, "0", le="2.5"), metrics |
| 108 | + ) |
| 109 | + self.assertIn( |
| 110 | + histogram_str_builder(name, "bucket", labels, "0", le="5"), metrics |
| 111 | + ) |
| 112 | + self.assertIn( |
| 113 | + histogram_str_builder(name, "bucket", labels, "0", le="10"), metrics |
| 114 | + ) |
| 115 | + self.assertIn( |
| 116 | + histogram_str_builder(name, "bucket", labels, "0", le="+Inf"), metrics |
| 117 | + ) |
| 118 | + |
| 119 | + # Histogram does not support value |
| 120 | + with self.assertRaises(pb_utils.TritonModelException): |
| 121 | + metric.value() |
| 122 | + |
| 123 | + # Test increment value |
| 124 | + increment = 2023.0 |
| 125 | + # Histogram does not support increment |
| 126 | + with self.assertRaises(pb_utils.TritonModelException): |
| 127 | + metric.increment(increment) |
| 128 | + |
| 129 | + # Test set value |
| 130 | + value = 999.9 |
| 131 | + # Histogram does not support set |
| 132 | + with self.assertRaises(pb_utils.TritonModelException): |
| 133 | + metric.set(value) |
| 134 | + |
| 135 | + # Test observe value |
| 136 | + data = [0.05, 1.5, 6.0] |
| 137 | + for datum in data: |
| 138 | + metric.observe(datum) |
| 139 | + logger.log_info("Observe histogram metric with value : {}".format(datum)) |
| 140 | + |
| 141 | + metrics = self._get_metrics() |
| 142 | + self.assertIn( |
| 143 | + histogram_str_builder(name, "count", labels, str(len(data))), metrics |
| 144 | + ) |
| 145 | + self.assertIn( |
| 146 | + histogram_str_builder(name, "sum", labels, str(sum(data))), metrics |
| 147 | + ) |
| 148 | + self.assertIn( |
| 149 | + histogram_str_builder(name, "bucket", labels, "1", le="0.1"), metrics |
| 150 | + ) |
| 151 | + self.assertIn( |
| 152 | + histogram_str_builder(name, "bucket", labels, "1", le="1"), metrics |
| 153 | + ) |
| 154 | + self.assertIn( |
| 155 | + histogram_str_builder(name, "bucket", labels, "2", le="2.5"), metrics |
| 156 | + ) |
| 157 | + self.assertIn( |
| 158 | + histogram_str_builder(name, "bucket", labels, "2", le="5"), metrics |
| 159 | + ) |
| 160 | + self.assertIn( |
| 161 | + histogram_str_builder(name, "bucket", labels, "3", le="10"), metrics |
| 162 | + ) |
| 163 | + self.assertIn( |
| 164 | + histogram_str_builder(name, "bucket", labels, "3", le="+Inf"), metrics |
| 165 | + ) |
| 166 | + |
77 | 167 | def _dup_metric_helper(self, labels={}): |
78 | 168 | # Adding logger to test if custom metrics and logging work together |
79 | 169 | # as they use the same message queue. |
@@ -136,6 +226,27 @@ def test_gauge_e2e(self): |
136 | 226 | metrics = self._get_metrics() |
137 | 227 | self.assertIn(pattern, metrics) |
138 | 228 |
|
| 229 | + def test_histogram_e2e(self): |
| 230 | + name = "test_histogram_e2e" |
| 231 | + metric_family = pb_utils.MetricFamily( |
| 232 | + name=name, |
| 233 | + description="test metric histogram kind end to end", |
| 234 | + kind=pb_utils.MetricFamily.HISTOGRAM, |
| 235 | + ) |
| 236 | + labels = {"example1": "counter_label1", "example2": "counter_label2"} |
| 237 | + buckets = [0.1, 1.0, 2.5, 5.0, 10.0] |
| 238 | + metric = metric_family.Metric(labels=labels, buckets=buckets) |
| 239 | + labels_str = 'example1="counter_label1",example2="counter_label2"' |
| 240 | + self._histogram_api_helper(metric, name, labels_str) |
| 241 | + |
| 242 | + metrics = self._get_metrics() |
| 243 | + count_pattern = f"{name}_count{{{labels_str}}}" |
| 244 | + sum_pattern = f"{name}_sum{{{labels_str}}}" |
| 245 | + bucket_pattern = f"{name}_bucket{{{labels_str}" |
| 246 | + self.assertEqual(metrics.count(count_pattern), 1) |
| 247 | + self.assertEqual(metrics.count(sum_pattern), 1) |
| 248 | + self.assertEqual(metrics.count(bucket_pattern), len(buckets) + 1) |
| 249 | + |
139 | 250 | def test_dup_metric_family_diff_kind(self): |
140 | 251 | # Test that a duplicate metric family can't be added with a conflicting type/kind |
141 | 252 | metric_family1 = pb_utils.MetricFamily( |
|
0 commit comments