prometheus_decoder_ut.cpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530
  1. #include "prometheus.h"
  2. #include <library/cpp/monlib/encode/protobuf/protobuf.h>
  3. #include <library/cpp/testing/unittest/registar.h>
  4. using namespace NMonitoring;
  5. #define ASSERT_LABEL_EQUAL(label, name, value) do { \
  6. UNIT_ASSERT_STRINGS_EQUAL((label).GetName(), name); \
  7. UNIT_ASSERT_STRINGS_EQUAL((label).GetValue(), value); \
  8. } while (false)
  9. #define ASSERT_DOUBLE_POINT(s, time, value) do { \
  10. UNIT_ASSERT_VALUES_EQUAL((s).GetTime(), (time).MilliSeconds()); \
  11. UNIT_ASSERT_EQUAL((s).GetValueCase(), NProto::TSingleSample::kFloat64); \
  12. UNIT_ASSERT_DOUBLES_EQUAL((s).GetFloat64(), value, std::numeric_limits<double>::epsilon()); \
  13. } while (false)
  14. #define ASSERT_UINT_POINT(s, time, value) do { \
  15. UNIT_ASSERT_VALUES_EQUAL((s).GetTime(), (time).MilliSeconds()); \
  16. UNIT_ASSERT_EQUAL((s).GetValueCase(), NProto::TSingleSample::kUint64); \
  17. UNIT_ASSERT_VALUES_EQUAL((s).GetUint64(), value); \
  18. } while (false)
  19. #define ASSERT_HIST_POINT(s, time, expected) do { \
  20. UNIT_ASSERT_VALUES_EQUAL((s).GetTime(), time.MilliSeconds()); \
  21. UNIT_ASSERT_EQUAL((s).GetValueCase(), NProto::TSingleSample::kHistogram);\
  22. UNIT_ASSERT_VALUES_EQUAL((s).GetHistogram().BoundsSize(), (expected).Count()); \
  23. UNIT_ASSERT_VALUES_EQUAL((s).GetHistogram().ValuesSize(), (expected).Count()); \
  24. for (size_t i = 0; i < (s).GetHistogram().BoundsSize(); i++) { \
  25. UNIT_ASSERT_DOUBLES_EQUAL((s).GetHistogram().GetBounds(i), (expected).UpperBound(i), Min<double>()); \
  26. UNIT_ASSERT_VALUES_EQUAL((s).GetHistogram().GetValues(i), (expected).Value(i)); \
  27. } \
  28. } while (false)
  29. Y_UNIT_TEST_SUITE(TPrometheusDecoderTest) {
  30. NProto::TSingleSamplesList Decode(TStringBuf data, const TPrometheusDecodeSettings& settings = TPrometheusDecodeSettings{}) {
  31. NProto::TSingleSamplesList samples;
  32. ;
  33. {
  34. IMetricEncoderPtr e = EncoderProtobuf(&samples);
  35. DecodePrometheus(data, e.Get(), "sensor", settings);
  36. }
  37. return samples;
  38. }
  39. Y_UNIT_TEST(Empty) {
  40. {
  41. auto samples = Decode("");
  42. UNIT_ASSERT_EQUAL(samples.SamplesSize(), 0);
  43. }
  44. {
  45. auto samples = Decode("\n");
  46. UNIT_ASSERT_EQUAL(samples.SamplesSize(), 0);
  47. }
  48. {
  49. auto samples = Decode("\n \n \n");
  50. UNIT_ASSERT_EQUAL(samples.SamplesSize(), 0);
  51. }
  52. {
  53. auto samples = Decode("\t\n\t\n");
  54. UNIT_ASSERT_EQUAL(samples.SamplesSize(), 0);
  55. }
  56. }
  57. Y_UNIT_TEST(Minimal) {
  58. auto samples = Decode(
  59. "minimal_metric 1.234\n"
  60. "big_num 1.04671344e+10\n"
  61. "another_metric -3e3 103948\n"
  62. "# Even that:\n"
  63. "no_labels{} 3\n"
  64. "# HELP line for non-existing metric will be ignored.\n");
  65. UNIT_ASSERT_EQUAL(samples.SamplesSize(), 4);
  66. {
  67. auto& s = samples.GetSamples(0);
  68. UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::GAUGE);
  69. UNIT_ASSERT_EQUAL(1, s.LabelsSize());
  70. ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "minimal_metric");
  71. ASSERT_DOUBLE_POINT(s, TInstant::Zero(), 1.234);
  72. }
  73. {
  74. auto& s = samples.GetSamples(1);
  75. UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::GAUGE);
  76. UNIT_ASSERT_EQUAL(1, s.LabelsSize());
  77. ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "big_num");
  78. ASSERT_DOUBLE_POINT(s, TInstant::Zero(), 1.04671344e+10);
  79. }
  80. {
  81. auto& s = samples.GetSamples(2);
  82. UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::GAUGE);
  83. UNIT_ASSERT_EQUAL(s.LabelsSize(), 1);
  84. ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "another_metric");
  85. ASSERT_DOUBLE_POINT(s, TInstant::MilliSeconds(103948), -3000.0);
  86. }
  87. {
  88. auto& s = samples.GetSamples(3);
  89. UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::GAUGE);
  90. UNIT_ASSERT_EQUAL(1, s.LabelsSize());
  91. ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "no_labels");
  92. ASSERT_DOUBLE_POINT(s, TInstant::Zero(), 3.0);
  93. }
  94. }
  95. Y_UNIT_TEST(Counter) {
  96. constexpr auto inputMetrics =
  97. "# A normal comment.\n"
  98. "#\n"
  99. "# TYPE name counter\n"
  100. "name{labelname=\"val1\",basename=\"basevalue\"} NaN\n"
  101. "name {labelname=\"val2\",basename=\"basevalue\"} 2.3 1234567890\n"
  102. "# HELP name two-line\\n doc str\\\\ing\n";
  103. {
  104. auto samples = Decode(inputMetrics);
  105. UNIT_ASSERT_EQUAL(samples.SamplesSize(), 2);
  106. {
  107. auto& s = samples.GetSamples(0);
  108. UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::RATE);
  109. UNIT_ASSERT_EQUAL(s.LabelsSize(), 3);
  110. ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "name");
  111. ASSERT_LABEL_EQUAL(s.GetLabels(1), "basename", "basevalue");
  112. ASSERT_LABEL_EQUAL(s.GetLabels(2), "labelname", "val1");
  113. ASSERT_UINT_POINT(s, TInstant::Zero(), ui64(0));
  114. }
  115. {
  116. auto& s = samples.GetSamples(1);
  117. UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::RATE);
  118. UNIT_ASSERT_EQUAL(s.LabelsSize(), 3);
  119. ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "name");
  120. ASSERT_LABEL_EQUAL(s.GetLabels(1), "basename", "basevalue");
  121. ASSERT_LABEL_EQUAL(s.GetLabels(2), "labelname", "val2");
  122. ASSERT_UINT_POINT(s, TInstant::MilliSeconds(1234567890), i64(2));
  123. }
  124. }
  125. {
  126. TPrometheusDecodeSettings settings;
  127. settings.Mode = EPrometheusDecodeMode::RAW;
  128. auto samples = Decode(inputMetrics, settings);
  129. UNIT_ASSERT_EQUAL(samples.SamplesSize(), 2);
  130. {
  131. auto& s = samples.GetSamples(0);
  132. UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::GAUGE);
  133. UNIT_ASSERT_EQUAL(s.LabelsSize(), 3);
  134. ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "name");
  135. ASSERT_LABEL_EQUAL(s.GetLabels(1), "basename", "basevalue");
  136. ASSERT_LABEL_EQUAL(s.GetLabels(2), "labelname", "val1");
  137. ASSERT_DOUBLE_POINT(s, TInstant::MilliSeconds(0), NAN);
  138. }
  139. {
  140. auto& s = samples.GetSamples(1);
  141. UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::GAUGE);
  142. UNIT_ASSERT_EQUAL(s.LabelsSize(), 3);
  143. ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "name");
  144. ASSERT_LABEL_EQUAL(s.GetLabels(1), "basename", "basevalue");
  145. ASSERT_LABEL_EQUAL(s.GetLabels(2), "labelname", "val2");
  146. ASSERT_DOUBLE_POINT(s, TInstant::MilliSeconds(1234567890), 2.3);
  147. }
  148. }
  149. }
  150. Y_UNIT_TEST(Gauge) {
  151. auto samples = Decode(
  152. "# A normal comment.\n"
  153. "#\n"
  154. " # HELP name2 \tdoc str\"ing 2\n"
  155. " # TYPE name2 gauge\n"
  156. "name2{labelname=\"val2\"\t,basename = \"basevalue2\"\t\t} +Inf 54321\n"
  157. "name2{ labelname = \"val1\" , }-Inf\n");
  158. UNIT_ASSERT_EQUAL(samples.SamplesSize(), 2);
  159. {
  160. auto& s = samples.GetSamples(0);
  161. UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::GAUGE);
  162. UNIT_ASSERT_EQUAL(s.LabelsSize(), 3);
  163. ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "name2");
  164. ASSERT_LABEL_EQUAL(s.GetLabels(1), "basename", "basevalue2");
  165. ASSERT_LABEL_EQUAL(s.GetLabels(2), "labelname", "val2");
  166. ASSERT_DOUBLE_POINT(s, TInstant::MilliSeconds(54321), INFINITY);
  167. }
  168. {
  169. auto& s = samples.GetSamples(1);
  170. UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::GAUGE);
  171. UNIT_ASSERT_EQUAL(s.LabelsSize(), 2);
  172. ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "name2");
  173. ASSERT_LABEL_EQUAL(s.GetLabels(1), "labelname", "val1");
  174. ASSERT_DOUBLE_POINT(s, TInstant::Zero(), -INFINITY);
  175. }
  176. }
  177. Y_UNIT_TEST(Summary) {
  178. auto samples = Decode(
  179. "# HELP \n"
  180. "# TYPE my_summary summary\n"
  181. "my_summary{n1=\"val1\",quantile=\"0.5\"} 110\n"
  182. "my_summary{n1=\"val1\",quantile=\"0.9\"} 140 1\n"
  183. "my_summary_count{n1=\"val1\"} 42\n"
  184. "my_summary_sum{n1=\"val1\"} 08 15\n"
  185. "# some\n"
  186. "# funny comments\n"
  187. "# HELP\n"
  188. "# HELP my_summary\n"
  189. "# HELP my_summary \n");
  190. UNIT_ASSERT_EQUAL(samples.SamplesSize(), 4);
  191. {
  192. auto& s = samples.GetSamples(0);
  193. UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::GAUGE);
  194. UNIT_ASSERT_EQUAL(s.LabelsSize(), 3);
  195. ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "my_summary");
  196. ASSERT_LABEL_EQUAL(s.GetLabels(1), "quantile", "0.5");
  197. ASSERT_LABEL_EQUAL(s.GetLabels(2), "n1", "val1");
  198. ASSERT_DOUBLE_POINT(s, TInstant::Zero(), 110.0);
  199. }
  200. {
  201. auto& s = samples.GetSamples(1);
  202. UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::GAUGE);
  203. UNIT_ASSERT_EQUAL(s.LabelsSize(), 3);
  204. ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "my_summary");
  205. ASSERT_LABEL_EQUAL(s.GetLabels(1), "quantile", "0.9");
  206. ASSERT_LABEL_EQUAL(s.GetLabels(2), "n1", "val1");
  207. ASSERT_DOUBLE_POINT(s, TInstant::MilliSeconds(1), 140.0);
  208. }
  209. {
  210. auto& s = samples.GetSamples(2);
  211. UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::RATE);
  212. UNIT_ASSERT_EQUAL(s.LabelsSize(), 2);
  213. ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "my_summary_count");
  214. ASSERT_LABEL_EQUAL(s.GetLabels(1), "n1", "val1");
  215. ASSERT_UINT_POINT(s, TInstant::Zero(), 42);
  216. }
  217. {
  218. auto& s = samples.GetSamples(3);
  219. UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::GAUGE);
  220. UNIT_ASSERT_EQUAL(s.LabelsSize(), 2);
  221. ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "my_summary_sum");
  222. ASSERT_LABEL_EQUAL(s.GetLabels(1), "n1", "val1");
  223. ASSERT_DOUBLE_POINT(s, TInstant::MilliSeconds(15), 8.0);
  224. }
  225. }
  226. Y_UNIT_TEST(Histogram) {
  227. constexpr auto inputMetrics =
  228. "# HELP request_duration_microseconds The response latency.\n"
  229. "# TYPE request_duration_microseconds histogram\n"
  230. "request_duration_microseconds_bucket{le=\"0\"} 0\n"
  231. "request_duration_microseconds_bucket{le=\"100\"} 123\n"
  232. "request_duration_microseconds_bucket{le=\"120\"} 412\n"
  233. "request_duration_microseconds_bucket{le=\"144\"} 592\n"
  234. "request_duration_microseconds_bucket{le=\"172.8\"} 1524\n"
  235. "request_duration_microseconds_bucket{le=\"+Inf\"} 2693\n"
  236. "request_duration_microseconds_sum 1.7560473e+06\n"
  237. "request_duration_microseconds_count 2693\n";
  238. {
  239. auto samples = Decode(inputMetrics);
  240. {
  241. auto& s = samples.GetSamples(0);
  242. UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::GAUGE);
  243. UNIT_ASSERT_EQUAL(s.LabelsSize(), 1);
  244. ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "request_duration_microseconds_sum");
  245. ASSERT_DOUBLE_POINT(s, TInstant::Zero(), 1756047.3);
  246. }
  247. {
  248. auto& s = samples.GetSamples(1);
  249. UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::RATE);
  250. UNIT_ASSERT_EQUAL(s.LabelsSize(), 1);
  251. ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "request_duration_microseconds_count");
  252. ASSERT_UINT_POINT(s, TInstant::Zero(), 2693);
  253. }
  254. {
  255. auto& s = samples.GetSamples(2);
  256. UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::HIST_RATE);
  257. UNIT_ASSERT_EQUAL(s.LabelsSize(), 1);
  258. ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "request_duration_microseconds");
  259. auto hist = ExplicitHistogramSnapshot(
  260. {0, 100, 120, 144, 172.8, HISTOGRAM_INF_BOUND},
  261. {0, 123, 289, 180, 932, 1169});
  262. ASSERT_HIST_POINT(s, TInstant::Zero(), *hist);
  263. }
  264. }
  265. {
  266. TPrometheusDecodeSettings settings;
  267. settings.Mode = EPrometheusDecodeMode::RAW;
  268. auto samples = Decode(inputMetrics, settings);
  269. UNIT_ASSERT_VALUES_EQUAL(samples.SamplesSize(), 8);
  270. {
  271. auto& s = samples.GetSamples(0);
  272. UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::GAUGE);
  273. UNIT_ASSERT_VALUES_EQUAL(s.LabelsSize(), 2);
  274. ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "request_duration_microseconds_bucket");
  275. ASSERT_LABEL_EQUAL(s.GetLabels(1), "le", "0");
  276. ASSERT_DOUBLE_POINT(s, TInstant::Zero(), 0);
  277. }
  278. }
  279. }
  280. Y_UNIT_TEST(HistogramWithLabels) {
  281. auto samples = Decode(
  282. "# A histogram, which has a pretty complex representation in the text format:\n"
  283. "# HELP http_request_duration_seconds A histogram of the request duration.\n"
  284. "# TYPE http_request_duration_seconds histogram\n"
  285. "http_request_duration_seconds_bucket{le=\"0.05\", method=\"POST\"} 24054\n"
  286. "http_request_duration_seconds_bucket{method=\"POST\", le=\"0.1\"} 33444\n"
  287. "http_request_duration_seconds_bucket{le=\"0.2\", method=\"POST\", } 100392\n"
  288. "http_request_duration_seconds_bucket{le=\"0.5\",method=\"POST\",} 129389\n"
  289. "http_request_duration_seconds_bucket{ method=\"POST\", le=\"1\", } 133988\n"
  290. "http_request_duration_seconds_bucket{ le=\"+Inf\", method=\"POST\", } 144320\n"
  291. "http_request_duration_seconds_sum{method=\"POST\"} 53423\n"
  292. "http_request_duration_seconds_count{ method=\"POST\", } 144320\n");
  293. UNIT_ASSERT_EQUAL(samples.SamplesSize(), 3);
  294. {
  295. auto& s = samples.GetSamples(0);
  296. UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::GAUGE);
  297. UNIT_ASSERT_EQUAL(s.LabelsSize(), 2);
  298. ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "http_request_duration_seconds_sum");
  299. ASSERT_LABEL_EQUAL(s.GetLabels(1), "method", "POST");
  300. ASSERT_DOUBLE_POINT(s, TInstant::Zero(), 53423.0);
  301. }
  302. {
  303. auto& s = samples.GetSamples(1);
  304. UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::RATE);
  305. UNIT_ASSERT_EQUAL(s.LabelsSize(), 2);
  306. ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "http_request_duration_seconds_count");
  307. ASSERT_LABEL_EQUAL(s.GetLabels(1), "method", "POST");
  308. ASSERT_UINT_POINT(s, TInstant::Zero(), 144320);
  309. }
  310. {
  311. auto& s = samples.GetSamples(2);
  312. UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::HIST_RATE);
  313. UNIT_ASSERT_EQUAL(s.LabelsSize(), 2);
  314. ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "http_request_duration_seconds");
  315. ASSERT_LABEL_EQUAL(s.GetLabels(1), "method", "POST");
  316. auto hist = ExplicitHistogramSnapshot(
  317. { 0.05, 0.1, 0.2, 0.5, 1, HISTOGRAM_INF_BOUND },
  318. { 24054, 9390, 66948, 28997, 4599, 10332 });
  319. ASSERT_HIST_POINT(s, TInstant::Zero(), *hist);
  320. }
  321. }
  322. Y_UNIT_TEST(MultipleHistograms) {
  323. auto samples = Decode(
  324. "# TYPE inboundBytesPerSec histogram\n"
  325. "inboundBytesPerSec_bucket{client=\"mbus\", le=\"10.0\"} 1.0\n"
  326. "inboundBytesPerSec_bucket{client=\"mbus\", le=\"20.0\"} 5.0\n"
  327. "inboundBytesPerSec_bucket{client=\"mbus\", le=\"+Inf\"} 5.0\n"
  328. "inboundBytesPerSec_count{client=\"mbus\"} 5.0\n"
  329. "inboundBytesPerSec_bucket{client=\"grpc\", le=\"10.0\"} 1.0\n"
  330. "inboundBytesPerSec_bucket{client=\"grpc\", le=\"20.0\"} 5.0\n"
  331. "inboundBytesPerSec_bucket{client=\"grpc\", le=\"30.0\"} 5.0\n"
  332. "inboundBytesPerSec_count{client=\"grpc\"} 5.0\n"
  333. "# TYPE outboundBytesPerSec histogram\n"
  334. "outboundBytesPerSec_bucket{client=\"grpc\", le=\"100.0\"} 1.0 1512216000000\n"
  335. "outboundBytesPerSec_bucket{client=\"grpc\", le=\"200.0\"} 1.0 1512216000000\n"
  336. "outboundBytesPerSec_bucket{client=\"grpc\", le=\"+Inf\"} 1.0 1512216000000\n"
  337. "outboundBytesPerSec_count{client=\"grpc\"} 1.0 1512216000000\n");
  338. UNIT_ASSERT_EQUAL(samples.SamplesSize(), 6);
  339. {
  340. auto& s = samples.GetSamples(0);
  341. UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::RATE);
  342. UNIT_ASSERT_EQUAL(s.LabelsSize(), 2);
  343. ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "inboundBytesPerSec_count");
  344. ASSERT_LABEL_EQUAL(s.GetLabels(1), "client", "mbus");
  345. ASSERT_UINT_POINT(s, TInstant::Zero(), 5);
  346. }
  347. {
  348. auto& s = samples.GetSamples(1);
  349. UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::HIST_RATE);
  350. UNIT_ASSERT_EQUAL(s.LabelsSize(), 2);
  351. ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "inboundBytesPerSec");
  352. ASSERT_LABEL_EQUAL(s.GetLabels(1), "client", "mbus");
  353. auto hist = ExplicitHistogramSnapshot(
  354. { 10, 20, HISTOGRAM_INF_BOUND },
  355. { 1, 4, 0 });
  356. ASSERT_HIST_POINT(s, TInstant::Zero(), *hist);
  357. }
  358. {
  359. auto& s = samples.GetSamples(2);
  360. UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::RATE);
  361. UNIT_ASSERT_EQUAL(s.LabelsSize(), 2);
  362. ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "inboundBytesPerSec_count");
  363. ASSERT_LABEL_EQUAL(s.GetLabels(1), "client", "grpc");
  364. ASSERT_UINT_POINT(s, TInstant::Zero(), 5);
  365. }
  366. {
  367. auto& s = samples.GetSamples(3);
  368. UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::HIST_RATE);
  369. UNIT_ASSERT_EQUAL(s.LabelsSize(), 2);
  370. ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "inboundBytesPerSec");
  371. ASSERT_LABEL_EQUAL(s.GetLabels(1), "client", "grpc");
  372. auto hist = ExplicitHistogramSnapshot(
  373. { 10, 20, 30 },
  374. { 1, 4, 0 });
  375. ASSERT_HIST_POINT(s, TInstant::Zero(), *hist);
  376. }
  377. {
  378. auto& s = samples.GetSamples(4);
  379. UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::RATE);
  380. UNIT_ASSERT_EQUAL(s.LabelsSize(), 2);
  381. ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "outboundBytesPerSec_count");
  382. ASSERT_LABEL_EQUAL(s.GetLabels(1), "client", "grpc");
  383. ASSERT_UINT_POINT(s, TInstant::Seconds(1512216000), 1) ;
  384. }
  385. {
  386. auto& s = samples.GetSamples(5);
  387. UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::HIST_RATE);
  388. UNIT_ASSERT_EQUAL(s.LabelsSize(), 2);
  389. ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "outboundBytesPerSec");
  390. ASSERT_LABEL_EQUAL(s.GetLabels(1), "client", "grpc");
  391. auto hist = ExplicitHistogramSnapshot(
  392. { 100, 200, HISTOGRAM_INF_BOUND },
  393. { 1, 0, 0 });
  394. ASSERT_HIST_POINT(s, TInstant::Seconds(1512216000), *hist);
  395. }
  396. }
  397. Y_UNIT_TEST(MixedTypes) {
  398. auto samples = Decode(
  399. "# HELP http_requests_total The total number of HTTP requests.\n"
  400. "# TYPE http_requests_total counter\n"
  401. "http_requests_total { } 1027 1395066363000\n"
  402. "http_requests_total{method=\"post\",code=\"200\"} 1027 1395066363000\n"
  403. "http_requests_total{method=\"post\",code=\"400\"} 3 1395066363000\n"
  404. "\n"
  405. "# Minimalistic line:\n"
  406. "metric_without_timestamp_and_labels 12.47\n"
  407. "\n"
  408. "# HELP rpc_duration_seconds A summary of the RPC duration in seconds.\n"
  409. "# TYPE rpc_duration_seconds summary\n"
  410. "rpc_duration_seconds{quantile=\"0.01\"} 3102\n"
  411. "rpc_duration_seconds{quantile=\"0.5\"} 4773\n"
  412. "rpc_duration_seconds{quantile=\"0.9\"} 9001\n"
  413. "rpc_duration_seconds_sum 1.7560473e+07\n"
  414. "rpc_duration_seconds_count 2693\n"
  415. "\n"
  416. "# Another mMinimalistic line:\n"
  417. "metric_with_timestamp 12.47 1234567890\n");
  418. UNIT_ASSERT_EQUAL(samples.SamplesSize(), 10);
  419. {
  420. auto& s = samples.GetSamples(0);
  421. UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::RATE);
  422. UNIT_ASSERT_EQUAL(s.LabelsSize(), 1);
  423. ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "http_requests_total");
  424. ASSERT_UINT_POINT(s, TInstant::Seconds(1395066363), 1027);
  425. }
  426. {
  427. auto& s = samples.GetSamples(1);
  428. UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::RATE);
  429. UNIT_ASSERT_EQUAL(s.LabelsSize(), 3);
  430. ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "http_requests_total");
  431. ASSERT_LABEL_EQUAL(s.GetLabels(1), "method", "post");
  432. ASSERT_LABEL_EQUAL(s.GetLabels(2), "code", "200");
  433. ASSERT_UINT_POINT(s, TInstant::Seconds(1395066363), 1027);
  434. }
  435. {
  436. auto& s = samples.GetSamples(2);
  437. UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::RATE);
  438. UNIT_ASSERT_EQUAL(s.LabelsSize(), 3);
  439. ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "http_requests_total");
  440. ASSERT_LABEL_EQUAL(s.GetLabels(1), "method", "post");
  441. ASSERT_LABEL_EQUAL(s.GetLabels(2), "code", "400");
  442. ASSERT_UINT_POINT(s, TInstant::Seconds(1395066363), 3);
  443. }
  444. {
  445. auto& s = samples.GetSamples(3);
  446. UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::GAUGE);
  447. UNIT_ASSERT_EQUAL(s.LabelsSize(), 1);
  448. ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "metric_without_timestamp_and_labels");
  449. ASSERT_DOUBLE_POINT(s, TInstant::Zero(), 12.47);
  450. }
  451. {
  452. auto& s = samples.GetSamples(4);
  453. UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::GAUGE);
  454. UNIT_ASSERT_EQUAL(s.LabelsSize(), 2);
  455. ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "rpc_duration_seconds");
  456. ASSERT_LABEL_EQUAL(s.GetLabels(1), "quantile", "0.01");
  457. ASSERT_DOUBLE_POINT(s, TInstant::Zero(), 3102);
  458. }
  459. {
  460. auto& s = samples.GetSamples(5);
  461. UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::GAUGE);
  462. UNIT_ASSERT_EQUAL(s.LabelsSize(), 2);
  463. ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "rpc_duration_seconds");
  464. ASSERT_LABEL_EQUAL(s.GetLabels(1), "quantile", "0.5");
  465. ASSERT_DOUBLE_POINT(s, TInstant::Zero(), 4773);
  466. }
  467. {
  468. auto& s = samples.GetSamples(6);
  469. UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::GAUGE);
  470. UNIT_ASSERT_EQUAL(s.LabelsSize(), 2);
  471. ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "rpc_duration_seconds");
  472. ASSERT_LABEL_EQUAL(s.GetLabels(1), "quantile", "0.9");
  473. ASSERT_DOUBLE_POINT(s, TInstant::Zero(), 9001);
  474. }
  475. {
  476. auto& s = samples.GetSamples(7);
  477. UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::GAUGE);
  478. UNIT_ASSERT_EQUAL(s.LabelsSize(), 1);
  479. ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "rpc_duration_seconds_sum");
  480. ASSERT_DOUBLE_POINT(s, TInstant::Zero(), 17560473);
  481. }
  482. {
  483. auto& s = samples.GetSamples(8);
  484. UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::RATE);
  485. UNIT_ASSERT_EQUAL(s.LabelsSize(), 1);
  486. ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "rpc_duration_seconds_count");
  487. ASSERT_UINT_POINT(s, TInstant::Zero(), 2693);
  488. }
  489. {
  490. auto& s = samples.GetSamples(9);
  491. UNIT_ASSERT_EQUAL(s.GetMetricType(), NProto::EMetricType::GAUGE);
  492. UNIT_ASSERT_EQUAL(s.LabelsSize(), 1);
  493. ASSERT_LABEL_EQUAL(s.GetLabels(0), "sensor", "metric_with_timestamp");
  494. ASSERT_DOUBLE_POINT(s, TInstant::MilliSeconds(1234567890), 12.47);
  495. }
  496. }
  497. }