charts2json.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  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_NO_ERROR_ON_FILE_IO);
  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) {
  35. static char *custom_dashboard_info_js_filename = NULL;
  36. size_t c = 0, 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_json_initialize(wb, "\"", "\"", 0, true, BUFFER_JSON_OPTIONS_DEFAULT);
  42. buffer_json_member_add_string(wb, "hostname", rrdhost_hostname(host));
  43. buffer_json_member_add_string(wb, "version", rrdhost_program_version(host));
  44. buffer_json_member_add_string(wb, "release_channel", get_release_channel());
  45. buffer_json_member_add_string(wb, "os", rrdhost_os(host));
  46. buffer_json_member_add_string(wb, "timezone", rrdhost_timezone(host));
  47. buffer_json_member_add_int64(wb, "update_every", host->rrd_update_every);
  48. buffer_json_member_add_int64(wb, "history", host->rrd_history_entries);
  49. buffer_json_member_add_string(wb, "memory_mode", rrd_memory_mode_name(host->rrd_memory_mode));
  50. buffer_json_member_add_string(wb, "custom_info", custom_dashboard_info_js_filename);
  51. buffer_json_member_add_object(wb, "charts");
  52. rrdset_foreach_read(st, host) {
  53. if (rrdset_is_available_for_viewers(st)) {
  54. buffer_json_member_add_object(wb, rrdset_id(st));
  55. rrdset2json(st, wb, &dimensions, &memory);
  56. buffer_json_object_close(wb);
  57. st->last_accessed_time_s = now;
  58. c++;
  59. }
  60. }
  61. rrdset_foreach_done(st);
  62. buffer_json_object_close(wb);
  63. RRDCALC *rc;
  64. foreach_rrdcalc_in_rrdhost_read(host, rc) {
  65. if(rc->rrdset)
  66. alarms++;
  67. }
  68. foreach_rrdcalc_in_rrdhost_done(rc);
  69. buffer_json_member_add_int64(wb, "charts_count", (int64_t) c);
  70. buffer_json_member_add_int64(wb, "dimensions_count", (int64_t) dimensions);
  71. buffer_json_member_add_int64(wb, "alarms_count", (int64_t)alarms);
  72. buffer_json_member_add_int64(wb, "rrd_memory_bytes", (int64_t)memory);
  73. buffer_json_member_add_int64(wb, "hosts_count", (int64_t) rrdhost_hosts_available());
  74. buffer_json_member_add_array(wb, "hosts");
  75. {
  76. rrd_rdlock();
  77. RRDHOST *h;
  78. rrdhost_foreach_read(h) {
  79. if(!rrdhost_should_be_removed(h, host, now) /*&& !rrdhost_flag_check(h, RRDHOST_FLAG_ARCHIVED) */) {
  80. buffer_json_add_array_item_object(wb);
  81. buffer_json_member_add_string(wb, "hostname", rrdhost_hostname(h));
  82. buffer_json_object_close(wb);
  83. }
  84. }
  85. rrd_unlock();
  86. }
  87. buffer_json_array_close(wb);
  88. buffer_json_finalize(wb);
  89. }