prometheus_encoder_ut.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414
  1. #include "prometheus.h"
  2. #include <library/cpp/monlib/encode/protobuf/protobuf.h>
  3. #include <library/cpp/monlib/metrics/metric_value.h>
  4. #include <library/cpp/monlib/metrics/histogram_snapshot.h>
  5. #include <library/cpp/testing/unittest/registar.h>
  6. #include <util/stream/str.h>
  7. using namespace NMonitoring;
  8. Y_UNIT_TEST_SUITE(TPrometheusEncoderTest) {
  9. template <typename TFunc>
  10. TString EncodeToString(TFunc fn) {
  11. TStringStream ss;
  12. IMetricEncoderPtr encoder = EncoderPrometheus(&ss);
  13. fn(encoder.Get());
  14. return ss.Str();
  15. }
  16. ISummaryDoubleSnapshotPtr TestSummaryDouble() {
  17. return MakeIntrusive<TSummaryDoubleSnapshot>(10.1, -0.45, 0.478, 0.3, 30u);
  18. }
  19. Y_UNIT_TEST(Empty) {
  20. auto result = EncodeToString([](IMetricEncoder* e) {
  21. e->OnStreamBegin();
  22. e->OnStreamEnd();
  23. });
  24. UNIT_ASSERT_STRINGS_EQUAL(result, "\n");
  25. }
  26. Y_UNIT_TEST(DoubleGauge) {
  27. auto result = EncodeToString([](IMetricEncoder* e) {
  28. e->OnStreamBegin();
  29. { // no values
  30. e->OnMetricBegin(EMetricType::GAUGE);
  31. {
  32. e->OnLabelsBegin();
  33. e->OnLabel("sensor", "cpuUsage");
  34. e->OnLabelsEnd();
  35. }
  36. e->OnMetricEnd();
  37. }
  38. { // one value no ts
  39. e->OnMetricBegin(EMetricType::GAUGE);
  40. {
  41. e->OnLabelsBegin();
  42. e->OnLabel("sensor", "diskUsage");
  43. e->OnLabel("disk", "sda1");
  44. e->OnLabelsEnd();
  45. }
  46. e->OnDouble(TInstant::Zero(), 1000);
  47. e->OnMetricEnd();
  48. }
  49. { // one value with ts
  50. e->OnMetricBegin(EMetricType::GAUGE);
  51. {
  52. e->OnLabelsBegin();
  53. e->OnLabel("sensor", "memoryUsage");
  54. e->OnLabel("host", "solomon-man-00");
  55. e->OnLabel("dc", "man");
  56. e->OnLabelsEnd();
  57. }
  58. e->OnDouble(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:00Z"), 1000);
  59. e->OnMetricEnd();
  60. }
  61. { // many values
  62. e->OnMetricBegin(EMetricType::GAUGE);
  63. {
  64. e->OnLabelsBegin();
  65. e->OnLabel("sensor", "bytesRx");
  66. e->OnLabel("host", "solomon-sas-01");
  67. e->OnLabel("dc", "sas");
  68. e->OnLabelsEnd();
  69. }
  70. e->OnDouble(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:00Z"), 2);
  71. e->OnDouble(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:05Z"), 4);
  72. e->OnDouble(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:10Z"), 8);
  73. e->OnMetricEnd();
  74. }
  75. { // already seen metric name
  76. e->OnMetricBegin(EMetricType::GAUGE);
  77. {
  78. e->OnLabelsBegin();
  79. e->OnLabel("sensor", "diskUsage");
  80. e->OnLabel("disk", "sdb1");
  81. e->OnLabelsEnd();
  82. }
  83. e->OnDouble(TInstant::Zero(), 1001);
  84. e->OnMetricEnd();
  85. }
  86. { // NaN
  87. e->OnMetricBegin(EMetricType::GAUGE);
  88. {
  89. e->OnLabelsBegin();
  90. e->OnLabel("sensor", "nanValue");
  91. e->OnLabelsEnd();
  92. }
  93. e->OnDouble(TInstant::Zero(), NAN);
  94. e->OnMetricEnd();
  95. }
  96. { // Inf
  97. e->OnMetricBegin(EMetricType::GAUGE);
  98. {
  99. e->OnLabelsBegin();
  100. e->OnLabel("sensor", "infValue");
  101. e->OnLabelsEnd();
  102. }
  103. e->OnDouble(TInstant::Zero(), INFINITY);
  104. e->OnMetricEnd();
  105. }
  106. {
  107. e->OnMetricBegin(EMetricType::DSUMMARY);
  108. {
  109. e->OnLabelsBegin();
  110. e->OnLabel("sensor", "seconds");
  111. e->OnLabel("disk", "sdb1");
  112. e->OnLabelsEnd();
  113. }
  114. e->OnSummaryDouble(TInstant::Zero(), TestSummaryDouble());
  115. e->OnMetricEnd();
  116. }
  117. e->OnStreamEnd();
  118. });
  119. UNIT_ASSERT_STRINGS_EQUAL(result,
  120. "# TYPE diskUsage gauge\n"
  121. "diskUsage{disk=\"sda1\", } 1000\n"
  122. "# TYPE memoryUsage gauge\n"
  123. "memoryUsage{host=\"solomon-man-00\", dc=\"man\", } 1000 1512216000000\n"
  124. "# TYPE bytesRx gauge\n"
  125. "bytesRx{host=\"solomon-sas-01\", dc=\"sas\", } 8 1512216010000\n"
  126. "diskUsage{disk=\"sdb1\", } 1001\n"
  127. "# TYPE nanValue gauge\n"
  128. "nanValue nan\n"
  129. "# TYPE infValue gauge\n"
  130. "infValue inf\n"
  131. "seconds_sum{disk=\"sdb1\", } 10.1\n"
  132. "seconds_min{disk=\"sdb1\", } -0.45\n"
  133. "seconds_max{disk=\"sdb1\", } 0.478\n"
  134. "seconds_last{disk=\"sdb1\", } 0.3\n"
  135. "seconds_count{disk=\"sdb1\", } 30\n"
  136. "\n");
  137. }
  138. Y_UNIT_TEST(IntGauges) {
  139. auto result = EncodeToString([](IMetricEncoder* e) {
  140. e->OnStreamBegin();
  141. { // no values
  142. e->OnMetricBegin(EMetricType::IGAUGE);
  143. {
  144. e->OnLabelsBegin();
  145. e->OnLabel("sensor", "cpuUsage");
  146. e->OnLabelsEnd();
  147. }
  148. e->OnMetricEnd();
  149. }
  150. { // one value no ts
  151. e->OnMetricBegin(EMetricType::IGAUGE);
  152. {
  153. e->OnLabelsBegin();
  154. e->OnLabel("sensor", "diskUsage");
  155. e->OnLabel("disk", "sda1");
  156. e->OnLabelsEnd();
  157. }
  158. e->OnInt64(TInstant::Zero(), 1000);
  159. e->OnMetricEnd();
  160. }
  161. { // one value with ts
  162. e->OnMetricBegin(EMetricType::IGAUGE);
  163. {
  164. e->OnLabelsBegin();
  165. e->OnLabel("sensor", "memoryUsage");
  166. e->OnLabel("dc", "man");
  167. e->OnLabel("host", "solomon-man-00");
  168. e->OnLabelsEnd();
  169. }
  170. e->OnInt64(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:00Z"), 1000);
  171. e->OnMetricEnd();
  172. }
  173. { // many values
  174. e->OnMetricBegin(EMetricType::IGAUGE);
  175. {
  176. e->OnLabelsBegin();
  177. e->OnLabel("sensor", "bytesRx");
  178. e->OnLabel("dc", "sas");
  179. e->OnLabel("host", "solomon-sas-01");
  180. e->OnLabelsEnd();
  181. }
  182. e->OnInt64(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:00Z"), 2);
  183. e->OnInt64(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:05Z"), 4);
  184. e->OnInt64(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:10Z"), 8);
  185. e->OnMetricEnd();
  186. }
  187. e->OnStreamEnd();
  188. });
  189. UNIT_ASSERT_STRINGS_EQUAL(result,
  190. "# TYPE diskUsage gauge\n"
  191. "diskUsage{disk=\"sda1\", } 1000\n"
  192. "# TYPE memoryUsage gauge\n"
  193. "memoryUsage{dc=\"man\", host=\"solomon-man-00\", } 1000 1512216000000\n"
  194. "# TYPE bytesRx gauge\n"
  195. "bytesRx{dc=\"sas\", host=\"solomon-sas-01\", } 8 1512216010000\n"
  196. "\n");
  197. }
  198. Y_UNIT_TEST(Counters) {
  199. auto result = EncodeToString([](IMetricEncoder* e) {
  200. e->OnStreamBegin();
  201. { // no values
  202. e->OnMetricBegin(EMetricType::COUNTER);
  203. {
  204. e->OnLabelsBegin();
  205. e->OnLabel("sensor", "cpuUsage");
  206. e->OnLabelsEnd();
  207. }
  208. e->OnMetricEnd();
  209. }
  210. { // one value no ts
  211. e->OnMetricBegin(EMetricType::COUNTER);
  212. {
  213. e->OnLabelsBegin();
  214. e->OnLabel("sensor", "diskUsage");
  215. e->OnLabel("disk", "sda1");
  216. e->OnLabelsEnd();
  217. }
  218. e->OnInt64(TInstant::Zero(), 1000);
  219. e->OnMetricEnd();
  220. }
  221. { // one value with ts
  222. e->OnMetricBegin(EMetricType::COUNTER);
  223. {
  224. e->OnLabelsBegin();
  225. e->OnLabel("sensor", "memoryUsage");
  226. e->OnLabel("host", "solomon-man-00");
  227. e->OnLabel("dc", "man");
  228. e->OnLabelsEnd();
  229. }
  230. e->OnInt64(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:00Z"), 1000);
  231. e->OnMetricEnd();
  232. }
  233. { // many values
  234. e->OnMetricBegin(EMetricType::COUNTER);
  235. {
  236. e->OnLabelsBegin();
  237. e->OnLabel("sensor", "bytesRx");
  238. e->OnLabel("host", "solomon-sas-01");
  239. e->OnLabel("dc", "sas");
  240. e->OnLabelsEnd();
  241. }
  242. e->OnInt64(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:00Z"), 2);
  243. e->OnInt64(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:05Z"), 4);
  244. e->OnInt64(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:10Z"), 8);
  245. e->OnMetricEnd();
  246. }
  247. e->OnStreamEnd();
  248. });
  249. UNIT_ASSERT_STRINGS_EQUAL(result,
  250. "# TYPE diskUsage counter\n"
  251. "diskUsage{disk=\"sda1\", } 1000\n"
  252. "# TYPE memoryUsage counter\n"
  253. "memoryUsage{host=\"solomon-man-00\", dc=\"man\", } 1000 1512216000000\n"
  254. "# TYPE bytesRx counter\n"
  255. "bytesRx{host=\"solomon-sas-01\", dc=\"sas\", } 8 1512216010000\n"
  256. "\n");
  257. }
  258. Y_UNIT_TEST(Histograms) {
  259. auto result = EncodeToString([](IMetricEncoder* e) {
  260. e->OnStreamBegin();
  261. { // no values histogram
  262. e->OnMetricBegin(EMetricType::HIST);
  263. {
  264. e->OnLabelsBegin();
  265. e->OnLabel("sensor", "cpuUsage");
  266. e->OnLabelsEnd();
  267. }
  268. e->OnMetricEnd();
  269. }
  270. { // one value no ts
  271. e->OnMetricBegin(EMetricType::HIST);
  272. {
  273. e->OnLabelsBegin();
  274. e->OnLabel("sensor", "inboundBytesPerSec");
  275. e->OnLabel("client", "mbus");
  276. e->OnLabelsEnd();
  277. }
  278. e->OnHistogram(
  279. TInstant::Zero(),
  280. ExplicitHistogramSnapshot({10, 20, HISTOGRAM_INF_BOUND}, {1, 4, 0}));
  281. e->OnMetricEnd();
  282. }
  283. { // one value no ts no +inf bucket
  284. e->OnMetricBegin(EMetricType::HIST);
  285. {
  286. e->OnLabelsBegin();
  287. e->OnLabel("sensor", "inboundBytesPerSec");
  288. e->OnLabel("client", "grpc");
  289. e->OnLabelsEnd();
  290. }
  291. e->OnHistogram(
  292. TInstant::Zero(),
  293. ExplicitHistogramSnapshot({10, 20, 30}, {1, 4, 0}));
  294. e->OnMetricEnd();
  295. }
  296. { // one value with ts
  297. e->OnMetricBegin(EMetricType::HIST_RATE);
  298. {
  299. e->OnLabelsBegin();
  300. e->OnLabel("sensor", "outboundBytesPerSec");
  301. e->OnLabel("client", "grps");
  302. e->OnLabelsEnd();
  303. }
  304. e->OnHistogram(
  305. TInstant::ParseIso8601Deprecated("2017-12-02T12:00:00Z"),
  306. ExplicitHistogramSnapshot({100, 200, HISTOGRAM_INF_BOUND}, {1, 0, 0}));
  307. e->OnMetricEnd();
  308. }
  309. { // many values
  310. e->OnMetricBegin(EMetricType::HIST);
  311. {
  312. e->OnLabelsBegin();
  313. e->OnLabel("sensor", "bytesRx");
  314. e->OnLabel("host", "solomon-sas-01");
  315. e->OnLabel("dc", "sas");
  316. e->OnLabelsEnd();
  317. }
  318. TBucketBounds bounds = {100, 200, HISTOGRAM_INF_BOUND};
  319. e->OnHistogram(
  320. TInstant::ParseIso8601Deprecated("2017-12-02T12:00:00Z"),
  321. ExplicitHistogramSnapshot(bounds, {10, 0, 0}));
  322. e->OnHistogram(
  323. TInstant::ParseIso8601Deprecated("2017-12-02T12:00:05Z"),
  324. ExplicitHistogramSnapshot(bounds, {10, 2, 0}));
  325. e->OnHistogram(
  326. TInstant::ParseIso8601Deprecated("2017-12-02T12:00:10Z"),
  327. ExplicitHistogramSnapshot(bounds, {10, 2, 5}));
  328. e->OnMetricEnd();
  329. }
  330. e->OnStreamEnd();
  331. });
  332. UNIT_ASSERT_STRINGS_EQUAL(result,
  333. "# TYPE inboundBytesPerSec histogram\n"
  334. "inboundBytesPerSec_bucket{client=\"mbus\", le=\"10\"} 1\n"
  335. "inboundBytesPerSec_bucket{client=\"mbus\", le=\"20\"} 5\n"
  336. "inboundBytesPerSec_bucket{client=\"mbus\", le=\"+Inf\"} 5\n"
  337. "inboundBytesPerSec_count{client=\"mbus\", } 5\n"
  338. "inboundBytesPerSec_bucket{client=\"grpc\", le=\"10\"} 1\n"
  339. "inboundBytesPerSec_bucket{client=\"grpc\", le=\"20\"} 5\n"
  340. "inboundBytesPerSec_bucket{client=\"grpc\", le=\"30\"} 5\n"
  341. "inboundBytesPerSec_count{client=\"grpc\", } 5\n"
  342. "# TYPE outboundBytesPerSec histogram\n"
  343. "outboundBytesPerSec_bucket{client=\"grps\", le=\"100\"} 1 1512216000000\n"
  344. "outboundBytesPerSec_bucket{client=\"grps\", le=\"200\"} 1 1512216000000\n"
  345. "outboundBytesPerSec_bucket{client=\"grps\", le=\"+Inf\"} 1 1512216000000\n"
  346. "outboundBytesPerSec_count{client=\"grps\", } 1 1512216000000\n"
  347. "# TYPE bytesRx histogram\n"
  348. "bytesRx_bucket{host=\"solomon-sas-01\", dc=\"sas\", le=\"100\"} 10 1512216010000\n"
  349. "bytesRx_bucket{host=\"solomon-sas-01\", dc=\"sas\", le=\"200\"} 12 1512216010000\n"
  350. "bytesRx_bucket{host=\"solomon-sas-01\", dc=\"sas\", le=\"+Inf\"} 17 1512216010000\n"
  351. "bytesRx_count{host=\"solomon-sas-01\", dc=\"sas\", } 17 1512216010000\n"
  352. "\n");
  353. }
  354. Y_UNIT_TEST(CommonLables) {
  355. auto result = EncodeToString([](IMetricEncoder* e) {
  356. e->OnStreamBegin();
  357. { // common time
  358. e->OnCommonTime(TInstant::Seconds(1500000000));
  359. }
  360. { // common labels
  361. e->OnLabelsBegin();
  362. e->OnLabel("project", "solomon");
  363. e->OnLabelsEnd();
  364. }
  365. { // metric #1
  366. e->OnMetricBegin(EMetricType::COUNTER);
  367. {
  368. e->OnLabelsBegin();
  369. e->OnLabel("sensor", "single");
  370. e->OnLabel("labels", "l1");
  371. e->OnLabelsEnd();
  372. }
  373. e->OnUint64(TInstant::ParseIso8601Deprecated("2017-12-02T12:00:10Z"), 17);
  374. e->OnMetricEnd();
  375. }
  376. { // metric #2
  377. e->OnMetricBegin(EMetricType::COUNTER);
  378. {
  379. e->OnLabelsBegin();
  380. e->OnLabel("sensor", "two");
  381. e->OnLabel("labels", "l2");
  382. e->OnLabelsEnd();
  383. }
  384. e->OnUint64(TInstant::Zero(), 42);
  385. e->OnMetricEnd();
  386. }
  387. e->OnStreamEnd();
  388. });
  389. UNIT_ASSERT_STRINGS_EQUAL(result,
  390. R"(# TYPE single counter
  391. single{labels="l1", project="solomon", } 17 1512216010000
  392. # TYPE two counter
  393. two{labels="l2", project="solomon", } 42 1500000000000
  394. )");
  395. }
  396. }