charts2json.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. // SPDX-License-Identifier: GPL-3.0-or-later
  2. #include "charts2json.h"
  3. // generate JSON for the /api/v1/charts API call
  4. const char* get_release_channel() {
  5. static int use_stable = -1;
  6. if (use_stable == -1) {
  7. char filename[FILENAME_MAX + 1];
  8. snprintfz(filename, FILENAME_MAX, "%s/.environment", netdata_configured_user_config_dir);
  9. procfile *ff = procfile_open(filename, "=", PROCFILE_FLAG_ERROR_ON_ERROR_LOG);
  10. if (ff) {
  11. procfile_set_quotes(ff, "'\"");
  12. ff = procfile_readall(ff);
  13. if (ff) {
  14. unsigned int i;
  15. for (i = 0; i < procfile_lines(ff); i++) {
  16. if (!procfile_linewords(ff, i))
  17. continue;
  18. if (!strcmp(procfile_lineword(ff, i, 0), "RELEASE_CHANNEL")) {
  19. if (!strcmp(procfile_lineword(ff, i, 1), "stable"))
  20. use_stable = 1;
  21. else if (!strcmp(procfile_lineword(ff, i, 1), "nightly"))
  22. use_stable = 0;
  23. break;
  24. }
  25. }
  26. procfile_close(ff);
  27. }
  28. }
  29. if (use_stable == -1)
  30. use_stable = strchr(program_version, '-') ? 0 : 1;
  31. }
  32. return (use_stable)?"stable":"nightly";
  33. }
  34. void charts2json(RRDHOST *host, BUFFER *wb, int skip_volatile, int show_archived) {
  35. static char *custom_dashboard_info_js_filename = NULL;
  36. size_t c, dimensions = 0, memory = 0, alarms = 0;
  37. RRDSET *st;
  38. time_t now = now_realtime_sec();
  39. if(unlikely(!custom_dashboard_info_js_filename))
  40. custom_dashboard_info_js_filename = config_get(CONFIG_SECTION_WEB, "custom dashboard_info.js", "");
  41. buffer_sprintf(wb, "{\n"
  42. "\t\"hostname\": \"%s\""
  43. ",\n\t\"version\": \"%s\""
  44. ",\n\t\"release_channel\": \"%s\""
  45. ",\n\t\"os\": \"%s\""
  46. ",\n\t\"timezone\": \"%s\""
  47. ",\n\t\"update_every\": %d"
  48. ",\n\t\"history\": %ld"
  49. ",\n\t\"memory_mode\": \"%s\""
  50. ",\n\t\"custom_info\": \"%s\""
  51. ",\n\t\"charts\": {"
  52. , rrdhost_hostname(host)
  53. , rrdhost_program_version(host)
  54. , get_release_channel()
  55. , rrdhost_os(host)
  56. , rrdhost_timezone(host)
  57. , host->rrd_update_every
  58. , host->rrd_history_entries
  59. , rrd_memory_mode_name(host->rrd_memory_mode)
  60. , custom_dashboard_info_js_filename
  61. );
  62. c = 0;
  63. rrdset_foreach_read(st, host) {
  64. if ((!show_archived && rrdset_is_available_for_viewers(st)) || (show_archived && rrdset_is_archived(st))) {
  65. if(c) buffer_strcat(wb, ",");
  66. buffer_strcat(wb, "\n\t\t\"");
  67. buffer_strcat(wb, rrdset_id(st));
  68. buffer_strcat(wb, "\": ");
  69. rrdset2json(st, wb, &dimensions, &memory, skip_volatile);
  70. c++;
  71. st->last_accessed_time_s = now;
  72. }
  73. }
  74. rrdset_foreach_done(st);
  75. RRDCALC *rc;
  76. foreach_rrdcalc_in_rrdhost_read(host, rc) {
  77. if(rc->rrdset)
  78. alarms++;
  79. }
  80. foreach_rrdcalc_in_rrdhost_done(rc);
  81. buffer_sprintf(wb
  82. , "\n\t}"
  83. ",\n\t\"charts_count\": %zu"
  84. ",\n\t\"dimensions_count\": %zu"
  85. ",\n\t\"alarms_count\": %zu"
  86. ",\n\t\"rrd_memory_bytes\": %zu"
  87. ",\n\t\"hosts_count\": %zu"
  88. ",\n\t\"hosts\": ["
  89. , c
  90. , dimensions
  91. , alarms
  92. , memory
  93. , rrdhost_hosts_available()
  94. );
  95. if(unlikely(rrdhost_hosts_available() > 1)) {
  96. rrd_rdlock();
  97. size_t found = 0;
  98. RRDHOST *h;
  99. rrdhost_foreach_read(h) {
  100. if(!rrdhost_should_be_removed(h, host, now) && !rrdhost_flag_check(h, RRDHOST_FLAG_ARCHIVED)) {
  101. buffer_sprintf(wb
  102. , "%s\n\t\t{"
  103. "\n\t\t\t\"hostname\": \"%s\""
  104. "\n\t\t}"
  105. , (found > 0) ? "," : ""
  106. , rrdhost_hostname(h)
  107. );
  108. found++;
  109. }
  110. }
  111. rrd_unlock();
  112. }
  113. else {
  114. buffer_sprintf(wb
  115. , "\n\t\t{"
  116. "\n\t\t\t\"hostname\": \"%s\""
  117. "\n\t\t}"
  118. , rrdhost_hostname(host)
  119. );
  120. }
  121. buffer_sprintf(wb, "\n\t]\n}\n");
  122. }