global_statistics.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752
  1. // SPDX-License-Identifier: GPL-3.0-or-later
  2. #include "common.h"
  3. #define GLOBAL_STATS_RESET_WEB_USEC_MAX 0x01
  4. static struct global_statistics {
  5. volatile uint16_t connected_clients;
  6. volatile uint64_t web_requests;
  7. volatile uint64_t web_usec;
  8. volatile uint64_t web_usec_max;
  9. volatile uint64_t bytes_received;
  10. volatile uint64_t bytes_sent;
  11. volatile uint64_t content_size;
  12. volatile uint64_t compressed_content_size;
  13. volatile uint64_t web_client_count;
  14. volatile uint64_t rrdr_queries_made;
  15. volatile uint64_t rrdr_db_points_read;
  16. volatile uint64_t rrdr_result_points_generated;
  17. } global_statistics = {
  18. .connected_clients = 0,
  19. .web_requests = 0,
  20. .web_usec = 0,
  21. .bytes_received = 0,
  22. .bytes_sent = 0,
  23. .content_size = 0,
  24. .compressed_content_size = 0,
  25. .web_client_count = 1,
  26. .rrdr_queries_made = 0,
  27. .rrdr_db_points_read = 0,
  28. .rrdr_result_points_generated = 0,
  29. };
  30. #if defined(HAVE_C___ATOMIC) && !defined(NETDATA_NO_ATOMIC_INSTRUCTIONS)
  31. #else
  32. netdata_mutex_t global_statistics_mutex = NETDATA_MUTEX_INITIALIZER;
  33. static inline void global_statistics_lock(void) {
  34. netdata_mutex_lock(&global_statistics_mutex);
  35. }
  36. static inline void global_statistics_unlock(void) {
  37. netdata_mutex_unlock(&global_statistics_mutex);
  38. }
  39. #endif
  40. void rrdr_query_completed(uint64_t db_points_read, uint64_t result_points_generated) {
  41. #if defined(HAVE_C___ATOMIC) && !defined(NETDATA_NO_ATOMIC_INSTRUCTIONS)
  42. __atomic_fetch_add(&global_statistics.rrdr_queries_made, 1, __ATOMIC_SEQ_CST);
  43. __atomic_fetch_add(&global_statistics.rrdr_db_points_read, db_points_read, __ATOMIC_SEQ_CST);
  44. __atomic_fetch_add(&global_statistics.rrdr_result_points_generated, result_points_generated, __ATOMIC_SEQ_CST);
  45. #else
  46. #warning NOT using atomic operations - using locks for global statistics
  47. if (web_server_is_multithreaded)
  48. global_statistics_lock();
  49. global_statistics.rrdr_queries_made++;
  50. global_statistics.rrdr_db_points_read += db_points_read;
  51. global_statistics.rrdr_result_points_generated += result_points_generated;
  52. if (web_server_is_multithreaded)
  53. global_statistics_unlock();
  54. #endif
  55. }
  56. void finished_web_request_statistics(uint64_t dt,
  57. uint64_t bytes_received,
  58. uint64_t bytes_sent,
  59. uint64_t content_size,
  60. uint64_t compressed_content_size) {
  61. #if defined(HAVE_C___ATOMIC) && !defined(NETDATA_NO_ATOMIC_INSTRUCTIONS)
  62. uint64_t old_web_usec_max = global_statistics.web_usec_max;
  63. while(dt > old_web_usec_max)
  64. __atomic_compare_exchange(&global_statistics.web_usec_max, &old_web_usec_max, &dt, 1, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
  65. __atomic_fetch_add(&global_statistics.web_requests, 1, __ATOMIC_SEQ_CST);
  66. __atomic_fetch_add(&global_statistics.web_usec, dt, __ATOMIC_SEQ_CST);
  67. __atomic_fetch_add(&global_statistics.bytes_received, bytes_received, __ATOMIC_SEQ_CST);
  68. __atomic_fetch_add(&global_statistics.bytes_sent, bytes_sent, __ATOMIC_SEQ_CST);
  69. __atomic_fetch_add(&global_statistics.content_size, content_size, __ATOMIC_SEQ_CST);
  70. __atomic_fetch_add(&global_statistics.compressed_content_size, compressed_content_size, __ATOMIC_SEQ_CST);
  71. #else
  72. #warning NOT using atomic operations - using locks for global statistics
  73. if (web_server_is_multithreaded)
  74. global_statistics_lock();
  75. if (dt > global_statistics.web_usec_max)
  76. global_statistics.web_usec_max = dt;
  77. global_statistics.web_requests++;
  78. global_statistics.web_usec += dt;
  79. global_statistics.bytes_received += bytes_received;
  80. global_statistics.bytes_sent += bytes_sent;
  81. global_statistics.content_size += content_size;
  82. global_statistics.compressed_content_size += compressed_content_size;
  83. if (web_server_is_multithreaded)
  84. global_statistics_unlock();
  85. #endif
  86. }
  87. uint64_t web_client_connected(void) {
  88. #if defined(HAVE_C___ATOMIC) && !defined(NETDATA_NO_ATOMIC_INSTRUCTIONS)
  89. __atomic_fetch_add(&global_statistics.connected_clients, 1, __ATOMIC_SEQ_CST);
  90. uint64_t id = __atomic_fetch_add(&global_statistics.web_client_count, 1, __ATOMIC_SEQ_CST);
  91. #else
  92. if (web_server_is_multithreaded)
  93. global_statistics_lock();
  94. global_statistics.connected_clients++;
  95. uint64_t id = global_statistics.web_client_count++;
  96. if (web_server_is_multithreaded)
  97. global_statistics_unlock();
  98. #endif
  99. return id;
  100. }
  101. void web_client_disconnected(void) {
  102. #if defined(HAVE_C___ATOMIC) && !defined(NETDATA_NO_ATOMIC_INSTRUCTIONS)
  103. __atomic_fetch_sub(&global_statistics.connected_clients, 1, __ATOMIC_SEQ_CST);
  104. #else
  105. if (web_server_is_multithreaded)
  106. global_statistics_lock();
  107. global_statistics.connected_clients--;
  108. if (web_server_is_multithreaded)
  109. global_statistics_unlock();
  110. #endif
  111. }
  112. static inline void global_statistics_copy(struct global_statistics *gs, uint8_t options) {
  113. #if defined(HAVE_C___ATOMIC) && !defined(NETDATA_NO_ATOMIC_INSTRUCTIONS)
  114. gs->connected_clients = __atomic_fetch_add(&global_statistics.connected_clients, 0, __ATOMIC_SEQ_CST);
  115. gs->web_requests = __atomic_fetch_add(&global_statistics.web_requests, 0, __ATOMIC_SEQ_CST);
  116. gs->web_usec = __atomic_fetch_add(&global_statistics.web_usec, 0, __ATOMIC_SEQ_CST);
  117. gs->web_usec_max = __atomic_fetch_add(&global_statistics.web_usec_max, 0, __ATOMIC_SEQ_CST);
  118. gs->bytes_received = __atomic_fetch_add(&global_statistics.bytes_received, 0, __ATOMIC_SEQ_CST);
  119. gs->bytes_sent = __atomic_fetch_add(&global_statistics.bytes_sent, 0, __ATOMIC_SEQ_CST);
  120. gs->content_size = __atomic_fetch_add(&global_statistics.content_size, 0, __ATOMIC_SEQ_CST);
  121. gs->compressed_content_size = __atomic_fetch_add(&global_statistics.compressed_content_size, 0, __ATOMIC_SEQ_CST);
  122. gs->web_client_count = __atomic_fetch_add(&global_statistics.web_client_count, 0, __ATOMIC_SEQ_CST);
  123. gs->rrdr_queries_made = __atomic_fetch_add(&global_statistics.rrdr_queries_made, 0, __ATOMIC_SEQ_CST);
  124. gs->rrdr_db_points_read = __atomic_fetch_add(&global_statistics.rrdr_db_points_read, 0, __ATOMIC_SEQ_CST);
  125. gs->rrdr_result_points_generated = __atomic_fetch_add(&global_statistics.rrdr_result_points_generated, 0, __ATOMIC_SEQ_CST);
  126. if(options & GLOBAL_STATS_RESET_WEB_USEC_MAX) {
  127. uint64_t n = 0;
  128. __atomic_compare_exchange(&global_statistics.web_usec_max, &gs->web_usec_max, &n, 1, __ATOMIC_SEQ_CST,
  129. __ATOMIC_SEQ_CST);
  130. }
  131. #else
  132. global_statistics_lock();
  133. memcpy(gs, (const void *)&global_statistics, sizeof(struct global_statistics));
  134. if (options & GLOBAL_STATS_RESET_WEB_USEC_MAX)
  135. global_statistics.web_usec_max = 0;
  136. global_statistics_unlock();
  137. #endif
  138. }
  139. void global_statistics_charts(void) {
  140. static unsigned long long old_web_requests = 0,
  141. old_web_usec = 0,
  142. old_content_size = 0,
  143. old_compressed_content_size = 0;
  144. static collected_number compression_ratio = -1,
  145. average_response_time = -1;
  146. struct global_statistics gs;
  147. struct rusage me, thread;
  148. global_statistics_copy(&gs, GLOBAL_STATS_RESET_WEB_USEC_MAX);
  149. getrusage(RUSAGE_THREAD, &thread);
  150. getrusage(RUSAGE_SELF, &me);
  151. {
  152. static RRDSET *st_cpu_thread = NULL;
  153. static RRDDIM *rd_cpu_thread_user = NULL,
  154. *rd_cpu_thread_system = NULL;
  155. #ifdef __FreeBSD__
  156. if (unlikely(!st_cpu_thread)) {
  157. st_cpu_thread = rrdset_create_localhost(
  158. "netdata"
  159. , "plugin_freebsd_cpu"
  160. , NULL
  161. , "freebsd"
  162. , NULL
  163. , "NetData FreeBSD Plugin CPU usage"
  164. , "milliseconds/s"
  165. , "netdata"
  166. , "stats"
  167. , 132000
  168. , localhost->rrd_update_every
  169. , RRDSET_TYPE_STACKED
  170. );
  171. #else
  172. if (unlikely(!st_cpu_thread)) {
  173. st_cpu_thread = rrdset_create_localhost(
  174. "netdata"
  175. , "plugin_proc_cpu"
  176. , NULL
  177. , "proc"
  178. , NULL
  179. , "NetData Proc Plugin CPU usage"
  180. , "milliseconds/s"
  181. , "netdata"
  182. , "stats"
  183. , 132000
  184. , localhost->rrd_update_every
  185. , RRDSET_TYPE_STACKED
  186. );
  187. #endif
  188. rd_cpu_thread_user = rrddim_add(st_cpu_thread, "user", NULL, 1, 1000, RRD_ALGORITHM_INCREMENTAL);
  189. rd_cpu_thread_system = rrddim_add(st_cpu_thread, "system", NULL, 1, 1000, RRD_ALGORITHM_INCREMENTAL);
  190. }
  191. else
  192. rrdset_next(st_cpu_thread);
  193. rrddim_set_by_pointer(st_cpu_thread, rd_cpu_thread_user, thread.ru_utime.tv_sec * 1000000ULL + thread.ru_utime.tv_usec);
  194. rrddim_set_by_pointer(st_cpu_thread, rd_cpu_thread_system, thread.ru_stime.tv_sec * 1000000ULL + thread.ru_stime.tv_usec);
  195. rrdset_done(st_cpu_thread);
  196. }
  197. // ----------------------------------------------------------------
  198. {
  199. static RRDSET *st_cpu = NULL;
  200. static RRDDIM *rd_cpu_user = NULL,
  201. *rd_cpu_system = NULL;
  202. if (unlikely(!st_cpu)) {
  203. st_cpu = rrdset_create_localhost(
  204. "netdata"
  205. , "server_cpu"
  206. , NULL
  207. , "netdata"
  208. , NULL
  209. , "NetData CPU usage"
  210. , "milliseconds/s"
  211. , "netdata"
  212. , "stats"
  213. , 130000
  214. , localhost->rrd_update_every
  215. , RRDSET_TYPE_STACKED
  216. );
  217. rd_cpu_user = rrddim_add(st_cpu, "user", NULL, 1, 1000, RRD_ALGORITHM_INCREMENTAL);
  218. rd_cpu_system = rrddim_add(st_cpu, "system", NULL, 1, 1000, RRD_ALGORITHM_INCREMENTAL);
  219. }
  220. else
  221. rrdset_next(st_cpu);
  222. rrddim_set_by_pointer(st_cpu, rd_cpu_user, me.ru_utime.tv_sec * 1000000ULL + me.ru_utime.tv_usec);
  223. rrddim_set_by_pointer(st_cpu, rd_cpu_system, me.ru_stime.tv_sec * 1000000ULL + me.ru_stime.tv_usec);
  224. rrdset_done(st_cpu);
  225. }
  226. // ----------------------------------------------------------------
  227. {
  228. static RRDSET *st_clients = NULL;
  229. static RRDDIM *rd_clients = NULL;
  230. if (unlikely(!st_clients)) {
  231. st_clients = rrdset_create_localhost(
  232. "netdata"
  233. , "clients"
  234. , NULL
  235. , "netdata"
  236. , NULL
  237. , "NetData Web Clients"
  238. , "connected clients"
  239. , "netdata"
  240. , "stats"
  241. , 130200
  242. , localhost->rrd_update_every
  243. , RRDSET_TYPE_LINE
  244. );
  245. rd_clients = rrddim_add(st_clients, "clients", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
  246. }
  247. else
  248. rrdset_next(st_clients);
  249. rrddim_set_by_pointer(st_clients, rd_clients, gs.connected_clients);
  250. rrdset_done(st_clients);
  251. }
  252. // ----------------------------------------------------------------
  253. {
  254. static RRDSET *st_reqs = NULL;
  255. static RRDDIM *rd_requests = NULL;
  256. if (unlikely(!st_reqs)) {
  257. st_reqs = rrdset_create_localhost(
  258. "netdata"
  259. , "requests"
  260. , NULL
  261. , "netdata"
  262. , NULL
  263. , "NetData Web Requests"
  264. , "requests/s"
  265. , "netdata"
  266. , "stats"
  267. , 130300
  268. , localhost->rrd_update_every
  269. , RRDSET_TYPE_LINE
  270. );
  271. rd_requests = rrddim_add(st_reqs, "requests", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
  272. }
  273. else
  274. rrdset_next(st_reqs);
  275. rrddim_set_by_pointer(st_reqs, rd_requests, (collected_number) gs.web_requests);
  276. rrdset_done(st_reqs);
  277. }
  278. // ----------------------------------------------------------------
  279. {
  280. static RRDSET *st_bytes = NULL;
  281. static RRDDIM *rd_in = NULL,
  282. *rd_out = NULL;
  283. if (unlikely(!st_bytes)) {
  284. st_bytes = rrdset_create_localhost(
  285. "netdata"
  286. , "net"
  287. , NULL
  288. , "netdata"
  289. , NULL
  290. , "NetData Network Traffic"
  291. , "kilobits/s"
  292. , "netdata"
  293. , "stats"
  294. , 130000
  295. , localhost->rrd_update_every
  296. , RRDSET_TYPE_AREA
  297. );
  298. rd_in = rrddim_add(st_bytes, "in", NULL, 8, BITS_IN_A_KILOBIT, RRD_ALGORITHM_INCREMENTAL);
  299. rd_out = rrddim_add(st_bytes, "out", NULL, -8, BITS_IN_A_KILOBIT, RRD_ALGORITHM_INCREMENTAL);
  300. }
  301. else
  302. rrdset_next(st_bytes);
  303. rrddim_set_by_pointer(st_bytes, rd_in, (collected_number) gs.bytes_received);
  304. rrddim_set_by_pointer(st_bytes, rd_out, (collected_number) gs.bytes_sent);
  305. rrdset_done(st_bytes);
  306. }
  307. // ----------------------------------------------------------------
  308. {
  309. static RRDSET *st_duration = NULL;
  310. static RRDDIM *rd_average = NULL,
  311. *rd_max = NULL;
  312. if (unlikely(!st_duration)) {
  313. st_duration = rrdset_create_localhost(
  314. "netdata"
  315. , "response_time"
  316. , NULL
  317. , "netdata"
  318. , NULL
  319. , "NetData API Response Time"
  320. , "milliseconds/request"
  321. , "netdata"
  322. , "stats"
  323. , 130400
  324. , localhost->rrd_update_every
  325. , RRDSET_TYPE_LINE
  326. );
  327. rd_average = rrddim_add(st_duration, "average", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
  328. rd_max = rrddim_add(st_duration, "max", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
  329. }
  330. else
  331. rrdset_next(st_duration);
  332. uint64_t gweb_usec = gs.web_usec;
  333. uint64_t gweb_requests = gs.web_requests;
  334. uint64_t web_usec = (gweb_usec >= old_web_usec) ? gweb_usec - old_web_usec : 0;
  335. uint64_t web_requests = (gweb_requests >= old_web_requests) ? gweb_requests - old_web_requests : 0;
  336. old_web_usec = gweb_usec;
  337. old_web_requests = gweb_requests;
  338. if (web_requests)
  339. average_response_time = (collected_number) (web_usec / web_requests);
  340. if (unlikely(average_response_time != -1))
  341. rrddim_set_by_pointer(st_duration, rd_average, average_response_time);
  342. else
  343. rrddim_set_by_pointer(st_duration, rd_average, 0);
  344. rrddim_set_by_pointer(st_duration, rd_max, ((gs.web_usec_max)?(collected_number)gs.web_usec_max:average_response_time));
  345. rrdset_done(st_duration);
  346. }
  347. // ----------------------------------------------------------------
  348. {
  349. static RRDSET *st_compression = NULL;
  350. static RRDDIM *rd_savings = NULL;
  351. if (unlikely(!st_compression)) {
  352. st_compression = rrdset_create_localhost(
  353. "netdata"
  354. , "compression_ratio"
  355. , NULL
  356. , "netdata"
  357. , NULL
  358. , "NetData API Responses Compression Savings Ratio"
  359. , "percentage"
  360. , "netdata"
  361. , "stats"
  362. , 130500
  363. , localhost->rrd_update_every
  364. , RRDSET_TYPE_LINE
  365. );
  366. rd_savings = rrddim_add(st_compression, "savings", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
  367. }
  368. else
  369. rrdset_next(st_compression);
  370. // since we don't lock here to read the global statistics
  371. // read the smaller value first
  372. unsigned long long gcompressed_content_size = gs.compressed_content_size;
  373. unsigned long long gcontent_size = gs.content_size;
  374. unsigned long long compressed_content_size = gcompressed_content_size - old_compressed_content_size;
  375. unsigned long long content_size = gcontent_size - old_content_size;
  376. old_compressed_content_size = gcompressed_content_size;
  377. old_content_size = gcontent_size;
  378. if (content_size && content_size >= compressed_content_size)
  379. compression_ratio = ((content_size - compressed_content_size) * 100 * 1000) / content_size;
  380. if (compression_ratio != -1)
  381. rrddim_set_by_pointer(st_compression, rd_savings, compression_ratio);
  382. rrdset_done(st_compression);
  383. }
  384. // ----------------------------------------------------------------
  385. if(gs.rrdr_queries_made) {
  386. static RRDSET *st_rrdr_queries = NULL;
  387. static RRDDIM *rd_queries = NULL;
  388. if (unlikely(!st_rrdr_queries)) {
  389. st_rrdr_queries = rrdset_create_localhost(
  390. "netdata"
  391. , "queries"
  392. , NULL
  393. , "queries"
  394. , NULL
  395. , "NetData API Queries"
  396. , "queries/s"
  397. , "netdata"
  398. , "stats"
  399. , 130500
  400. , localhost->rrd_update_every
  401. , RRDSET_TYPE_LINE
  402. );
  403. rd_queries = rrddim_add(st_rrdr_queries, "queries", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
  404. }
  405. else
  406. rrdset_next(st_rrdr_queries);
  407. rrddim_set_by_pointer(st_rrdr_queries, rd_queries, (collected_number)gs.rrdr_queries_made);
  408. rrdset_done(st_rrdr_queries);
  409. }
  410. // ----------------------------------------------------------------
  411. if(gs.rrdr_db_points_read || gs.rrdr_result_points_generated) {
  412. static RRDSET *st_rrdr_points = NULL;
  413. static RRDDIM *rd_points_read = NULL;
  414. static RRDDIM *rd_points_generated = NULL;
  415. if (unlikely(!st_rrdr_points)) {
  416. st_rrdr_points = rrdset_create_localhost(
  417. "netdata"
  418. , "db_points"
  419. , NULL
  420. , "queries"
  421. , NULL
  422. , "NetData API Points"
  423. , "points/s"
  424. , "netdata"
  425. , "stats"
  426. , 130501
  427. , localhost->rrd_update_every
  428. , RRDSET_TYPE_AREA
  429. );
  430. rd_points_read = rrddim_add(st_rrdr_points, "read", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
  431. rd_points_generated = rrddim_add(st_rrdr_points, "generated", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
  432. }
  433. else
  434. rrdset_next(st_rrdr_points);
  435. rrddim_set_by_pointer(st_rrdr_points, rd_points_read, (collected_number)gs.rrdr_db_points_read);
  436. rrddim_set_by_pointer(st_rrdr_points, rd_points_generated, (collected_number)gs.rrdr_result_points_generated);
  437. rrdset_done(st_rrdr_points);
  438. }
  439. // ----------------------------------------------------------------
  440. #ifdef ENABLE_DBENGINE
  441. if (localhost->rrd_memory_mode == RRD_MEMORY_MODE_DBENGINE) {
  442. unsigned long long stats_array[27];
  443. /* get localhost's DB engine's statistics */
  444. rrdeng_get_27_statistics(localhost->rrdeng_ctx, stats_array);
  445. // ----------------------------------------------------------------
  446. {
  447. static RRDSET *st_compression = NULL;
  448. static RRDDIM *rd_savings = NULL;
  449. if (unlikely(!st_compression)) {
  450. st_compression = rrdset_create_localhost(
  451. "netdata"
  452. , "dbengine_compression_ratio"
  453. , NULL
  454. , "dbengine"
  455. , NULL
  456. , "NetData DB engine data extents' compression savings ratio"
  457. , "percentage"
  458. , "netdata"
  459. , "stats"
  460. , 130502
  461. , localhost->rrd_update_every
  462. , RRDSET_TYPE_LINE
  463. );
  464. rd_savings = rrddim_add(st_compression, "savings", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
  465. }
  466. else
  467. rrdset_next(st_compression);
  468. unsigned long long ratio;
  469. unsigned long long compressed_content_size = stats_array[12];
  470. unsigned long long content_size = stats_array[11];
  471. if (content_size) {
  472. // allow negative savings
  473. ratio = ((content_size - compressed_content_size) * 100 * 1000) / content_size;
  474. } else {
  475. ratio = 0;
  476. }
  477. rrddim_set_by_pointer(st_compression, rd_savings, ratio);
  478. rrdset_done(st_compression);
  479. }
  480. // ----------------------------------------------------------------
  481. {
  482. static RRDSET *st_pg_cache_hit_ratio = NULL;
  483. static RRDDIM *rd_hit_ratio = NULL;
  484. if (unlikely(!st_pg_cache_hit_ratio)) {
  485. st_pg_cache_hit_ratio = rrdset_create_localhost(
  486. "netdata"
  487. , "page_cache_hit_ratio"
  488. , NULL
  489. , "dbengine"
  490. , NULL
  491. , "NetData DB engine page cache hit ratio"
  492. , "percentage"
  493. , "netdata"
  494. , "stats"
  495. , 130503
  496. , localhost->rrd_update_every
  497. , RRDSET_TYPE_LINE
  498. );
  499. rd_hit_ratio = rrddim_add(st_pg_cache_hit_ratio, "ratio", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
  500. }
  501. else
  502. rrdset_next(st_pg_cache_hit_ratio);
  503. static unsigned long long old_hits = 0;
  504. static unsigned long long old_misses = 0;
  505. unsigned long long hits = stats_array[7];
  506. unsigned long long misses = stats_array[8];
  507. unsigned long long hits_delta;
  508. unsigned long long misses_delta;
  509. unsigned long long ratio;
  510. hits_delta = hits - old_hits;
  511. misses_delta = misses - old_misses;
  512. old_hits = hits;
  513. old_misses = misses;
  514. if (hits_delta + misses_delta) {
  515. // allow negative savings
  516. ratio = (hits_delta * 100 * 1000) / (hits_delta + misses_delta);
  517. } else {
  518. ratio = 0;
  519. }
  520. rrddim_set_by_pointer(st_pg_cache_hit_ratio, rd_hit_ratio, ratio);
  521. rrdset_done(st_pg_cache_hit_ratio);
  522. }
  523. // ----------------------------------------------------------------
  524. {
  525. static RRDSET *st_pg_cache_pages = NULL;
  526. static RRDDIM *rd_populated = NULL;
  527. static RRDDIM *rd_commited = NULL;
  528. static RRDDIM *rd_insertions = NULL;
  529. static RRDDIM *rd_deletions = NULL;
  530. static RRDDIM *rd_backfills = NULL;
  531. static RRDDIM *rd_evictions = NULL;
  532. if (unlikely(!st_pg_cache_pages)) {
  533. st_pg_cache_pages = rrdset_create_localhost(
  534. "netdata"
  535. , "page_cache_stats"
  536. , NULL
  537. , "dbengine"
  538. , NULL
  539. , "NetData DB engine page statistics"
  540. , "pages"
  541. , "netdata"
  542. , "stats"
  543. , 130504
  544. , localhost->rrd_update_every
  545. , RRDSET_TYPE_LINE
  546. );
  547. rd_populated = rrddim_add(st_pg_cache_pages, "populated", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
  548. rd_commited = rrddim_add(st_pg_cache_pages, "commited", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
  549. rd_insertions = rrddim_add(st_pg_cache_pages, "insertions", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
  550. rd_deletions = rrddim_add(st_pg_cache_pages, "deletions", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
  551. rd_backfills = rrddim_add(st_pg_cache_pages, "backfills", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
  552. rd_evictions = rrddim_add(st_pg_cache_pages, "evictions", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
  553. }
  554. else
  555. rrdset_next(st_pg_cache_pages);
  556. rrddim_set_by_pointer(st_pg_cache_pages, rd_populated, (collected_number)stats_array[3]);
  557. rrddim_set_by_pointer(st_pg_cache_pages, rd_commited, (collected_number)stats_array[4]);
  558. rrddim_set_by_pointer(st_pg_cache_pages, rd_insertions, (collected_number)stats_array[5]);
  559. rrddim_set_by_pointer(st_pg_cache_pages, rd_deletions, (collected_number)stats_array[6]);
  560. rrddim_set_by_pointer(st_pg_cache_pages, rd_backfills, (collected_number)stats_array[9]);
  561. rrddim_set_by_pointer(st_pg_cache_pages, rd_evictions, (collected_number)stats_array[10]);
  562. rrdset_done(st_pg_cache_pages);
  563. }
  564. // ----------------------------------------------------------------
  565. {
  566. static RRDSET *st_io_stats = NULL;
  567. static RRDDIM *rd_reads = NULL;
  568. static RRDDIM *rd_writes = NULL;
  569. if (unlikely(!st_io_stats)) {
  570. st_io_stats = rrdset_create_localhost(
  571. "netdata"
  572. , "dbengine_io_throughput"
  573. , NULL
  574. , "dbengine"
  575. , NULL
  576. , "NetData DB engine I/O throughput"
  577. , "MiB/s"
  578. , "netdata"
  579. , "stats"
  580. , 130505
  581. , localhost->rrd_update_every
  582. , RRDSET_TYPE_LINE
  583. );
  584. rd_reads = rrddim_add(st_io_stats, "reads", NULL, 1, 1024 * 1024, RRD_ALGORITHM_INCREMENTAL);
  585. rd_writes = rrddim_add(st_io_stats, "writes", NULL, -1, 1024 * 1024, RRD_ALGORITHM_INCREMENTAL);
  586. }
  587. else
  588. rrdset_next(st_io_stats);
  589. rrddim_set_by_pointer(st_io_stats, rd_reads, (collected_number)stats_array[17]);
  590. rrddim_set_by_pointer(st_io_stats, rd_writes, (collected_number)stats_array[15]);
  591. rrdset_done(st_io_stats);
  592. }
  593. // ----------------------------------------------------------------
  594. {
  595. static RRDSET *st_io_stats = NULL;
  596. static RRDDIM *rd_reads = NULL;
  597. static RRDDIM *rd_writes = NULL;
  598. if (unlikely(!st_io_stats)) {
  599. st_io_stats = rrdset_create_localhost(
  600. "netdata"
  601. , "dbengine_io_operations"
  602. , NULL
  603. , "dbengine"
  604. , NULL
  605. , "NetData DB engine I/O operations"
  606. , "operations/s"
  607. , "netdata"
  608. , "stats"
  609. , 130506
  610. , localhost->rrd_update_every
  611. , RRDSET_TYPE_LINE
  612. );
  613. rd_reads = rrddim_add(st_io_stats, "reads", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
  614. rd_writes = rrddim_add(st_io_stats, "writes", NULL, -1, 1, RRD_ALGORITHM_INCREMENTAL);
  615. }
  616. else
  617. rrdset_next(st_io_stats);
  618. rrddim_set_by_pointer(st_io_stats, rd_reads, (collected_number)stats_array[18]);
  619. rrddim_set_by_pointer(st_io_stats, rd_writes, (collected_number)stats_array[16]);
  620. rrdset_done(st_io_stats);
  621. }
  622. }
  623. #endif
  624. }