| 1 | // SPDX-License-Identifier: GPL-3.0-or-later |
| 2 | |
| 3 | #include "netdata-conf-profile.h" |
| 4 | #include "streaming/stream-conf.h" |
| 5 | #include "netdata-conf.h" |
| 6 | |
| 7 | ENUM_STR_MAP_DEFINE(ND_PROFILE) = { |
| 8 | { .id = ND_PROFILE_STANDALONE, .name = "standalone" }, |
| 9 | { .id = ND_PROFILE_PARENT, .name = "parent" }, |
| 10 | { .id = ND_PROFILE_CHILD, .name = "child" }, |
| 11 | { .id = ND_PROFILE_IOT, .name = "iot" }, |
| 12 | |
| 13 | // terminator |
| 14 | { . id = 0, .name = NULL } |
| 15 | }; |
| 16 | |
| 17 | BITMAP_STR_DEFINE_FUNCTIONS(ND_PROFILE, ND_PROFILE_NONE, ""); |
| 18 | |
| 19 | static inline ND_PROFILE prefer_profile(ND_PROFILE setting, ND_PROFILE preferred, ND_PROFILE out_of) { |
| 20 | if(setting & preferred) { |
| 21 | setting &= ~out_of; |
| 22 | setting |= preferred; |
| 23 | } |
| 24 | return setting; |
| 25 | } |
| 26 | |
| 27 | ND_PROFILE nd_profile_detect_and_configure(bool recheck) { |
| 28 | static ND_PROFILE profile = ND_PROFILE_NONE; |
| 29 | if(!recheck && profile != ND_PROFILE_NONE) |
| 30 | return profile; |
| 31 | |
| 32 | // required for detecting the profile |
| 33 | stream_conf_load(); |
| 34 | netdata_conf_section_directories(); |
| 35 | |
| 36 | ND_PROFILE def_profile = ND_PROFILE_NONE; |
| 37 | |
| 38 | OS_SYSTEM_MEMORY mem = os_system_memory(true); |
| 39 | size_t cpus = os_get_system_cpus_uncached(); |
| 40 | |
| 41 | if(cpus <= 1 || (OS_SYSTEM_MEMORY_OK(mem) && mem.ram_total_bytes < 1ULL * 1024 * 1024 * 1024)) |
| 42 | def_profile = ND_PROFILE_IOT; |
| 43 | |
| 44 | else if(stream_conf_is_parent(true)) |
| 45 | def_profile = ND_PROFILE_PARENT; |
| 46 | |
| 47 | else if(stream_conf_is_child()) |
| 48 | def_profile = ND_PROFILE_CHILD; |
| 49 | |
| 50 | else |
| 51 | def_profile = ND_PROFILE_STANDALONE; |
| 52 | |
| 53 | CLEAN_BUFFER *wb = buffer_create(0, NULL); |
| 54 | ND_PROFILE_2buffer(wb, def_profile, " "); |
| 55 | |
| 56 | CLEAN_CHAR_P *s = strdupz(inicfg_get(&netdata_config, CONFIG_SECTION_GLOBAL, "profile", buffer_tostring(wb))); |
| 57 | |
| 58 | char *words[100]; |
| 59 | size_t n = quoted_strings_splitter(s, words, _countof(words), isspace_map_whitespace); |
| 60 | ND_PROFILE pt = ND_PROFILE_NONE; |
| 61 | for(size_t i = 0; i < n ;i++) { |
| 62 | ND_PROFILE ptt = ND_PROFILE_2id_one(words[i]); |
| 63 | if(ptt == ND_PROFILE_NONE) |
| 64 | nd_log(NDLS_DAEMON, NDLP_ERR, "Cannot understand netdata.conf [global].profile = %s", words[i]); |
| 65 | pt |= ptt; |
| 66 | } |
| 67 | |
| 68 | // sanity checks |
| 69 | |
| 70 | ND_PROFILE started = pt; |
| 71 | |
| 72 | if(!(pt & ND_CONF_PROFILES_SYSTEM)) |
| 73 | // system profile is missing from the settings |
| 74 | pt |= (def_profile & ND_CONF_PROFILES_SYSTEM); |
| 75 | |
| 76 | pt = prefer_profile(pt, ND_PROFILE_PARENT, ND_CONF_PROFILES_SYSTEM); |
| 77 | pt = prefer_profile(pt, ND_PROFILE_STANDALONE, ND_CONF_PROFILES_SYSTEM); |
| 78 | pt = prefer_profile(pt, ND_PROFILE_CHILD, ND_CONF_PROFILES_SYSTEM); |
| 79 | pt = prefer_profile(pt, ND_PROFILE_IOT, ND_CONF_PROFILES_SYSTEM); |
| 80 | |
| 81 | if(pt != started) { |
| 82 | buffer_flush(wb); |
| 83 | ND_PROFILE_2buffer(wb, pt, " "); |
| 84 | inicfg_set(&netdata_config, CONFIG_SECTION_GLOBAL, "profile", buffer_tostring(wb)); |
| 85 | |
| 86 | nd_log(NDLS_DAEMON, NDLP_WARNING, |
| 87 | "The netdata.conf setting [global].profile has been overwritten to '%s'", |
| 88 | buffer_tostring(wb)); |
| 89 | } |
| 90 | |
| 91 | profile = pt; |
| 92 | return profile; |
| 93 | } |
| 94 | |
| 95 | struct nd_profile_t nd_profile = { 0 }; |
| 96 | |
| 97 | void nd_profile_setup(void) { |
| 98 | FUNCTION_RUN_ONCE(); |
| 99 | |
| 100 | ND_PROFILE profile = nd_profile_detect_and_configure(true); (void)profile; |
| 101 | if(netdata_conf_is_iot()) { |
| 102 | nd_profile.storage_tiers = 3; // MUST BE 1 |
| 103 | nd_profile.update_every = 1; // MUST BE 2 |
| 104 | nd_profile.malloc_arenas = 1; |
| 105 | nd_profile.malloc_trim = 16 * 1024; |
| 106 | nd_profile.stream_sender_compression = ND_COMPRESSION_FASTEST; |
| 107 | nd_profile.dbengine_journal_v2_unmount_time = 120; |
| 108 | nd_profile.max_page_size = 16 * 1024; |
| 109 | nd_profile.ml_enabled = CONFIG_BOOLEAN_NO; |
| 110 | // web server threads = 6 |
| 111 | // aclk query threads = 6 |
| 112 | // backfill threads = 0 |
| 113 | // replication threads = 1 // can we disable them completely? |
| 114 | // ml enabled = false |
| 115 | // health enabled = true if there is no parent, otherwise false |
| 116 | // disable internal plugins: tc, idlejitter, cgroups |
| 117 | // disable external plugins: all except apps, network_viewer, systemd-journal |
| 118 | // disable sqlite |
| 119 | } |
| 120 | else if(netdata_conf_is_parent()) { |
| 121 | nd_profile.storage_tiers = 3; |
| 122 | nd_profile.update_every = 1; |
| 123 | nd_profile.malloc_arenas = 4; |
| 124 | nd_profile.malloc_trim = 128 * 1024; |
| 125 | nd_profile.stream_sender_compression = ND_COMPRESSION_FASTEST; |
| 126 | nd_profile.dbengine_journal_v2_unmount_time = 600; |
| 127 | nd_profile.max_page_size = 2 * 1024 * 1024; // 2MB for THP |
| 128 | nd_profile.ml_enabled = CONFIG_BOOLEAN_AUTO; |
| 129 | // web server threads = dynamic |
| 130 | // aclk query threads = dynamic |
| 131 | // backfill threads = dynamic |
| 132 | // replication threads = dynamic |
| 133 | // ml enabled = true |
| 134 | // health enabled = true |
| 135 | } |
| 136 | else if(netdata_conf_is_child()) { |
| 137 | nd_profile.storage_tiers = 3; |
| 138 | nd_profile.update_every = 1; |
| 139 | nd_profile.malloc_arenas = 1; |
| 140 | nd_profile.malloc_trim = 32 * 1024; |
| 141 | nd_profile.stream_sender_compression = ND_COMPRESSION_DEFAULT; |
| 142 | nd_profile.dbengine_journal_v2_unmount_time = 120; |
| 143 | nd_profile.max_page_size = 32 * 1024; |
| 144 | nd_profile.ml_enabled = CONFIG_BOOLEAN_AUTO; |
| 145 | // web server threads = 6 |
| 146 | // aclk query threads = 6 |
| 147 | // backfill threads = 0 |
| 148 | // replication threads = 1 |
| 149 | // ml enabled = false |
| 150 | // health enabled = false |
| 151 | } |
| 152 | else /* if(netdata_conf_is_standalone()) */ { |
| 153 | nd_profile.storage_tiers = 3; |
| 154 | nd_profile.update_every = 1; |
| 155 | nd_profile.malloc_arenas = 1; |
| 156 | nd_profile.malloc_trim = 64 * 1024; |
| 157 | nd_profile.stream_sender_compression = ND_COMPRESSION_DEFAULT; |
| 158 | nd_profile.dbengine_journal_v2_unmount_time = 120; |
| 159 | nd_profile.max_page_size = 64 * 1024; |
| 160 | nd_profile.ml_enabled = CONFIG_BOOLEAN_AUTO; |
| 161 | // web server threads = 6 |
| 162 | // aclk query threads = 6 |
| 163 | // backfill threads = 0 |
| 164 | // replication threads = 1 // can we disable them completely? |
| 165 | // ml enabled = true |
| 166 | // health enabled = true |
| 167 | } |
| 168 | |
| 169 | aral_optimal_malloc_page_size_set(nd_profile.max_page_size); |
| 170 | netdata_conf_glibc_malloc_initialize(nd_profile.malloc_arenas, nd_profile.malloc_trim); |
| 171 | stream_conf_set_sender_compression_levels(nd_profile.stream_sender_compression); |
| 172 | } |