ostream_metric_test.cc 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413
  1. // Copyright The OpenTelemetry Authors
  2. // SPDX-License-Identifier: Apache-2.0
  3. #include <gtest/gtest.h>
  4. #include <cstdint>
  5. #include <iostream>
  6. #include <sstream>
  7. #include <string>
  8. #include <vector>
  9. #include "opentelemetry/common/timestamp.h"
  10. #include "opentelemetry/exporters/ostream/metric_exporter.h"
  11. #include "opentelemetry/nostd/unique_ptr.h"
  12. #include "opentelemetry/sdk/common/exporter_utils.h"
  13. #include "opentelemetry/sdk/instrumentationscope/instrumentation_scope.h"
  14. #include "opentelemetry/sdk/metrics/data/circular_buffer.h"
  15. #include "opentelemetry/sdk/metrics/data/metric_data.h"
  16. #include "opentelemetry/sdk/metrics/data/point_data.h"
  17. #include "opentelemetry/sdk/metrics/export/metric_producer.h"
  18. #include "opentelemetry/sdk/metrics/instruments.h"
  19. #include "opentelemetry/sdk/metrics/push_metric_exporter.h"
  20. #include "opentelemetry/sdk/resource/resource.h"
  21. #include "opentelemetry/sdk/version/version.h"
  22. namespace metric_sdk = opentelemetry::sdk::metrics;
  23. namespace nostd = opentelemetry::nostd;
  24. namespace exportermetrics = opentelemetry::exporter::metrics;
  25. TEST(OStreamMetricsExporter, Shutdown)
  26. {
  27. auto exporter =
  28. std::unique_ptr<metric_sdk::PushMetricExporter>(new exportermetrics::OStreamMetricExporter);
  29. ASSERT_TRUE(exporter->Shutdown());
  30. auto result = exporter->Export(metric_sdk::ResourceMetrics{});
  31. EXPECT_EQ(result, opentelemetry::sdk::common::ExportResult::kFailure);
  32. }
  33. TEST(OStreamMetricsExporter, ExportSumPointData)
  34. {
  35. auto exporter =
  36. std::unique_ptr<metric_sdk::PushMetricExporter>(new exportermetrics::OStreamMetricExporter);
  37. metric_sdk::SumPointData sum_point_data{};
  38. sum_point_data.value_ = 10.0;
  39. metric_sdk::SumPointData sum_point_data2{};
  40. sum_point_data2.value_ = 20.0;
  41. metric_sdk::ResourceMetrics data;
  42. auto resource = opentelemetry::sdk::resource::Resource::Create(
  43. opentelemetry::sdk::resource::ResourceAttributes{});
  44. data.resource_ = &resource;
  45. auto scope = opentelemetry::sdk::instrumentationscope::InstrumentationScope::Create(
  46. "library_name", "1.2.0");
  47. metric_sdk::MetricData metric_data{
  48. metric_sdk::InstrumentDescriptor{"library_name", "description", "unit",
  49. metric_sdk::InstrumentType::kCounter,
  50. metric_sdk::InstrumentValueType::kDouble},
  51. metric_sdk::AggregationTemporality::kDelta, opentelemetry::common::SystemTimestamp{},
  52. opentelemetry::common::SystemTimestamp{},
  53. std::vector<metric_sdk::PointDataAttributes>{
  54. {metric_sdk::PointAttributes{{"a1", "b1"}}, sum_point_data},
  55. {metric_sdk::PointAttributes{{"a1", "b1"}}, sum_point_data2}}};
  56. data.scope_metric_data_ = std::vector<metric_sdk::ScopeMetrics>{
  57. {scope.get(), std::vector<metric_sdk::MetricData>{metric_data}}};
  58. std::stringstream stdoutOutput;
  59. std::streambuf *sbuf = std::cout.rdbuf();
  60. std::cout.rdbuf(stdoutOutput.rdbuf());
  61. auto result = exporter->Export(data);
  62. EXPECT_EQ(result, opentelemetry::sdk::common::ExportResult::kSuccess);
  63. std::cout.rdbuf(sbuf);
  64. std::string expected_output =
  65. "{"
  66. "\n scope name\t: library_name"
  67. "\n schema url\t: "
  68. "\n version\t: 1.2.0"
  69. "\n start time\t: Thu Jan 1 00:00:00 1970"
  70. "\n end time\t: Thu Jan 1 00:00:00 1970"
  71. "\n instrument name\t: library_name"
  72. "\n description\t: description"
  73. "\n unit\t\t: unit"
  74. "\n type\t\t: SumPointData"
  75. "\n value\t\t: 10"
  76. "\n attributes\t\t: "
  77. "\n\ta1: b1"
  78. "\n type\t\t: SumPointData"
  79. "\n value\t\t: 20"
  80. "\n attributes\t\t: "
  81. "\n\ta1: b1"
  82. "\n resources\t:"
  83. "\n\tservice.name: unknown_service"
  84. "\n\ttelemetry.sdk.language: cpp"
  85. "\n\ttelemetry.sdk.name: opentelemetry"
  86. "\n\ttelemetry.sdk.version: ";
  87. expected_output += OPENTELEMETRY_SDK_VERSION;
  88. expected_output += "\n}\n";
  89. ASSERT_EQ(stdoutOutput.str(), expected_output);
  90. }
  91. TEST(OStreamMetricsExporter, ExportHistogramPointData)
  92. {
  93. auto exporter =
  94. std::unique_ptr<metric_sdk::PushMetricExporter>(new exportermetrics::OStreamMetricExporter);
  95. metric_sdk::HistogramPointData histogram_point_data{};
  96. histogram_point_data.boundaries_ = std::vector<double>{10.1, 20.2, 30.2};
  97. histogram_point_data.count_ = 3;
  98. histogram_point_data.counts_ = {200, 300, 400, 500};
  99. histogram_point_data.sum_ = 900.5;
  100. histogram_point_data.min_ = 1.8;
  101. histogram_point_data.max_ = 12.0;
  102. metric_sdk::HistogramPointData histogram_point_data2{};
  103. histogram_point_data2.boundaries_ = std::vector<double>{10.0, 20.0, 30.0};
  104. histogram_point_data2.count_ = 3;
  105. histogram_point_data2.counts_ = {200, 300, 400, 500};
  106. histogram_point_data2.sum_ = static_cast<int64_t>(900);
  107. metric_sdk::ResourceMetrics data;
  108. auto resource = opentelemetry::sdk::resource::Resource::Create(
  109. opentelemetry::sdk::resource::ResourceAttributes{});
  110. data.resource_ = &resource;
  111. auto scope = opentelemetry::sdk::instrumentationscope::InstrumentationScope::Create(
  112. "library_name", "1.2.0");
  113. metric_sdk::MetricData metric_data{
  114. metric_sdk::InstrumentDescriptor{"library_name", "description", "unit",
  115. metric_sdk::InstrumentType::kCounter,
  116. metric_sdk::InstrumentValueType::kDouble},
  117. metric_sdk::AggregationTemporality::kDelta, opentelemetry::common::SystemTimestamp{},
  118. opentelemetry::common::SystemTimestamp{},
  119. std::vector<metric_sdk::PointDataAttributes>{
  120. {metric_sdk::PointAttributes{{"a1", "b1"}, {"a2", "b2"}}, histogram_point_data},
  121. {metric_sdk::PointAttributes{{"a1", "b1"}}, histogram_point_data2}}};
  122. data.scope_metric_data_ = std::vector<metric_sdk::ScopeMetrics>{
  123. {scope.get(), std::vector<metric_sdk::MetricData>{metric_data}}};
  124. std::stringstream stdoutOutput;
  125. std::streambuf *sbuf = std::cout.rdbuf();
  126. std::cout.rdbuf(stdoutOutput.rdbuf());
  127. auto result = exporter->Export(data);
  128. EXPECT_EQ(result, opentelemetry::sdk::common::ExportResult::kSuccess);
  129. std::cout.rdbuf(sbuf);
  130. std::string expected_output =
  131. "{"
  132. "\n scope name\t: library_name"
  133. "\n schema url\t: "
  134. "\n version\t: 1.2.0"
  135. "\n start time\t: Thu Jan 1 00:00:00 1970"
  136. "\n end time\t: Thu Jan 1 00:00:00 1970"
  137. "\n instrument name\t: library_name"
  138. "\n description\t: description"
  139. "\n unit\t\t: unit"
  140. "\n type : HistogramPointData"
  141. "\n count : 3"
  142. "\n sum : 900.5"
  143. "\n min : 1.8"
  144. "\n max : 12"
  145. "\n buckets : [10.1, 20.2, 30.2, ]"
  146. "\n counts : [200, 300, 400, 500, ]"
  147. "\n attributes\t\t: "
  148. "\n\ta1: b1"
  149. "\n\ta2: b2"
  150. "\n type : HistogramPointData"
  151. "\n count : 3"
  152. "\n sum : 900"
  153. "\n min : 0"
  154. "\n max : 0"
  155. "\n buckets : [10, 20, 30, ]"
  156. "\n counts : [200, 300, 400, 500, ]"
  157. "\n attributes\t\t: "
  158. "\n\ta1: b1"
  159. "\n resources\t:"
  160. "\n\tservice.name: unknown_service"
  161. "\n\ttelemetry.sdk.language: cpp"
  162. "\n\ttelemetry.sdk.name: opentelemetry"
  163. "\n\ttelemetry.sdk.version: ";
  164. expected_output += OPENTELEMETRY_SDK_VERSION;
  165. expected_output += "\n}\n";
  166. ASSERT_EQ(stdoutOutput.str(), expected_output);
  167. }
  168. TEST(OStreamMetricsExporter, ExportBase2ExponentialHistogramPointData)
  169. {
  170. auto exporter =
  171. std::unique_ptr<metric_sdk::PushMetricExporter>(new exportermetrics::OStreamMetricExporter);
  172. metric_sdk::Base2ExponentialHistogramPointData histogram_point_data1;
  173. histogram_point_data1.count_ = 3;
  174. histogram_point_data1.sum_ = 6.5;
  175. histogram_point_data1.min_ = 0.0;
  176. histogram_point_data1.max_ = 3.5;
  177. histogram_point_data1.scale_ = 3;
  178. histogram_point_data1.record_min_max_ = true;
  179. histogram_point_data1.zero_count_ = 1;
  180. histogram_point_data1.positive_buckets_ =
  181. std::make_unique<opentelemetry::sdk::metrics::AdaptingCircularBufferCounter>(10);
  182. histogram_point_data1.negative_buckets_ =
  183. std::make_unique<opentelemetry::sdk::metrics::AdaptingCircularBufferCounter>(10);
  184. histogram_point_data1.positive_buckets_->Increment(1, 1);
  185. histogram_point_data1.negative_buckets_->Increment(-2, 1);
  186. metric_sdk::Base2ExponentialHistogramPointData histogram_point_data2;
  187. histogram_point_data2.count_ = 4;
  188. histogram_point_data2.sum_ = 6.2;
  189. histogram_point_data2.min_ = -0.03;
  190. histogram_point_data2.max_ = 3.5;
  191. histogram_point_data2.scale_ = 3;
  192. histogram_point_data2.record_min_max_ = false;
  193. histogram_point_data2.zero_count_ = 2;
  194. histogram_point_data2.positive_buckets_ =
  195. std::make_unique<opentelemetry::sdk::metrics::AdaptingCircularBufferCounter>(10);
  196. histogram_point_data2.negative_buckets_ =
  197. std::make_unique<opentelemetry::sdk::metrics::AdaptingCircularBufferCounter>(10);
  198. histogram_point_data2.positive_buckets_->Increment(3, 1);
  199. histogram_point_data2.negative_buckets_->Increment(-2, 1);
  200. histogram_point_data2.negative_buckets_->Increment(-4, 2);
  201. metric_sdk::ResourceMetrics data;
  202. auto resource = opentelemetry::sdk::resource::Resource::Create(
  203. opentelemetry::sdk::resource::ResourceAttributes{});
  204. data.resource_ = &resource;
  205. auto scope = opentelemetry::sdk::instrumentationscope::InstrumentationScope::Create(
  206. "library_name", "1.2.0");
  207. metric_sdk::MetricData metric_data{
  208. metric_sdk::InstrumentDescriptor{"library_name", "description", "unit",
  209. metric_sdk::InstrumentType::kCounter,
  210. metric_sdk::InstrumentValueType::kDouble},
  211. metric_sdk::AggregationTemporality::kDelta, opentelemetry::common::SystemTimestamp{},
  212. opentelemetry::common::SystemTimestamp{},
  213. std::vector<metric_sdk::PointDataAttributes>{
  214. {metric_sdk::PointAttributes{{"a1", "b1"}, {"a2", "b2"}}, histogram_point_data1},
  215. {metric_sdk::PointAttributes{{"a1", "b1"}}, histogram_point_data2}}};
  216. data.scope_metric_data_ = std::vector<metric_sdk::ScopeMetrics>{
  217. {scope.get(), std::vector<metric_sdk::MetricData>{metric_data}}};
  218. std::stringstream stdoutOutput;
  219. std::streambuf *sbuf = std::cout.rdbuf();
  220. std::cout.rdbuf(stdoutOutput.rdbuf());
  221. auto result = exporter->Export(data);
  222. EXPECT_EQ(result, opentelemetry::sdk::common::ExportResult::kSuccess);
  223. std::cout.rdbuf(sbuf);
  224. std::string expected_output =
  225. "{"
  226. "\n scope name\t: library_name"
  227. "\n schema url\t: "
  228. "\n version\t: 1.2.0"
  229. "\n start time\t: Thu Jan 1 00:00:00 1970"
  230. "\n end time\t: Thu Jan 1 00:00:00 1970"
  231. "\n instrument name\t: library_name"
  232. "\n description\t: description"
  233. "\n unit\t\t: unit"
  234. "\n type: Base2ExponentialHistogramPointData"
  235. "\n count: 3"
  236. "\n sum: 6.5"
  237. "\n zero_count: 1"
  238. "\n min: 0"
  239. "\n max: 3.5"
  240. "\n scale: 3"
  241. "\n positive buckets:"
  242. "\n\t1: 1"
  243. "\n negative buckets:"
  244. "\n\t-2: 1"
  245. "\n attributes\t\t: "
  246. "\n\ta1: b1"
  247. "\n\ta2: b2"
  248. "\n type: Base2ExponentialHistogramPointData"
  249. "\n count: 4"
  250. "\n sum: 6.2"
  251. "\n zero_count: 2"
  252. "\n scale: 3"
  253. "\n positive buckets:"
  254. "\n\t3: 1"
  255. "\n negative buckets:"
  256. "\n\t-4: 2"
  257. "\n\t-3: 0"
  258. "\n\t-2: 1"
  259. "\n attributes\t\t: "
  260. "\n\ta1: b1"
  261. "\n resources\t:"
  262. "\n\tservice.name: unknown_service"
  263. "\n\ttelemetry.sdk.language: cpp"
  264. "\n\ttelemetry.sdk.name: opentelemetry"
  265. "\n\ttelemetry.sdk.version: ";
  266. expected_output += OPENTELEMETRY_SDK_VERSION;
  267. expected_output += "\n}\n";
  268. ASSERT_EQ(stdoutOutput.str(), expected_output);
  269. }
  270. TEST(OStreamMetricsExporter, ExportLastValuePointData)
  271. {
  272. auto exporter =
  273. std::unique_ptr<metric_sdk::PushMetricExporter>(new exportermetrics::OStreamMetricExporter);
  274. metric_sdk::ResourceMetrics data;
  275. auto resource = opentelemetry::sdk::resource::Resource::Create(
  276. opentelemetry::sdk::resource::ResourceAttributes{});
  277. data.resource_ = &resource;
  278. auto scope = opentelemetry::sdk::instrumentationscope::InstrumentationScope::Create(
  279. "library_name", "1.2.0");
  280. metric_sdk::LastValuePointData last_value_point_data{};
  281. last_value_point_data.value_ = 10.0;
  282. last_value_point_data.is_lastvalue_valid_ = true;
  283. last_value_point_data.sample_ts_ = opentelemetry::common::SystemTimestamp{};
  284. metric_sdk::LastValuePointData last_value_point_data2{};
  285. last_value_point_data2.value_ = static_cast<int64_t>(20);
  286. last_value_point_data2.is_lastvalue_valid_ = true;
  287. last_value_point_data2.sample_ts_ = opentelemetry::common::SystemTimestamp{};
  288. metric_sdk::MetricData metric_data{
  289. metric_sdk::InstrumentDescriptor{"library_name", "description", "unit",
  290. metric_sdk::InstrumentType::kCounter,
  291. metric_sdk::InstrumentValueType::kDouble},
  292. metric_sdk::AggregationTemporality::kDelta, opentelemetry::common::SystemTimestamp{},
  293. opentelemetry::common::SystemTimestamp{},
  294. std::vector<metric_sdk::PointDataAttributes>{
  295. {metric_sdk::PointAttributes{}, last_value_point_data},
  296. {metric_sdk::PointAttributes{}, last_value_point_data2}}};
  297. data.scope_metric_data_ = std::vector<metric_sdk::ScopeMetrics>{
  298. {scope.get(), std::vector<metric_sdk::MetricData>{metric_data}}};
  299. std::stringstream stdoutOutput;
  300. std::streambuf *sbuf = std::cout.rdbuf();
  301. std::cout.rdbuf(stdoutOutput.rdbuf());
  302. auto result = exporter->Export(data);
  303. EXPECT_EQ(result, opentelemetry::sdk::common::ExportResult::kSuccess);
  304. std::cout.rdbuf(sbuf);
  305. std::string expected_output =
  306. "{"
  307. "\n scope name\t: library_name"
  308. "\n schema url\t: "
  309. "\n version\t: 1.2.0"
  310. "\n start time\t: Thu Jan 1 00:00:00 1970"
  311. "\n end time\t: Thu Jan 1 00:00:00 1970"
  312. "\n instrument name\t: library_name"
  313. "\n description\t: description"
  314. "\n unit\t\t: unit"
  315. "\n type : LastValuePointData"
  316. "\n timestamp : 0"
  317. "\n valid : true"
  318. "\n value : 10"
  319. "\n attributes\t\t: "
  320. "\n type : LastValuePointData"
  321. "\n timestamp : 0"
  322. "\n valid : true"
  323. "\n value : 20"
  324. "\n attributes\t\t: "
  325. "\n resources\t:"
  326. "\n\tservice.name: unknown_service"
  327. "\n\ttelemetry.sdk.language: cpp"
  328. "\n\ttelemetry.sdk.name: opentelemetry"
  329. "\n\ttelemetry.sdk.version: ";
  330. expected_output += OPENTELEMETRY_SDK_VERSION;
  331. expected_output += "\n}\n";
  332. ASSERT_EQ(stdoutOutput.str(), expected_output);
  333. }
  334. TEST(OStreamMetricsExporter, ExportDropPointData)
  335. {
  336. auto exporter =
  337. std::unique_ptr<metric_sdk::PushMetricExporter>(new exportermetrics::OStreamMetricExporter);
  338. metric_sdk::ResourceMetrics data;
  339. auto resource = opentelemetry::sdk::resource::Resource::Create(
  340. opentelemetry::sdk::resource::ResourceAttributes{});
  341. data.resource_ = &resource;
  342. auto scope = opentelemetry::sdk::instrumentationscope::InstrumentationScope::Create(
  343. "library_name", "1.2.0");
  344. metric_sdk::DropPointData drop_point_data{};
  345. metric_sdk::DropPointData drop_point_data2{};
  346. metric_sdk::MetricData metric_data{
  347. metric_sdk::InstrumentDescriptor{"library_name", "description", "unit",
  348. metric_sdk::InstrumentType::kCounter,
  349. metric_sdk::InstrumentValueType::kDouble},
  350. metric_sdk::AggregationTemporality::kDelta, opentelemetry::common::SystemTimestamp{},
  351. opentelemetry::common::SystemTimestamp{},
  352. std::vector<metric_sdk::PointDataAttributes>{
  353. {metric_sdk::PointAttributes{}, drop_point_data},
  354. {metric_sdk::PointAttributes{}, drop_point_data2}}};
  355. data.scope_metric_data_ = std::vector<metric_sdk::ScopeMetrics>{
  356. {scope.get(), std::vector<metric_sdk::MetricData>{metric_data}}};
  357. std::stringstream stdoutOutput;
  358. std::streambuf *sbuf = std::cout.rdbuf();
  359. std::cout.rdbuf(stdoutOutput.rdbuf());
  360. auto result = exporter->Export(data);
  361. EXPECT_EQ(result, opentelemetry::sdk::common::ExportResult::kSuccess);
  362. std::cout.rdbuf(sbuf);
  363. std::string expected_output =
  364. "{"
  365. "\n scope name\t: library_name"
  366. "\n schema url\t: "
  367. "\n version\t: 1.2.0"
  368. "\n start time\t: Thu Jan 1 00:00:00 1970"
  369. "\n end time\t: Thu Jan 1 00:00:00 1970"
  370. "\n instrument name\t: library_name"
  371. "\n description\t: description"
  372. "\n unit\t\t: unit"
  373. "\n resources\t:"
  374. "\n\tservice.name: unknown_service"
  375. "\n\ttelemetry.sdk.language: cpp"
  376. "\n\ttelemetry.sdk.name: opentelemetry"
  377. "\n\ttelemetry.sdk.version: ";
  378. expected_output += OPENTELEMETRY_SDK_VERSION;
  379. expected_output += "\n}\n";
  380. ASSERT_EQ(stdoutOutput.str(), expected_output);
  381. }