read_config.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515
  1. // SPDX-License-Identifier: GPL-3.0-or-later
  2. #include "exporting_engine.h"
  3. EXPORTING_OPTIONS global_exporting_options = EXPORTING_SOURCE_DATA_AVERAGE | EXPORTING_OPTION_SEND_NAMES;
  4. const char *global_exporting_prefix = "netdata";
  5. struct config exporting_config = { .first_section = NULL,
  6. .last_section = NULL,
  7. .mutex = NETDATA_MUTEX_INITIALIZER,
  8. .index = { .avl_tree = { .root = NULL, .compar = appconfig_section_compare },
  9. .rwlock = AVL_LOCK_INITIALIZER } };
  10. struct instance *prometheus_exporter_instance = NULL;
  11. static _CONNECTOR_INSTANCE *find_instance(const char *section)
  12. {
  13. _CONNECTOR_INSTANCE *local_ci;
  14. local_ci = add_connector_instance(NULL, NULL); // Get root section
  15. if (unlikely(!local_ci))
  16. return local_ci;
  17. if (!section)
  18. return local_ci;
  19. while (local_ci) {
  20. if (!strcmp(local_ci->instance_name, section))
  21. break;
  22. local_ci = local_ci->next;
  23. }
  24. return local_ci;
  25. }
  26. char *expconfig_get(struct config *root, const char *section, const char *name, const char *default_value)
  27. {
  28. _CONNECTOR_INSTANCE *local_ci;
  29. if (!strcmp(section, CONFIG_SECTION_EXPORTING))
  30. return appconfig_get(root, CONFIG_SECTION_EXPORTING, name, default_value);
  31. local_ci = find_instance(section);
  32. if (!local_ci)
  33. return NULL; // TODO: Check if it is meaningful to return default_value
  34. return appconfig_get(
  35. root, local_ci->instance_name, name,
  36. appconfig_get(
  37. root, local_ci->connector_name, name, appconfig_get(root, CONFIG_SECTION_EXPORTING, name, default_value)));
  38. }
  39. int expconfig_get_boolean(struct config *root, const char *section, const char *name, int default_value)
  40. {
  41. _CONNECTOR_INSTANCE *local_ci;
  42. if (!strcmp(section, CONFIG_SECTION_EXPORTING))
  43. return appconfig_get_boolean(root, CONFIG_SECTION_EXPORTING, name, default_value);
  44. local_ci = find_instance(section);
  45. if (!local_ci)
  46. return 0; // TODO: Check if it is meaningful to return default_value
  47. return appconfig_get_boolean(
  48. root, local_ci->instance_name, name,
  49. appconfig_get_boolean(
  50. root, local_ci->connector_name, name,
  51. appconfig_get_boolean(root, CONFIG_SECTION_EXPORTING, name, default_value)));
  52. }
  53. long long expconfig_get_number(struct config *root, const char *section, const char *name, long long default_value)
  54. {
  55. _CONNECTOR_INSTANCE *local_ci;
  56. if (!strcmp(section, CONFIG_SECTION_EXPORTING))
  57. return appconfig_get_number(root, CONFIG_SECTION_EXPORTING, name, default_value);
  58. local_ci = find_instance(section);
  59. if (!local_ci)
  60. return 0; // TODO: Check if it is meaningful to return default_value
  61. return appconfig_get_number(
  62. root, local_ci->instance_name, name,
  63. appconfig_get_number(
  64. root, local_ci->connector_name, name,
  65. appconfig_get_number(root, CONFIG_SECTION_EXPORTING, name, default_value)));
  66. }
  67. /*
  68. * Get the next connector instance that we need to activate
  69. *
  70. * @param @target_ci will be filled with instance name and connector name
  71. *
  72. * @return - 1 if more connectors to be fetched, 0 done
  73. *
  74. */
  75. int get_connector_instance(struct connector_instance *target_ci)
  76. {
  77. static _CONNECTOR_INSTANCE *local_ci = NULL;
  78. _CONNECTOR_INSTANCE *global_connector_instance;
  79. global_connector_instance = find_instance(NULL); // Fetch head of instances
  80. if (unlikely(!global_connector_instance))
  81. return 0;
  82. if (target_ci == NULL) {
  83. local_ci = NULL;
  84. return 1;
  85. }
  86. if (local_ci == NULL)
  87. local_ci = global_connector_instance;
  88. else {
  89. local_ci = local_ci->next;
  90. if (local_ci == NULL)
  91. return 0;
  92. }
  93. strcpy(target_ci->instance_name, local_ci->instance_name);
  94. strcpy(target_ci->connector_name, local_ci->connector_name);
  95. return 1;
  96. }
  97. /**
  98. * Select Type
  99. *
  100. * Select the connector type based on the user input
  101. *
  102. * @param type is the string that defines the connector type
  103. *
  104. * @return It returns the connector id.
  105. */
  106. EXPORTING_CONNECTOR_TYPE exporting_select_type(const char *type)
  107. {
  108. if (!strcmp(type, "graphite") || !strcmp(type, "graphite:plaintext")) {
  109. return EXPORTING_CONNECTOR_TYPE_GRAPHITE;
  110. } else if (!strcmp(type, "graphite:http") || !strcmp(type, "graphite:https")) {
  111. return EXPORTING_CONNECTOR_TYPE_GRAPHITE_HTTP;
  112. } else if (!strcmp(type, "json") || !strcmp(type, "json:plaintext")) {
  113. return EXPORTING_CONNECTOR_TYPE_JSON;
  114. } else if (!strcmp(type, "json:http") || !strcmp(type, "json:https")) {
  115. return EXPORTING_CONNECTOR_TYPE_JSON_HTTP;
  116. } else if (!strcmp(type, "opentsdb") || !strcmp(type, "opentsdb:telnet")) {
  117. return EXPORTING_CONNECTOR_TYPE_OPENTSDB;
  118. } else if (!strcmp(type, "opentsdb:http") || !strcmp(type, "opentsdb:https")) {
  119. return EXPORTING_CONNECTOR_TYPE_OPENTSDB_HTTP;
  120. } else if (
  121. !strcmp(type, "prometheus_remote_write") ||
  122. !strcmp(type, "prometheus_remote_write:http") ||
  123. !strcmp(type, "prometheus_remote_write:https")) {
  124. return EXPORTING_CONNECTOR_TYPE_PROMETHEUS_REMOTE_WRITE;
  125. } else if (!strcmp(type, "kinesis") || !strcmp(type, "kinesis:plaintext")) {
  126. return EXPORTING_CONNECTOR_TYPE_KINESIS;
  127. } else if (!strcmp(type, "pubsub") || !strcmp(type, "pubsub:plaintext")) {
  128. return EXPORTING_CONNECTOR_TYPE_PUBSUB;
  129. } else if (!strcmp(type, "mongodb") || !strcmp(type, "mongodb:plaintext"))
  130. return EXPORTING_CONNECTOR_TYPE_MONGODB;
  131. return EXPORTING_CONNECTOR_TYPE_UNKNOWN;
  132. }
  133. inline EXPORTING_OPTIONS exporting_parse_data_source(const char *data_source, EXPORTING_OPTIONS exporting_options)
  134. {
  135. if (!strcmp(data_source, "raw") || !strcmp(data_source, "as collected") || !strcmp(data_source, "as-collected") ||
  136. !strcmp(data_source, "as_collected") || !strcmp(data_source, "ascollected")) {
  137. exporting_options |= EXPORTING_SOURCE_DATA_AS_COLLECTED;
  138. exporting_options &= ~(EXPORTING_OPTIONS_SOURCE_BITS ^ EXPORTING_SOURCE_DATA_AS_COLLECTED);
  139. } else if (!strcmp(data_source, "average")) {
  140. exporting_options |= EXPORTING_SOURCE_DATA_AVERAGE;
  141. exporting_options &= ~(EXPORTING_OPTIONS_SOURCE_BITS ^ EXPORTING_SOURCE_DATA_AVERAGE);
  142. } else if (!strcmp(data_source, "sum") || !strcmp(data_source, "volume")) {
  143. exporting_options |= EXPORTING_SOURCE_DATA_SUM;
  144. exporting_options &= ~(EXPORTING_OPTIONS_SOURCE_BITS ^ EXPORTING_SOURCE_DATA_SUM);
  145. } else {
  146. netdata_log_error("EXPORTING: invalid data data_source method '%s'.", data_source);
  147. }
  148. return exporting_options;
  149. }
  150. /**
  151. * Read configuration
  152. *
  153. * Based on read configuration an engine data structure is filled with exporting connector instances.
  154. *
  155. * @return Returns a filled engine data structure or NULL if there are no connector instances configured.
  156. */
  157. struct engine *read_exporting_config()
  158. {
  159. int instances_to_activate = 0;
  160. int exporting_config_exists = 0;
  161. static struct engine *engine = NULL;
  162. struct connector_instance_list {
  163. struct connector_instance local_ci;
  164. EXPORTING_CONNECTOR_TYPE exporting_type;
  165. struct connector_instance_list *next;
  166. };
  167. struct connector_instance local_ci;
  168. struct connector_instance_list *tmp_ci_list = NULL, *tmp_ci_list1 = NULL, *tmp_ci_list_prev = NULL;
  169. if (unlikely(engine))
  170. return engine;
  171. char *filename = strdupz_path_subpath(netdata_configured_user_config_dir, EXPORTING_CONF);
  172. exporting_config_exists = appconfig_load(&exporting_config, filename, 0, NULL);
  173. if (!exporting_config_exists) {
  174. netdata_log_info("CONFIG: cannot load user exporting config '%s'. Will try the stock version.", filename);
  175. freez(filename);
  176. filename = strdupz_path_subpath(netdata_configured_stock_config_dir, EXPORTING_CONF);
  177. exporting_config_exists = appconfig_load(&exporting_config, filename, 0, NULL);
  178. if (!exporting_config_exists)
  179. netdata_log_info("CONFIG: cannot load stock exporting config '%s'. Running with internal defaults.", filename);
  180. }
  181. freez(filename);
  182. #define prometheus_config_get(name, value) \
  183. appconfig_get( \
  184. &exporting_config, CONFIG_SECTION_PROMETHEUS, name, \
  185. appconfig_get(&exporting_config, CONFIG_SECTION_EXPORTING, name, value))
  186. #define prometheus_config_get_number(name, value) \
  187. appconfig_get_number( \
  188. &exporting_config, CONFIG_SECTION_PROMETHEUS, name, \
  189. appconfig_get_number(&exporting_config, CONFIG_SECTION_EXPORTING, name, value))
  190. #define prometheus_config_get_boolean(name, value) \
  191. appconfig_get_boolean( \
  192. &exporting_config, CONFIG_SECTION_PROMETHEUS, name, \
  193. appconfig_get_boolean(&exporting_config, CONFIG_SECTION_EXPORTING, name, value))
  194. if (!prometheus_exporter_instance) {
  195. prometheus_exporter_instance = callocz(1, sizeof(struct instance));
  196. prometheus_exporter_instance->config.update_every =
  197. prometheus_config_get_number(EXPORTING_UPDATE_EVERY_OPTION_NAME, EXPORTING_UPDATE_EVERY_DEFAULT);
  198. prometheus_exporter_instance->config.options |= global_exporting_options & EXPORTING_OPTIONS_SOURCE_BITS;
  199. char *data_source = prometheus_config_get("data source", "average");
  200. prometheus_exporter_instance->config.options =
  201. exporting_parse_data_source(data_source, prometheus_exporter_instance->config.options);
  202. if (prometheus_config_get_boolean(
  203. "send names instead of ids", global_exporting_options & EXPORTING_OPTION_SEND_NAMES))
  204. prometheus_exporter_instance->config.options |= EXPORTING_OPTION_SEND_NAMES;
  205. else
  206. prometheus_exporter_instance->config.options &= ~EXPORTING_OPTION_SEND_NAMES;
  207. if (prometheus_config_get_boolean("send configured labels", CONFIG_BOOLEAN_YES))
  208. prometheus_exporter_instance->config.options |= EXPORTING_OPTION_SEND_CONFIGURED_LABELS;
  209. else
  210. prometheus_exporter_instance->config.options &= ~EXPORTING_OPTION_SEND_CONFIGURED_LABELS;
  211. if (prometheus_config_get_boolean("send automatic labels", CONFIG_BOOLEAN_NO))
  212. prometheus_exporter_instance->config.options |= EXPORTING_OPTION_SEND_AUTOMATIC_LABELS;
  213. else
  214. prometheus_exporter_instance->config.options &= ~EXPORTING_OPTION_SEND_AUTOMATIC_LABELS;
  215. prometheus_exporter_instance->config.charts_pattern = simple_pattern_create(
  216. prometheus_config_get("send charts matching", "*"),
  217. NULL,
  218. SIMPLE_PATTERN_EXACT, true);
  219. prometheus_exporter_instance->config.hosts_pattern = simple_pattern_create(
  220. prometheus_config_get("send hosts matching", "localhost *"), NULL, SIMPLE_PATTERN_EXACT, true);
  221. prometheus_exporter_instance->config.prefix = prometheus_config_get("prefix", global_exporting_prefix);
  222. prometheus_exporter_instance->config.label_prefix = prometheus_config_get("netdata label prefix", "");
  223. prometheus_exporter_instance->config.initialized = 1;
  224. }
  225. while (get_connector_instance(&local_ci)) {
  226. netdata_log_info("Processing connector instance (%s)", local_ci.instance_name);
  227. if (exporter_get_boolean(local_ci.instance_name, "enabled", 0)) {
  228. netdata_log_info(
  229. "Instance (%s) on connector (%s) is enabled and scheduled for activation",
  230. local_ci.instance_name, local_ci.connector_name);
  231. tmp_ci_list = (struct connector_instance_list *)callocz(1, sizeof(struct connector_instance_list));
  232. memcpy(&tmp_ci_list->local_ci, &local_ci, sizeof(local_ci));
  233. tmp_ci_list->exporting_type = exporting_select_type(local_ci.connector_name);
  234. tmp_ci_list->next = tmp_ci_list_prev;
  235. tmp_ci_list_prev = tmp_ci_list;
  236. instances_to_activate++;
  237. } else
  238. netdata_log_info("Instance (%s) on connector (%s) is not enabled", local_ci.instance_name, local_ci.connector_name);
  239. }
  240. if (unlikely(!instances_to_activate)) {
  241. netdata_log_info("No connector instances to activate");
  242. return NULL;
  243. }
  244. engine = (struct engine *)callocz(1, sizeof(struct engine));
  245. // TODO: Check and fill engine fields if actually needed
  246. if (exporting_config_exists) {
  247. engine->config.hostname =
  248. strdupz(exporter_get(CONFIG_SECTION_EXPORTING, "hostname", netdata_configured_hostname));
  249. engine->config.update_every = exporter_get_number(
  250. CONFIG_SECTION_EXPORTING, EXPORTING_UPDATE_EVERY_OPTION_NAME, EXPORTING_UPDATE_EVERY_DEFAULT);
  251. }
  252. while (tmp_ci_list) {
  253. struct instance *tmp_instance;
  254. char *instance_name;
  255. char *default_destination = "localhost";
  256. netdata_log_info("Instance %s on %s", tmp_ci_list->local_ci.instance_name, tmp_ci_list->local_ci.connector_name);
  257. if (tmp_ci_list->exporting_type == EXPORTING_CONNECTOR_TYPE_UNKNOWN) {
  258. netdata_log_error("Unknown exporting connector type");
  259. goto next_connector_instance;
  260. }
  261. #ifndef ENABLE_PROMETHEUS_REMOTE_WRITE
  262. if (tmp_ci_list->exporting_type == EXPORTING_CONNECTOR_TYPE_PROMETHEUS_REMOTE_WRITE) {
  263. netdata_log_error("Prometheus Remote Write support isn't compiled");
  264. goto next_connector_instance;
  265. }
  266. #endif
  267. #ifndef HAVE_KINESIS
  268. if (tmp_ci_list->exporting_type == EXPORTING_CONNECTOR_TYPE_KINESIS) {
  269. netdata_log_error("AWS Kinesis support isn't compiled");
  270. goto next_connector_instance;
  271. }
  272. #endif
  273. #ifndef ENABLE_EXPORTING_PUBSUB
  274. if (tmp_ci_list->exporting_type == EXPORTING_CONNECTOR_TYPE_PUBSUB) {
  275. netdata_log_error("Google Cloud Pub/Sub support isn't compiled");
  276. goto next_connector_instance;
  277. }
  278. #endif
  279. #ifndef HAVE_MONGOC
  280. if (tmp_ci_list->exporting_type == EXPORTING_CONNECTOR_TYPE_MONGODB) {
  281. netdata_log_error("MongoDB support isn't compiled");
  282. goto next_connector_instance;
  283. }
  284. #endif
  285. tmp_instance = (struct instance *)callocz(1, sizeof(struct instance));
  286. tmp_instance->next = engine->instance_root;
  287. engine->instance_root = tmp_instance;
  288. tmp_instance->engine = engine;
  289. tmp_instance->config.type = tmp_ci_list->exporting_type;
  290. instance_name = tmp_ci_list->local_ci.instance_name;
  291. tmp_instance->config.type_name = strdupz(tmp_ci_list->local_ci.connector_name);
  292. tmp_instance->config.name = strdupz(tmp_ci_list->local_ci.instance_name);
  293. tmp_instance->config.update_every =
  294. exporter_get_number(instance_name, EXPORTING_UPDATE_EVERY_OPTION_NAME, EXPORTING_UPDATE_EVERY_DEFAULT);
  295. tmp_instance->config.buffer_on_failures = exporter_get_number(instance_name, "buffer on failures", 10);
  296. tmp_instance->config.timeoutms = exporter_get_number(instance_name, "timeout ms", 10000);
  297. tmp_instance->config.charts_pattern =
  298. simple_pattern_create(exporter_get(instance_name, "send charts matching", "*"), NULL,
  299. SIMPLE_PATTERN_EXACT,
  300. true);
  301. tmp_instance->config.hosts_pattern = simple_pattern_create(
  302. exporter_get(instance_name, "send hosts matching", "localhost *"), NULL, SIMPLE_PATTERN_EXACT, true);
  303. char *data_source = exporter_get(instance_name, "data source", "average");
  304. tmp_instance->config.options = exporting_parse_data_source(data_source, tmp_instance->config.options);
  305. if (EXPORTING_OPTIONS_DATA_SOURCE(tmp_instance->config.options) != EXPORTING_SOURCE_DATA_AS_COLLECTED &&
  306. tmp_instance->config.update_every % localhost->rrd_update_every)
  307. netdata_log_info(
  308. "The update interval %d for instance %s is not a multiple of the database update interval %d. "
  309. "Metric values will deviate at different points in time.",
  310. tmp_instance->config.update_every, tmp_instance->config.name, localhost->rrd_update_every);
  311. if (exporter_get_boolean(instance_name, "send configured labels", CONFIG_BOOLEAN_YES))
  312. tmp_instance->config.options |= EXPORTING_OPTION_SEND_CONFIGURED_LABELS;
  313. else
  314. tmp_instance->config.options &= ~EXPORTING_OPTION_SEND_CONFIGURED_LABELS;
  315. if (exporter_get_boolean(instance_name, "send automatic labels", CONFIG_BOOLEAN_NO))
  316. tmp_instance->config.options |= EXPORTING_OPTION_SEND_AUTOMATIC_LABELS;
  317. else
  318. tmp_instance->config.options &= ~EXPORTING_OPTION_SEND_AUTOMATIC_LABELS;
  319. if (exporter_get_boolean(instance_name, "send names instead of ids", CONFIG_BOOLEAN_YES))
  320. tmp_instance->config.options |= EXPORTING_OPTION_SEND_NAMES;
  321. else
  322. tmp_instance->config.options &= ~EXPORTING_OPTION_SEND_NAMES;
  323. if (exporter_get_boolean(instance_name, "send variables", CONFIG_BOOLEAN_YES))
  324. tmp_instance->config.options |= EXPORTING_OPTION_SEND_VARIABLES;
  325. else
  326. tmp_instance->config.options &= ~EXPORTING_OPTION_SEND_VARIABLES;
  327. if (tmp_instance->config.type == EXPORTING_CONNECTOR_TYPE_PROMETHEUS_REMOTE_WRITE) {
  328. struct prometheus_remote_write_specific_config *connector_specific_config =
  329. callocz(1, sizeof(struct prometheus_remote_write_specific_config));
  330. tmp_instance->config.connector_specific_config = connector_specific_config;
  331. connector_specific_config->remote_write_path =
  332. strdupz(exporter_get(instance_name, "remote write URL path", "/receive"));
  333. }
  334. if (tmp_instance->config.type == EXPORTING_CONNECTOR_TYPE_KINESIS) {
  335. struct aws_kinesis_specific_config *connector_specific_config =
  336. callocz(1, sizeof(struct aws_kinesis_specific_config));
  337. default_destination = "us-east-1";
  338. tmp_instance->config.connector_specific_config = connector_specific_config;
  339. connector_specific_config->stream_name = strdupz(exporter_get(instance_name, "stream name", ""));
  340. connector_specific_config->auth_key_id = strdupz(exporter_get(instance_name, "aws_access_key_id", ""));
  341. connector_specific_config->secure_key = strdupz(exporter_get(instance_name, "aws_secret_access_key", ""));
  342. }
  343. if (tmp_instance->config.type == EXPORTING_CONNECTOR_TYPE_PUBSUB) {
  344. struct pubsub_specific_config *connector_specific_config =
  345. callocz(1, sizeof(struct pubsub_specific_config));
  346. default_destination = "pubsub.googleapis.com";
  347. tmp_instance->config.connector_specific_config = connector_specific_config;
  348. connector_specific_config->credentials_file = strdupz(exporter_get(instance_name, "credentials file", ""));
  349. connector_specific_config->project_id = strdupz(exporter_get(instance_name, "project id", ""));
  350. connector_specific_config->topic_id = strdupz(exporter_get(instance_name, "topic id", ""));
  351. }
  352. if (tmp_instance->config.type == EXPORTING_CONNECTOR_TYPE_MONGODB) {
  353. struct mongodb_specific_config *connector_specific_config =
  354. callocz(1, sizeof(struct mongodb_specific_config));
  355. tmp_instance->config.connector_specific_config = connector_specific_config;
  356. connector_specific_config->database = strdupz(exporter_get(
  357. instance_name, "database", ""));
  358. connector_specific_config->collection = strdupz(exporter_get(
  359. instance_name, "collection", ""));
  360. }
  361. tmp_instance->config.destination = strdupz(exporter_get(instance_name, "destination", default_destination));
  362. tmp_instance->config.username = strdupz(exporter_get(instance_name, "username", ""));
  363. tmp_instance->config.password = strdupz(exporter_get(instance_name, "password", ""));
  364. tmp_instance->config.prefix = strdupz(exporter_get(instance_name, "prefix", "netdata"));
  365. tmp_instance->config.hostname = strdupz(exporter_get(instance_name, "hostname", engine->config.hostname));
  366. #ifdef ENABLE_HTTPS
  367. #define STR_GRAPHITE_HTTPS "graphite:https"
  368. #define STR_JSON_HTTPS "json:https"
  369. #define STR_OPENTSDB_HTTPS "opentsdb:https"
  370. #define STR_PROMETHEUS_REMOTE_WRITE_HTTPS "prometheus_remote_write:https"
  371. if ((tmp_instance->config.type == EXPORTING_CONNECTOR_TYPE_GRAPHITE_HTTP &&
  372. !strncmp(tmp_ci_list->local_ci.connector_name, STR_GRAPHITE_HTTPS, strlen(STR_GRAPHITE_HTTPS))) ||
  373. (tmp_instance->config.type == EXPORTING_CONNECTOR_TYPE_JSON_HTTP &&
  374. !strncmp(tmp_ci_list->local_ci.connector_name, STR_JSON_HTTPS, strlen(STR_JSON_HTTPS))) ||
  375. (tmp_instance->config.type == EXPORTING_CONNECTOR_TYPE_OPENTSDB_HTTP &&
  376. !strncmp(tmp_ci_list->local_ci.connector_name, STR_OPENTSDB_HTTPS, strlen(STR_OPENTSDB_HTTPS))) ||
  377. (tmp_instance->config.type == EXPORTING_CONNECTOR_TYPE_PROMETHEUS_REMOTE_WRITE &&
  378. !strncmp(
  379. tmp_ci_list->local_ci.connector_name, STR_PROMETHEUS_REMOTE_WRITE_HTTPS,
  380. strlen(STR_PROMETHEUS_REMOTE_WRITE_HTTPS)))) {
  381. tmp_instance->config.options |= EXPORTING_OPTION_USE_TLS;
  382. }
  383. #endif
  384. #ifdef NETDATA_INTERNAL_CHECKS
  385. netdata_log_info(
  386. " Dest=[%s], upd=[%d], buffer=[%d] timeout=[%ld] options=[%u]",
  387. tmp_instance->config.destination,
  388. tmp_instance->config.update_every,
  389. tmp_instance->config.buffer_on_failures,
  390. tmp_instance->config.timeoutms,
  391. tmp_instance->config.options);
  392. #endif
  393. if (unlikely(!exporting_config_exists) && !engine->config.hostname) {
  394. engine->config.hostname = strdupz(config_get(instance_name, "hostname", netdata_configured_hostname));
  395. engine->config.update_every =
  396. config_get_number(instance_name, EXPORTING_UPDATE_EVERY_OPTION_NAME, EXPORTING_UPDATE_EVERY_DEFAULT);
  397. }
  398. next_connector_instance:
  399. tmp_ci_list1 = tmp_ci_list->next;
  400. freez(tmp_ci_list);
  401. tmp_ci_list = tmp_ci_list1;
  402. }
  403. return engine;
  404. }