systemd-main.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. // SPDX-License-Identifier: GPL-3.0-or-later
  2. #include "systemd-internals.h"
  3. #include "libnetdata/required_dummies.h"
  4. #define SYSTEMD_JOURNAL_WORKER_THREADS 5
  5. netdata_mutex_t stdout_mutex = NETDATA_MUTEX_INITIALIZER;
  6. static bool plugin_should_exit = false;
  7. static bool journal_data_direcories_exist() {
  8. struct stat st;
  9. for (unsigned i = 0; i < MAX_JOURNAL_DIRECTORIES && journal_directories[i].path; i++) {
  10. if ((stat(string2str(journal_directories[i].path), &st) == 0) && S_ISDIR(st.st_mode))
  11. return true;
  12. }
  13. return false;
  14. }
  15. int main(int argc __maybe_unused, char **argv __maybe_unused) {
  16. clocks_init();
  17. netdata_thread_set_tag("SDMAIN");
  18. nd_log_initialize_for_external_plugins("systemd-journal.plugin");
  19. netdata_configured_host_prefix = getenv("NETDATA_HOST_PREFIX");
  20. if(verify_netdata_host_prefix() == -1) exit(1);
  21. // ------------------------------------------------------------------------
  22. // initialization
  23. netdata_systemd_journal_message_ids_init();
  24. journal_init_files_and_directories();
  25. if (!journal_data_direcories_exist()) {
  26. nd_log_collector(NDLP_INFO, "unable to locate journal data directories. Exiting...");
  27. fprintf(stdout, "DISABLE\n");
  28. fflush(stdout);
  29. exit(0);
  30. }
  31. // ------------------------------------------------------------------------
  32. // debug
  33. if(argc == 2 && strcmp(argv[1], "debug") == 0) {
  34. journal_files_registry_update();
  35. bool cancelled = false;
  36. usec_t stop_monotonic_ut = now_monotonic_usec() + 600 * USEC_PER_SEC;
  37. char buf[] = "systemd-journal after:-8640000 before:0 direction:backward last:200 data_only:false slice:true source:all";
  38. // char buf[] = "systemd-journal after:1695332964 before:1695937764 direction:backward last:100 slice:true source:all DHKucpqUoe1:PtVoyIuX.MU";
  39. // char buf[] = "systemd-journal after:1694511062 before:1694514662 anchor:1694514122024403";
  40. function_systemd_journal("123", buf, &stop_monotonic_ut, &cancelled, NULL, NULL, NULL);
  41. // function_systemd_units("123", "systemd-units", 600, &cancelled);
  42. exit(1);
  43. }
  44. #ifdef ENABLE_SYSTEMD_DBUS
  45. if(argc == 2 && strcmp(argv[1], "debug-units") == 0) {
  46. bool cancelled = false;
  47. usec_t stop_monotonic_ut = now_monotonic_usec() + 600 * USEC_PER_SEC;
  48. function_systemd_units("123", "systemd-units", &stop_monotonic_ut, &cancelled, NULL, NULL, NULL);
  49. exit(1);
  50. }
  51. #endif
  52. // ------------------------------------------------------------------------
  53. // watcher thread
  54. netdata_thread_t watcher_thread;
  55. netdata_thread_create(&watcher_thread, "SDWATCH",
  56. NETDATA_THREAD_OPTION_DONT_LOG, journal_watcher_main, NULL);
  57. // ------------------------------------------------------------------------
  58. // the event loop for functions
  59. struct functions_evloop_globals *wg =
  60. functions_evloop_init(SYSTEMD_JOURNAL_WORKER_THREADS, "SDJ", &stdout_mutex, &plugin_should_exit);
  61. functions_evloop_add_function(wg,
  62. SYSTEMD_JOURNAL_FUNCTION_NAME,
  63. function_systemd_journal,
  64. SYSTEMD_JOURNAL_DEFAULT_TIMEOUT,
  65. NULL);
  66. #ifdef ENABLE_SYSTEMD_DBUS
  67. functions_evloop_add_function(wg,
  68. SYSTEMD_UNITS_FUNCTION_NAME,
  69. function_systemd_units,
  70. SYSTEMD_UNITS_DEFAULT_TIMEOUT,
  71. NULL);
  72. #endif
  73. systemd_journal_dyncfg_init(wg);
  74. // ------------------------------------------------------------------------
  75. // register functions to netdata
  76. netdata_mutex_lock(&stdout_mutex);
  77. fprintf(stdout, PLUGINSD_KEYWORD_FUNCTION " GLOBAL \"%s\" %d \"%s\" \"logs\" \"members\" %d\n",
  78. SYSTEMD_JOURNAL_FUNCTION_NAME, SYSTEMD_JOURNAL_DEFAULT_TIMEOUT, SYSTEMD_JOURNAL_FUNCTION_DESCRIPTION,
  79. RRDFUNCTIONS_PRIORITY_DEFAULT);
  80. #ifdef ENABLE_SYSTEMD_DBUS
  81. fprintf(stdout, PLUGINSD_KEYWORD_FUNCTION " GLOBAL \"%s\" %d \"%s\" \"top\" \"members\" %d\n",
  82. SYSTEMD_UNITS_FUNCTION_NAME, SYSTEMD_UNITS_DEFAULT_TIMEOUT, SYSTEMD_UNITS_FUNCTION_DESCRIPTION,
  83. RRDFUNCTIONS_PRIORITY_DEFAULT);
  84. #endif
  85. fflush(stdout);
  86. netdata_mutex_unlock(&stdout_mutex);
  87. // ------------------------------------------------------------------------
  88. usec_t step_ut = 100 * USEC_PER_MS;
  89. usec_t send_newline_ut = 0;
  90. usec_t since_last_scan_ut = SYSTEMD_JOURNAL_ALL_FILES_SCAN_EVERY_USEC * 2; // something big to trigger scanning at start
  91. bool tty = isatty(fileno(stdout)) == 1;
  92. heartbeat_t hb;
  93. heartbeat_init(&hb);
  94. while(!plugin_should_exit) {
  95. if(since_last_scan_ut > SYSTEMD_JOURNAL_ALL_FILES_SCAN_EVERY_USEC) {
  96. journal_files_registry_update();
  97. since_last_scan_ut = 0;
  98. }
  99. usec_t dt_ut = heartbeat_next(&hb, step_ut);
  100. since_last_scan_ut += dt_ut;
  101. send_newline_ut += dt_ut;
  102. if(!tty && send_newline_ut > USEC_PER_SEC) {
  103. send_newline_and_flush();
  104. send_newline_ut = 0;
  105. }
  106. }
  107. exit(0);
  108. }