summaryrefslogtreecommitdiffstats
path: root/src/fluent-bit/plugins/in_node_exporter_metrics/ne_utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fluent-bit/plugins/in_node_exporter_metrics/ne_utils.c')
-rw-r--r--src/fluent-bit/plugins/in_node_exporter_metrics/ne_utils.c256
1 files changed, 256 insertions, 0 deletions
diff --git a/src/fluent-bit/plugins/in_node_exporter_metrics/ne_utils.c b/src/fluent-bit/plugins/in_node_exporter_metrics/ne_utils.c
new file mode 100644
index 000000000..54cb2e2da
--- /dev/null
+++ b/src/fluent-bit/plugins/in_node_exporter_metrics/ne_utils.c
@@ -0,0 +1,256 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+
+/* Fluent Bit
+ * ==========
+ * Copyright (C) 2015-2022 The Fluent Bit Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <fluent-bit/flb_info.h>
+#include <fluent-bit/flb_input_plugin.h>
+#include <fluent-bit/flb_sds.h>
+#include "ne.h"
+
+/* required by stat(2), open(2) */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include <glob.h>
+
+int ne_utils_str_to_double(char *str, double *out_val)
+{
+ double val;
+ char *end;
+
+ errno = 0;
+ val = strtod(str, &end);
+ if (errno != 0 || *end != '\0') {
+ return -1;
+ }
+ *out_val = val;
+ return 0;
+}
+
+int ne_utils_str_to_uint64(char *str, uint64_t *out_val)
+{
+ uint64_t val;
+ char *end;
+
+ errno = 0;
+ val = strtoll(str, &end, 10);
+ if ((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN))
+ || (errno != 0 && val == 0)) {
+ flb_errno();
+ return -1;
+ }
+
+ if (end == str) {
+ return -1;
+ }
+
+ *out_val = val;
+ return 0;
+}
+
+int ne_utils_file_read_uint64(const char *mount,
+ const char *path,
+ const char *join_a, const char *join_b,
+ uint64_t *out_val)
+{
+ int fd;
+ int len;
+ int ret;
+ flb_sds_t p;
+ uint64_t val;
+ ssize_t bytes;
+ char tmp[32];
+
+ /* Check the path starts with the mount point to prevent duplication. */
+ if (strncasecmp(path, mount, strlen(mount)) == 0 &&
+ path[strlen(mount)] == '/') {
+ mount = "";
+ }
+
+ /* Compose the final path */
+ p = flb_sds_create(mount);
+ if (!p) {
+ return -1;
+ }
+
+ len = strlen(path);
+ flb_sds_cat_safe(&p, path, len);
+
+ if (join_a) {
+ flb_sds_cat_safe(&p, "/", 1);
+ len = strlen(join_a);
+ flb_sds_cat_safe(&p, join_a, len);
+ }
+
+ if (join_b) {
+ flb_sds_cat_safe(&p, "/", 1);
+ len = strlen(join_b);
+ flb_sds_cat_safe(&p, join_b, len);
+ }
+
+ fd = open(p, O_RDONLY);
+ if (fd == -1) {
+ flb_sds_destroy(p);
+ return -1;
+ }
+ flb_sds_destroy(p);
+
+ bytes = read(fd, &tmp, sizeof(tmp));
+ if (bytes == -1) {
+ flb_errno();
+ close(fd);
+ return -1;
+ }
+ close(fd);
+
+ ret = ne_utils_str_to_uint64(tmp, &val);
+ if (ret == -1) {
+ return -1;
+ }
+
+ *out_val = val;
+ return 0;
+}
+
+/*
+ * Read a file and every non-empty line is stored as a flb_slist_entry in the
+ * given list.
+ */
+int ne_utils_file_read_lines(const char *mount, const char *path, struct mk_list *list)
+{
+ int len;
+ int ret;
+ FILE *f;
+ char line[512];
+ char real_path[2048];
+
+ mk_list_init(list);
+
+ /* Check the path starts with the mount point to prevent duplication. */
+ if (strncasecmp(path, mount, strlen(mount)) == 0 &&
+ path[strlen(mount)] == '/') {
+ mount = "";
+ }
+
+ snprintf(real_path, sizeof(real_path) - 1, "%s%s", mount, path);
+ f = fopen(real_path, "r");
+ if (f == NULL) {
+ flb_errno();
+ return -1;
+ }
+
+ /* Read the content */
+ while (fgets(line, sizeof(line) - 1, f)) {
+ len = strlen(line);
+ if (line[len - 1] == '\n') {
+ line[--len] = 0;
+ if (len && line[len - 1] == '\r') {
+ line[--len] = 0;
+ }
+ }
+
+ ret = flb_slist_add(list, line);
+ if (ret == -1) {
+ fclose(f);
+ flb_slist_destroy(list);
+ return -1;
+ }
+ }
+
+ fclose(f);
+ return 0;
+}
+
+int ne_utils_path_scan(struct flb_ne *ctx, const char *mount, const char *path,
+ int expected, struct mk_list *list)
+{
+ int i;
+ int ret;
+ glob_t globbuf;
+ struct stat st;
+ char real_path[2048];
+
+ if (!path) {
+ return -1;
+ }
+
+ /* Safe reset for globfree() */
+ globbuf.gl_pathv = NULL;
+
+ /* Scan the real path */
+ snprintf(real_path, sizeof(real_path) - 1, "%s%s", mount, path);
+ ret = glob(real_path, GLOB_TILDE | GLOB_ERR, NULL, &globbuf);
+ if (ret != 0) {
+ switch (ret) {
+ case GLOB_NOSPACE:
+ flb_plg_error(ctx->ins, "no memory space available");
+ return -1;
+ case GLOB_ABORTED:
+ flb_plg_error(ctx->ins, "read error, check permissions: %s", path);
+ return -1;;
+ case GLOB_NOMATCH:
+ ret = stat(path, &st);
+ if (ret == -1) {
+ flb_plg_debug(ctx->ins, "cannot read info from: %s", path);
+ }
+ else {
+ ret = access(path, R_OK);
+ if (ret == -1 && errno == EACCES) {
+ flb_plg_error(ctx->ins, "NO read access for path: %s", path);
+ }
+ else {
+ flb_plg_debug(ctx->ins, "NO matches for path: %s", path);
+ }
+ }
+ return -1;
+ }
+ }
+
+ if (globbuf.gl_pathc <= 0) {
+ globfree(&globbuf);
+ return -1;
+ }
+
+ /* Initialize list */
+ flb_slist_create(list);
+
+ /* For every entry found, generate an output list */
+ for (i = 0; i < globbuf.gl_pathc; i++) {
+ ret = stat(globbuf.gl_pathv[i], &st);
+ if (ret != 0) {
+ continue;
+ }
+
+ if ((expected == NE_SCAN_FILE && S_ISREG(st.st_mode)) ||
+ (expected == NE_SCAN_DIR && S_ISDIR(st.st_mode))) {
+
+ /* Compose the path */
+ ret = flb_slist_add(list, globbuf.gl_pathv[i]);
+ if (ret != 0) {
+ globfree(&globbuf);
+ flb_slist_destroy(list);
+ return -1;
+ }
+ }
+ }
+
+ globfree(&globbuf);
+ return 0;
+}