diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 2715876119d..13f8d67ad36 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -205,10 +205,13 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") REGISTER_IN_PLUGIN("in_netif") REGISTER_IN_PLUGIN("in_docker") REGISTER_IN_PLUGIN("in_docker_events") - REGISTER_IN_PLUGIN("in_node_exporter_metrics") REGISTER_IN_PLUGIN("in_podman_metrics") endif() +if(${CMAKE_SYSTEM_NAME} MATCHES "Linux" OR ${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + REGISTER_IN_PLUGIN("in_node_exporter_metrics") +endif() + REGISTER_IN_PLUGIN("in_kubernetes_events") REGISTER_IN_PLUGIN("in_kafka") REGISTER_IN_PLUGIN("in_fluentbit_metrics") diff --git a/plugins/in_node_exporter_metrics/CMakeLists.txt b/plugins/in_node_exporter_metrics/CMakeLists.txt index 16584dc0609..79f82e9c8eb 100644 --- a/plugins/in_node_exporter_metrics/CMakeLists.txt +++ b/plugins/in_node_exporter_metrics/CMakeLists.txt @@ -23,4 +23,8 @@ set(src ) endif() -FLB_PLUGIN(in_node_exporter_metrics "${src}" "") +if (APPLE) + FLB_PLUGIN(in_node_exporter_metrics "${src}" "-framework Foundation -framework IOKit") +else() + FLB_PLUGIN(in_node_exporter_metrics "${src}" "") +endif() diff --git a/plugins/in_node_exporter_metrics/ne.c b/plugins/in_node_exporter_metrics/ne.c index d7781795788..395056a94c7 100644 --- a/plugins/in_node_exporter_metrics/ne.c +++ b/plugins/in_node_exporter_metrics/ne.c @@ -1015,7 +1015,7 @@ static struct flb_config_map config_map[] = { { FLB_CONFIG_MAP_CLIST, "metrics", - "cpu,cpufreq,meminfo,diskstats,filesystem,uname,stat,time,loadavg,vmstat,netdev,filefd,systemd", + NE_DEFAULT_ENABLED_METRICS, 0, FLB_TRUE, offsetof(struct flb_ne, metrics), "Comma separated list of keys to enable metrics." }, diff --git a/plugins/in_node_exporter_metrics/ne.h b/plugins/in_node_exporter_metrics/ne.h index ba6e89caa94..a9bfc73eeba 100644 --- a/plugins/in_node_exporter_metrics/ne.h +++ b/plugins/in_node_exporter_metrics/ne.h @@ -30,6 +30,14 @@ #include #include +/* Default enabled metrics */ + +#ifdef __linux__ +#define NE_DEFAULT_ENABLED_METRICS "cpu,cpufreq,meminfo,diskstats,filesystem,uname,stat,time,loadavg,vmstat,netdev,filefd,systemd" +#elif __APPLE__ +#define NE_DEFAULT_ENABLED_METRICS "cpu,loadavg,meminfo,diskstats,uname,netdev" +#endif + /* filesystem: regex for ignoring mount points and filesystem types */ #define IGNORED_MOUNT_POINTS "^/(dev|proc|run/credentials/.+|sys|var/lib/docker/.+|var/lib/containers/storage/.+)($|/)" @@ -108,6 +116,22 @@ struct flb_ne { /* meminfo hash table */ struct flb_hash_table *meminfo_ht; +#ifdef FLB_SYSTEM_MACOS + /* meminfo_darwin */ + struct cmt_gauge *darwin_free_bytes; + struct cmt_gauge *darwin_active_bytes; + struct cmt_gauge *darwin_compressed_bytes; + struct cmt_gauge *darwin_inactive_bytes; + struct cmt_gauge *darwin_wired_bytes; + struct cmt_gauge *darwin_internal_bytes; + struct cmt_gauge *darwin_purgeable_bytes; + struct cmt_counter *darwin_pageins_bytes; + struct cmt_counter *darwin_pageouts_bytes; + struct cmt_gauge *darwin_swap_used_bytes; + struct cmt_gauge *darwin_swap_total_bytes; + struct cmt_counter *darwin_total_bytes; +#endif + /* diskstats: abbreviation 'dt' */ void *dt_metrics; struct flb_regex *dt_regex_skip_devices; @@ -131,6 +155,21 @@ struct flb_ne { /* netdev */ struct flb_hash_table *netdev_ht; +#ifdef FLB_SYSTEM_MACOS + /* netdev_darwin */ + struct cmt_gauge *darwin_receive_packets; + struct cmt_gauge *darwin_transmit_packets; + struct cmt_gauge *darwin_receive_bytes; + struct cmt_gauge *darwin_transmit_bytes; + struct cmt_gauge *darwin_receive_errors; + struct cmt_gauge *darwin_transmit_errors; + struct cmt_gauge *darwin_receive_dropped; + struct cmt_gauge *darwin_receive_multicast; + struct cmt_gauge *darwin_transmit_multicast; + struct cmt_gauge *darwin_collisions; + struct cmt_gauge *darwin_noproto; +#endif + /* time */ struct cmt_gauge *time; diff --git a/plugins/in_node_exporter_metrics/ne_cpu.c b/plugins/in_node_exporter_metrics/ne_cpu.c index 70fd33ca13d..e92c3334359 100644 --- a/plugins/in_node_exporter_metrics/ne_cpu.c +++ b/plugins/in_node_exporter_metrics/ne_cpu.c @@ -20,4 +20,6 @@ #ifdef __linux__ #include "ne_cpu_linux.c" #include "ne_cpufreq_linux.c" +#elif __APPLE__ +#include "ne_cpu_darwin.c" #endif diff --git a/plugins/in_node_exporter_metrics/ne_cpu.h b/plugins/in_node_exporter_metrics/ne_cpu.h index 52c6b574fd5..814652ea6db 100644 --- a/plugins/in_node_exporter_metrics/ne_cpu.h +++ b/plugins/in_node_exporter_metrics/ne_cpu.h @@ -22,7 +22,41 @@ #include "ne.h" +#ifdef __linux__ int ne_cpu_init(struct flb_ne *ctx); int ne_cpu_update(struct flb_ne *ctx); +#elif __APPLE__ +int ne_cpu_init(struct flb_ne *ctx); +int ne_cpu_update(struct flb_ne *ctx); +static int ne_cpufreq_init(struct flb_ne *ctx) +{ + return 0; +} + +static int ne_cpufreq_update(struct flb_ne *ctx) +{ + return 0; +} +#else +static int ne_cpu_init(struct flb_ne *ctx) +{ + return 0; +} + +static int ne_cpu_update(struct flb_ne *ctx) +{ + return 0; +} + +static int ne_cpufreq_init(struct flb_ne *ctx) +{ + return 0; +} + +static int ne_cpufreq_update(struct flb_ne *ctx) +{ + return 0; +} +#endif #endif diff --git a/plugins/in_node_exporter_metrics/ne_cpu_darwin.c b/plugins/in_node_exporter_metrics/ne_cpu_darwin.c new file mode 100644 index 00000000000..983e763f5ac --- /dev/null +++ b/plugins/in_node_exporter_metrics/ne_cpu_darwin.c @@ -0,0 +1,133 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +/* Fluent Bit + * ========== + * Copyright (C) 2023 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 +#include + +#include "ne.h" +#include "ne_utils.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if TARGET_OS_MAC +#include +#endif +#include +#include + +/* + * CPU stats from host_processor_info() + * + * https://developer.apple.com/documentation/kernel/1502854-host_processor_info + * --------------------------- + */ +static inline int cpu_stat_init(struct flb_ne *ctx) +{ + struct cmt_counter *c; + + c = cmt_counter_create(ctx->cmt, "node", "cpu", "seconds_total", + "Seconds the CPUs spent in each mode.", + 2, (char *[]) {"cpu", "mode"}); + if (!c) { + return -1; + } + ctx->cpu_seconds = c; + + return 0; +} + +int ne_cpu_init(struct flb_ne *ctx) +{ + int ret; + + /* CPU Stats */ + ret = cpu_stat_init(ctx); + if (ret == -1) { + flb_plg_error(ctx->ins, "could not initialize cpu_stat metrics"); + return -1; + } + + return 0; +} + +static int cpu_stat_update(struct flb_ne *ctx, uint64_t ts) +{ + int i; + mach_msg_type_number_t count; + processor_cpu_load_info_t pinfo; + natural_t ncpu; + kern_return_t err; + char cpu_id[8]; + double clock_per_sec = CLK_TCK; + + err = host_processor_info(mach_host_self(), + PROCESSOR_CPU_LOAD_INFO, + &ncpu, + (processor_info_array_t *)(&pinfo), + &count); + + if (err != KERN_SUCCESS) { + flb_plg_error(ctx->ins, "host_processor_info() is failed with error = %d", err); + return -1; + } + + for (i = 0; i < ncpu; i++) { + snprintf(cpu_id, sizeof(cpu_id), "%d", i); + + /* CPU seconds */ + cmt_counter_set(ctx->cpu_seconds, ts, + pinfo[i].cpu_ticks[CPU_STATE_USER]/clock_per_sec, + 2, (char *[]) {cpu_id, "user"}); + + cmt_counter_set(ctx->cpu_seconds, ts, + pinfo[i].cpu_ticks[CPU_STATE_SYSTEM]/clock_per_sec, + 2, (char *[]) {cpu_id, "system"}); + + cmt_counter_set(ctx->cpu_seconds, ts, + pinfo[i].cpu_ticks[CPU_STATE_NICE]/clock_per_sec, + 2, (char *[]) {cpu_id, "nice"}); + + cmt_counter_set(ctx->cpu_seconds, ts, + pinfo[i].cpu_ticks[CPU_STATE_IDLE]/clock_per_sec, + 2, (char *[]) {cpu_id, "idle"}); + } + + vm_deallocate(mach_task_self(), (vm_address_t)pinfo, + (vm_size_t)sizeof(*pinfo) * ncpu); + + return 0; +} + +int ne_cpu_update(struct flb_ne *ctx) +{ + uint64_t ts; + + ts = cfl_time_now(); + + cpu_stat_update(ctx, ts); + + return 0; +} diff --git a/plugins/in_node_exporter_metrics/ne_diskstats.c b/plugins/in_node_exporter_metrics/ne_diskstats.c index 0b4ac57f140..5bb246235c9 100644 --- a/plugins/in_node_exporter_metrics/ne_diskstats.c +++ b/plugins/in_node_exporter_metrics/ne_diskstats.c @@ -19,4 +19,6 @@ #ifdef __linux__ #include "ne_diskstats_linux.c" +#elif __APPLE__ +#include "ne_diskstats_darwin.c" #endif diff --git a/plugins/in_node_exporter_metrics/ne_diskstats.h b/plugins/in_node_exporter_metrics/ne_diskstats.h index 4904e33ef33..34cc111f503 100644 --- a/plugins/in_node_exporter_metrics/ne_diskstats.h +++ b/plugins/in_node_exporter_metrics/ne_diskstats.h @@ -22,8 +22,25 @@ #include "ne.h" +#if defined(__linux__) || defined(__APPLE__) int ne_diskstats_init(struct flb_ne *ctx); int ne_diskstats_update(struct flb_ne *ctx); int ne_diskstats_exit(struct flb_ne *ctx); +#else +static int ne_diskstats_init(struct flb_ne *ctx) +{ + return 0; +} + +static int ne_diskstats_update(struct flb_ne *ctx) +{ + return 0; +} + +static int ne_diskstats_exit(struct flb_ne *ctx) +{ + return 0; +} +#endif #endif diff --git a/plugins/in_node_exporter_metrics/ne_diskstats_darwin.c b/plugins/in_node_exporter_metrics/ne_diskstats_darwin.c new file mode 100644 index 00000000000..55c6bafedc6 --- /dev/null +++ b/plugins/in_node_exporter_metrics/ne_diskstats_darwin.c @@ -0,0 +1,484 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +/* Fluent Bit + * ========== + * Copyright (C) 2023 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 +#include +#include + +#include "ne.h" +#include "ne_utils.h" + +#ifdef __MACH__ +#include +#include +#include +#endif + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#if (MAC_OS_X_VERSION_MIN_REQUIRED < 120000) + /* If deployent target is before macOS 12.0, use the old name. */ + #define IOMainPort IOMasterPort +#endif + +#define TARGET_METRICS 11 +#define DRIVE_NAME_LEN 31 + +struct dt_metric { + void *metric; + double factor; +}; + +static void metric_cache_set(struct flb_ne *ctx, void *metric, double factor, int *offset) +{ + int id; + struct dt_metric *m; + struct dt_metric **cache; + + id = *offset; + + cache = (struct dt_metric **) ctx->dt_metrics; + m = (struct dt_metric *) &cache[id]; + m->metric = metric; + m->factor = factor; + (*offset)++; +} + +static void metric_cache_update(struct flb_ne *ctx, int id, flb_sds_t device, + double val) +{ + int ret = -1; + uint64_t ts; + struct dt_metric *m; + struct dt_metric **cache; + struct cmt_counter *c; + + cache = (struct dt_metric **) ctx->dt_metrics; + m = (struct dt_metric *) &cache[id]; + + ts = cfl_time_now(); + + if (m->factor > DBL_EPSILON) { + val *= m->factor; + } + + c = (struct cmt_counter *) m->metric; + ret = cmt_counter_set(c, ts, val, 1, (char *[]) {device}); + + if (ret == -1) { + flb_plg_error(ctx->ins, + "could not update metric id '%i', device '%s'", + id, device); + } +} + +/* List of the diskstats metrics on macOS + * + * 0. node_disk_reads_completed_total + * 1. node_disk_read_sectors_total + * 2. node_disk_read_time_seconds_total + * 3. node_disk_writes_completed_total + * 4. node_disk_written_sectors_total + * 5. node_disk_write_time_seconds_total + * 6. node_disk_read_bytes_total + * 7. node_disk_written_bytes_total + * 8. node_disk_read_errors_total + * 9. node_disk_write_errors_total + * 10. node_disk_read_retries_total + * 11. node_disk_write_retries_total + * + */ + +/* Setup metrics contexts */ +static int ne_diskstats_configure(struct flb_ne *ctx) +{ + int offset = 0; + struct cmt_counter *c; + + + /* Create cache for metrics */ + ctx->dt_metrics = flb_calloc(1, sizeof(struct dt_metric) * TARGET_METRICS); + if (!ctx->dt_metrics) { + flb_errno(); + return -1; + } + + /* Initialize regex for skipped devices */ + ctx->dt_regex_skip_devices = flb_regex_create(ctx->dt_regex_skip_devices_text); + if (!ctx->dt_regex_skip_devices) { + flb_plg_error(ctx->ins, + "could not initialize regex pattern for ignored " + "devices: '%s'", + IGNORED_DEVICES); + return -1; + } + + /* node_disk_reads_completed_total */ + c = cmt_counter_create(ctx->cmt, "node", "disk", "reads_completed_total", + "The total number of reads completed successfully.", + 1, (char *[]) {"device"}); + if (!c) { + return -1; + } + metric_cache_set(ctx, c, 0, &offset); + + /* node_disk_read_sectors_total */ + c = cmt_counter_create(ctx->cmt, "node", "disk", "reads_sectors_total", + "The total number of sectors read successfully.", + 1, (char *[]) {"device"}); + if (!c) { + return -1; + } + metric_cache_set(ctx, c, 0, &offset); + + /* node_disk_read_time_seconds_total */ + c = cmt_counter_create(ctx->cmt, "node", "disk", "read_time_seconds_total", + "The total number of seconds spent by all reads.", + 1, (char *[]) {"device"}); + if (!c) { + return -1; + } + metric_cache_set(ctx, c, 0, &offset); + + /* node_disk_writes_completed_total */ + c = cmt_counter_create(ctx->cmt, "node", "disk", "writes_completed_total", + "The total number of writes completed successfully.", + 1, (char *[]) {"device"}); + if (!c) { + return -1; + } + metric_cache_set(ctx, c, 0, &offset); + + /* node_disk_written_sectors_total */ + c = cmt_counter_create(ctx->cmt, "node", "disk", "written_sectors_total", + "The total number of sectors written successfully.", + 1, (char *[]) {"device"}); + if (!c) { + return -1; + } + metric_cache_set(ctx, c, 0, &offset); + + /* node_disk_write_time_seconds_total */ + c = cmt_counter_create(ctx->cmt, "node", "disk", "write_time_seconds_total", + "This is the total number of seconds spent by all writes.", + 1, (char *[]) {"device"}); + if (!c) { + return -1; + } + metric_cache_set(ctx, c, 0, &offset); + + /* node_disk_read_bytes_total */ + c = cmt_counter_create(ctx->cmt, "node", "disk", "read_bytes_total", + "The total number of read bytes successfully.", + 1, (char *[]) {"device"}); + if (!c) { + return -1; + } + metric_cache_set(ctx, c, 0, &offset); + + /* node_disk_written_bytes_total */ + c = cmt_counter_create(ctx->cmt, "node", "disk", "written_bytes_total", + "The total number of written bytes successfully.", + 1, (char *[]) {"device"}); + if (!c) { + return -1; + } + metric_cache_set(ctx, c, 0, &offset); + + /* node_disk_read_errors_total */ + c = cmt_counter_create(ctx->cmt, "node", "disk", "read_errors_total", + "The total number of read errors.", + 1, (char *[]) {"device"}); + if (!c) { + return -1; + } + metric_cache_set(ctx, c, 0, &offset); + + /* node_disk_write_errors_total */ + c = cmt_counter_create(ctx->cmt, "node", "disk", "write_errors_total", + "The total number of write errors.", + 1, (char *[]) {"device"}); + if (!c) { + return -1; + } + metric_cache_set(ctx, c, 0, &offset); + + /* node_disk_read_retries_total */ + c = cmt_counter_create(ctx->cmt, "node", "disk", "read_retries_total", + "The total number of read retries.", + 1, (char *[]) {"device"}); + if (!c) { + return -1; + } + metric_cache_set(ctx, c, 0, &offset); + + /* node_disk_write_retries_total */ + c = cmt_counter_create(ctx->cmt, "node", "disk", "write_retries_total", + "The total number of write errors.", + 1, (char *[]) {"device"}); + if (!c) { + return -1; + } + metric_cache_set(ctx, c, 0, &offset); + + return 0; +} + + +static int skip_device(struct flb_ne *ctx, flb_sds_t device) +{ + return flb_regex_match(ctx->dt_regex_skip_devices, + (unsigned char *) device, flb_sds_len(device)); +} + +static int diskstats_update(struct flb_ne *ctx) +{ + char drive_name[DRIVE_NAME_LEN+1]; + flb_sds_t device; + mach_port_t iokit_port = MACH_PORT_NULL; + io_iterator_t drive_list; + io_registry_entry_t drive, media; + CFMutableDictionaryRef properties = NULL; + CFDictionaryRef statistics; + CFNumberRef number; + CFStringRef name; + int64_t value; + kern_return_t err; + int64_t blocksize; + + err = IOMainPort(bootstrap_port, &iokit_port); + + if (err != KERN_SUCCESS) { + flb_plg_error(ctx->ins, "calling IOMainPort is failed"); + + return -1; + } + + /* Get the list of all drives */ + if (IOServiceGetMatchingServices(iokit_port, + IOServiceMatching("IOBlockStorageDriver"), + &drive_list)) { + flb_plg_error(ctx->ins, "calling IOBlockStorageDirver is failed"); + + return -1; + + + } + + while ((drive = IOIteratorNext(drive_list)) != 0) { + properties = NULL; + + err = IORegistryEntryGetChildEntry(drive, kIOServicePlane, &media); + if (err != KERN_SUCCESS) { + IOObjectRelease(drive); + flb_plg_warn(ctx->ins, "calling IORegistryEntryGetChildEntry is failed"); + + continue; + } + + if (IORegistryEntryCreateCFProperties(media, (CFMutableDictionaryRef *)&properties, + kCFAllocatorDefault, kNilOptions) == KERN_SUCCESS) { + name = (CFStringRef)CFDictionaryGetValue(properties, + CFSTR(kIOBSDNameKey)); + if (name != NULL) { + CFStringGetCString(name, drive_name, DRIVE_NAME_LEN, CFStringGetSystemEncoding()); + device = flb_sds_create_len(drive_name, strlen(drive_name)); + if (skip_device(ctx, device)) { + flb_plg_debug(ctx->ins, "skip device: %s", device); + flb_sds_destroy(device); + + continue; + } + } + else { + device = flb_sds_create_len("(unknown)", strlen("(unknown)")); + } + } + + /* Get blocksize */ + number = (CFNumberRef)CFDictionaryGetValue(properties, CFSTR(kIOMediaPreferredBlockSizeKey)); + CFNumberGetValue(number, kCFNumberSInt64Type, &blocksize); + + /* Teardown */ + CFRelease(properties); + IOObjectRelease(media); + + /* Get the properties of this drive */ + if (IORegistryEntryCreateCFProperties(drive, &properties, + kCFAllocatorDefault, kNilOptions) != KERN_SUCCESS) { + IOObjectRelease(drive); + IOObjectRelease(drive_list); + flb_sds_destroy(device); + flb_plg_error(ctx->ins, "calling IORegistryEntryCreateCFProperties is failed"); + + return -1; + } + + if (!properties) { + IOObjectRelease(drive); + flb_sds_destroy(device); + + continue; + } + + /* Get the statistics of this drive */ + statistics = (CFDictionaryRef)CFDictionaryGetValue(properties, + CFSTR(kIOBlockStorageDriverStatisticsKey)); + + if (!statistics) { + CFRelease(properties); + IOObjectRelease(drive); + flb_sds_destroy(device); + + continue; + } + + /* Get number of read and sectors read */ + number = (CFNumberRef)CFDictionaryGetValue(statistics, + CFSTR(kIOBlockStorageDriverStatisticsReadsKey)); + if (number != 0) { + CFNumberGetValue(number, kCFNumberSInt64Type, &value); + metric_cache_update(ctx, 0, device, (double)value); + metric_cache_update(ctx, 1, device, (double)value/blocksize); + } + + /* Get number of write and sectors write */ + number = (CFNumberRef)CFDictionaryGetValue(statistics, + CFSTR(kIOBlockStorageDriverStatisticsWritesKey)); + if (number != 0) { + CFNumberGetValue(number, kCFNumberSInt64Type, &value); + metric_cache_update(ctx, 3, device, (double)value); + metric_cache_update(ctx, 4, device, (double)value/blocksize); + } + + /* Get bytes read */ + number = (CFNumberRef)CFDictionaryGetValue(statistics, + CFSTR(kIOBlockStorageDriverStatisticsBytesReadKey)); + if (number != 0) { + CFNumberGetValue(number, kCFNumberSInt64Type, &value); + metric_cache_update(ctx, 6, device, (double)value); + } + + /* Get bytes written */ + number = (CFNumberRef)CFDictionaryGetValue(statistics, + CFSTR(kIOBlockStorageDriverStatisticsBytesWrittenKey)); + if (number != 0) { + CFNumberGetValue(number, kCFNumberSInt64Type, &value); + metric_cache_update(ctx, 7, device, (double)value); + } + + /* Get total read time (in seconds) */ + number = (CFNumberRef)CFDictionaryGetValue(statistics, + CFSTR(kIOBlockStorageDriverStatisticsTotalReadTimeKey)); + if (number != 0) { + CFNumberGetValue(number, kCFNumberSInt64Type, &value); + metric_cache_update(ctx, 2, device, (double)value/1e9); + } + + /* Get total write time (in seconds) */ + number = (CFNumberRef)CFDictionaryGetValue(statistics, + CFSTR(kIOBlockStorageDriverStatisticsTotalWriteTimeKey)); + if (number != 0) { + CFNumberGetValue(number, kCFNumberSInt64Type, &value); + metric_cache_update(ctx, 5, device, (double)value/1e9); + } + + /* Get read errors */ + number = (CFNumberRef)CFDictionaryGetValue(statistics, + CFSTR(kIOBlockStorageDriverStatisticsReadErrorsKey)); + if (number != 0) { + CFNumberGetValue(number, kCFNumberSInt64Type, &value); + metric_cache_update(ctx, 8, device, (double)value); + } + + /* Get write errors */ + number = (CFNumberRef)CFDictionaryGetValue(statistics, + CFSTR(kIOBlockStorageDriverStatisticsWriteErrorsKey)); + if (number != 0) { + CFNumberGetValue(number, kCFNumberSInt64Type, &value); + metric_cache_update(ctx, 9, device, (double)value); + } + + /* Get read retries */ + number = (CFNumberRef)CFDictionaryGetValue(statistics, + CFSTR(kIOBlockStorageDriverStatisticsReadRetriesKey)); + if (number != 0) { + CFNumberGetValue(number, kCFNumberSInt64Type, &value); + metric_cache_update(ctx, 10, device, (double)value); + } + + /* Get write retries */ + number = (CFNumberRef)CFDictionaryGetValue(statistics, + CFSTR(kIOBlockStorageDriverStatisticsWriteRetriesKey)); + if (number != 0) { + CFNumberGetValue(number, kCFNumberSInt64Type, &value); + metric_cache_update(ctx, 11, device, (double)value); + } + + flb_sds_destroy(device); + CFRelease(properties); + IOObjectRelease(drive); + } + + if (drive_list) { + IOObjectRelease(drive_list); + } + + if (iokit_port != MACH_PORT_NULL) { + mach_port_deallocate(mach_task_self(), iokit_port); + iokit_port = MACH_PORT_NULL; + } + + return 0; +} + +int ne_diskstats_init(struct flb_ne *ctx) +{ + ne_diskstats_configure(ctx); + return 0; +} + +int ne_diskstats_update(struct flb_ne *ctx) +{ + diskstats_update(ctx); + return 0; +} + +int ne_diskstats_exit(struct flb_ne *ctx) +{ + flb_free(ctx->dt_metrics); + if (ctx->dt_regex_skip_devices) { + flb_regex_destroy(ctx->dt_regex_skip_devices); + } + return 0; +} diff --git a/plugins/in_node_exporter_metrics/ne_filefd_linux.h b/plugins/in_node_exporter_metrics/ne_filefd_linux.h index ef9df5d1c4d..659cfd6298c 100644 --- a/plugins/in_node_exporter_metrics/ne_filefd_linux.h +++ b/plugins/in_node_exporter_metrics/ne_filefd_linux.h @@ -22,7 +22,19 @@ #include "ne.h" +#ifdef __linux__ int ne_filefd_init(struct flb_ne *ctx); int ne_filefd_update(struct flb_ne *ctx); +#else +static int ne_filefd_init(struct flb_ne *ctx) +{ + return 0; +} + +static int ne_filefd_update(struct flb_ne *ctx) +{ + return 0; +} +#endif #endif diff --git a/plugins/in_node_exporter_metrics/ne_filesystem.c b/plugins/in_node_exporter_metrics/ne_filesystem.c index 6cc2a196034..47d13a19b14 100644 --- a/plugins/in_node_exporter_metrics/ne_filesystem.c +++ b/plugins/in_node_exporter_metrics/ne_filesystem.c @@ -19,21 +19,4 @@ #ifdef __linux__ #include "ne_filesystem_linux.c" -#else - -int ne_filesystem_init(struct flb_ne *ctx) -{ - return 0; -} - -int ne_filesystem_update(struct flb_ne *ctx) -{ - return 0; -} - -int ne_filesystem_exit(struct flb_ne *ctx) -{ - return 0; -} - -#endif \ No newline at end of file +#endif diff --git a/plugins/in_node_exporter_metrics/ne_filesystem.h b/plugins/in_node_exporter_metrics/ne_filesystem.h index 1e87b28254c..8bd2bc64876 100644 --- a/plugins/in_node_exporter_metrics/ne_filesystem.h +++ b/plugins/in_node_exporter_metrics/ne_filesystem.h @@ -22,8 +22,25 @@ #include "ne.h" +#ifdef __linux__ int ne_filesystem_init(struct flb_ne *ctx); int ne_filesystem_update(struct flb_ne *ctx); int ne_filesystem_exit(struct flb_ne *ctx); +#else +static int ne_filesystem_init(struct flb_ne *ctx) +{ + return 0; +} + +static int ne_filesystem_update(struct flb_ne *ctx) +{ + return 0; +} + +static int ne_filesystem_exit(struct flb_ne *ctx) +{ + return 0; +} +#endif #endif diff --git a/plugins/in_node_exporter_metrics/ne_loadavg.c b/plugins/in_node_exporter_metrics/ne_loadavg.c index 123ab1dc844..efef4f3efc1 100644 --- a/plugins/in_node_exporter_metrics/ne_loadavg.c +++ b/plugins/in_node_exporter_metrics/ne_loadavg.c @@ -19,4 +19,6 @@ #ifdef __linux__ #include "ne_loadavg_linux.c" +#elif __APPLE__ +#include "ne_loadavg_darwin.c" #endif diff --git a/plugins/in_node_exporter_metrics/ne_loadavg.h b/plugins/in_node_exporter_metrics/ne_loadavg.h index 95540ac377a..874f4ab5443 100644 --- a/plugins/in_node_exporter_metrics/ne_loadavg.h +++ b/plugins/in_node_exporter_metrics/ne_loadavg.h @@ -22,8 +22,25 @@ #include "ne.h" +#if defined(__linux__) || defined(__APPLE__) int ne_loadavg_init(struct flb_ne *ctx); int ne_loadavg_update(struct flb_ne *ctx); int ne_loadavg_exit(struct flb_ne *ctx); +#else +static int ne_loadavg_init(struct flb_ne *ctx) +{ + return 0; +} + +static int ne_loadavg_update(struct flb_ne *ctx) +{ + return 0; +} + +static int ne_loadavg_exit(struct flb_ne *ctx) +{ + return 0; +} +#endif #endif diff --git a/plugins/in_node_exporter_metrics/ne_loadavg_darwin.c b/plugins/in_node_exporter_metrics/ne_loadavg_darwin.c new file mode 100644 index 00000000000..8c803787683 --- /dev/null +++ b/plugins/in_node_exporter_metrics/ne_loadavg_darwin.c @@ -0,0 +1,91 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +/* Fluent Bit + * ========== + * Copyright (C) 2023 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 +#include +#include + +#include "ne.h" + +/* Setup metrics contexts */ +static int ne_loadavg_configure(struct flb_ne *ctx) +{ + struct cmt_gauge *g; + + /* loadavg 1m */ + g = cmt_gauge_create(ctx->cmt, "node", "", "load1", + "1m load average.", + 0, NULL); + ctx->lavg_1 = g; + + /* loadavg 5m */ + g = cmt_gauge_create(ctx->cmt, "node", "", "load5", + "5m load average.", + 0, NULL); + ctx->lavg_5 = g; + + /* loadavg 15m */ + g = cmt_gauge_create(ctx->cmt, "node", "", "load15", + "15m load average.", + 0, NULL); + ctx->lavg_15 = g; + + return 0; +} + +static int loadavg_update(struct flb_ne *ctx) +{ + int ret; + double loadavg[3]; + uint64_t ts; + + ts = cfl_time_now(); + + ret = getloadavg(loadavg, 3); + if (ret == -1) { + flb_plg_error(ctx->ins, "failed to retrieve loadavg"); + return -1; + } + + /* Confirm the count of the values from getloadavg */ + if (ret >= 3) { + /* 1m */ + cmt_gauge_set(ctx->lavg_1, ts, loadavg[0], 0, NULL); + + /* 5m */ + cmt_gauge_set(ctx->lavg_5, ts, loadavg[1], 0, NULL); + + /* 15m */ + cmt_gauge_set(ctx->lavg_15, ts, loadavg[2], 0, NULL); + } + + return 0; +} + +int ne_loadavg_init(struct flb_ne *ctx) +{ + ne_loadavg_configure(ctx); + return 0; +} + +int ne_loadavg_update(struct flb_ne *ctx) +{ + loadavg_update(ctx); + return 0; +} diff --git a/plugins/in_node_exporter_metrics/ne_meminfo.c b/plugins/in_node_exporter_metrics/ne_meminfo.c index 8dfeaa678b8..cf7d93dca03 100644 --- a/plugins/in_node_exporter_metrics/ne_meminfo.c +++ b/plugins/in_node_exporter_metrics/ne_meminfo.c @@ -20,4 +20,6 @@ #ifdef __linux__ #include "ne_meminfo_linux.c" +#elif __APPLE__ +#include "ne_meminfo_darwin.c" #endif diff --git a/plugins/in_node_exporter_metrics/ne_meminfo.h b/plugins/in_node_exporter_metrics/ne_meminfo.h index bd3edc1954c..a038b2c3443 100644 --- a/plugins/in_node_exporter_metrics/ne_meminfo.h +++ b/plugins/in_node_exporter_metrics/ne_meminfo.h @@ -22,8 +22,25 @@ #include "ne.h" +#if defined(__linux__) || defined(__APPLE__) int ne_meminfo_init(struct flb_ne *ctx); int ne_meminfo_update(struct flb_ne *ctx); int ne_meminfo_exit(struct flb_ne *ctx); +#else +static int ne_meminfo_init(struct flb_ne *ctx) +{ + return 0; +} + +static int ne_meminfo_update(struct flb_ne *ctx) +{ + return 0; +} + +static int ne_meminfo_exit(struct flb_ne *ctx) +{ + return 0; +} +#endif #endif diff --git a/plugins/in_node_exporter_metrics/ne_meminfo_darwin.c b/plugins/in_node_exporter_metrics/ne_meminfo_darwin.c new file mode 100644 index 00000000000..a2d18b0dd59 --- /dev/null +++ b/plugins/in_node_exporter_metrics/ne_meminfo_darwin.c @@ -0,0 +1,237 @@ +/* -*- 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 +#include + +#include + +#include "ne.h" +#include "ne_utils.h" + +#include +#include + +#include +#include +#include + +static int meminfo_configure(struct flb_ne *ctx) +{ + struct cmt_counter *c; + struct cmt_gauge *g; + + g = cmt_gauge_create(ctx->cmt, "node", "meminfo", "free_bytes", + "memory information for free in bytes", + 0, NULL); + if (!g) { + return -1; + } + ctx->darwin_free_bytes = g; + + g = cmt_gauge_create(ctx->cmt, "node", "meminfo", "active_bytes", + "memory information for active in bytes", + 0, NULL); + if (!g) { + return -1; + } + ctx->darwin_active_bytes = g; + + g = cmt_gauge_create(ctx->cmt, "node", "meminfo", "compressed_bytes", + "meminfo information for compressored pages in bytes", + 0, NULL); + if (!g) { + return -1; + } + ctx->darwin_compressed_bytes = g; + + g = cmt_gauge_create(ctx->cmt, "node", "meminfo", "inactive_bytes", + "meminfo information for inactive in bytes", + 0, NULL); + if (!g) { + return -1; + } + ctx->darwin_inactive_bytes = g; + + g = cmt_gauge_create(ctx->cmt, "node", "meminfo", "internal_bytes", + "meminfo information for internal in bytes", + 0, NULL); + if (!g) { + return -1; + } + ctx->darwin_internal_bytes = g; + + g = cmt_gauge_create(ctx->cmt, "node", "meminfo", "wired_bytes", + "meminfo information for wire in bytes", + 0, NULL); + if (!g) { + return -1; + } + ctx->darwin_wired_bytes = g; + + g = cmt_gauge_create(ctx->cmt, "node", "meminfo", "purgeable_bytes", + "meminfo information for purgeable in bytes", + 0, NULL); + if (!g) { + return -1; + } + ctx->darwin_purgeable_bytes = g; + + c = cmt_counter_create(ctx->cmt, "node", "meminfo", "pageins_bytes", + "meminfo information for pageins in bytes", + 0, NULL); + if (!c) { + return -1; + } + ctx->darwin_pageins_bytes = c; + + c = cmt_counter_create(ctx->cmt, "node", "meminfo", "pageouts_bytes", + "meminfo information for pageouts in bytes", + 0, NULL); + if (!c) { + return -1; + } + ctx->darwin_pageouts_bytes = c; + + g = cmt_gauge_create(ctx->cmt, "node", "meminfo", "swap_used_bytes", + "meminfo information for swap_used in bytes", + 0, NULL); + if (!g) { + return -1; + } + ctx->darwin_swap_used_bytes = g; + + g = cmt_gauge_create(ctx->cmt, "node", "meminfo", "swap_total_bytes", + "meminfo information for swap_total in bytes", + 0, NULL); + if (!g) { + return -1; + } + ctx->darwin_swap_total_bytes = g; + + c = cmt_counter_create(ctx->cmt, "node", "meminfo", "total_bytes", + "meminfo information for total in bytes", + 0, NULL); + if (!c) { + return -1; + } + ctx->darwin_total_bytes = c; + + return 0; +} + +static int meminfo_update(struct flb_ne *ctx, uint64_t ts) +{ + mach_port_t host_port; + mach_msg_type_number_t host_size; + vm_statistics64_data_t vm_stat; + kern_return_t err; + vm_size_t page_size; + struct xsw_usage swap; + uint64_t ps; + int64_t total; + int mib[2]; + size_t len; + + host_port = mach_host_self(); + host_size = sizeof(vm_statistics_data_t) / sizeof(integer_t); + + err = host_statistics64(host_port, HOST_VM_INFO, (host_info_t)&vm_stat, &host_size); + + if (err != KERN_SUCCESS) { + flb_plg_error(ctx->ins, "host_statistics() is failed with error = %d", err); + mach_port_deallocate(mach_task_self(), host_port); + return -1; + } + + host_page_size(host_port, &page_size); + + ps = (uint64_t)page_size; + + mib[0] = CTL_HW; + mib[1] = HW_MEMSIZE; + len = sizeof(int64_t); + sysctl(mib, 2, &total, &len, NULL, 0); + + mib[0] = CTL_VM; + mib[1] = VM_SWAPUSAGE; + len = sizeof(struct xsw_usage); + sysctl(mib, 2, &swap, &len, NULL, 0); + + cmt_gauge_set(ctx->darwin_free_bytes, ts, + ps * vm_stat.free_count, 0, NULL); + + cmt_gauge_set(ctx->darwin_compressed_bytes, ts, + ps * vm_stat.compressor_page_count, 0, NULL); + + cmt_gauge_set(ctx->darwin_active_bytes, ts, + ps * vm_stat.active_count, 0, NULL); + + cmt_gauge_set(ctx->darwin_inactive_bytes, ts, + ps * vm_stat.inactive_count, 0, NULL); + + cmt_gauge_set(ctx->darwin_internal_bytes, ts, + ps * vm_stat.internal_page_count, 0, NULL); + + cmt_gauge_set(ctx->darwin_wired_bytes, ts, + ps * vm_stat.wire_count, 0, NULL); + + cmt_gauge_set(ctx->darwin_purgeable_bytes, ts, + ps * vm_stat.purgeable_count, 0, NULL); + + cmt_counter_set(ctx->darwin_pageins_bytes, ts, + ps * vm_stat.pageins, 0, NULL); + + cmt_counter_set(ctx->darwin_pageouts_bytes, ts, + ps * vm_stat.pageouts, 0, NULL); + + cmt_gauge_set(ctx->darwin_swap_used_bytes, ts, + (double)swap.xsu_used, 0, NULL); + + cmt_gauge_set(ctx->darwin_swap_total_bytes, ts, + (double)swap.xsu_total, 0, NULL); + + cmt_counter_set(ctx->darwin_total_bytes, ts, + (double)total, 0, NULL); + + mach_port_deallocate(mach_task_self(), host_port); + + return 0; +} + +int ne_meminfo_init(struct flb_ne *ctx) +{ + meminfo_configure(ctx); + return 0; +} + +int ne_meminfo_update(struct flb_ne *ctx) +{ + uint64_t ts; + + ts = cfl_time_now(); + + meminfo_update(ctx, ts); + return 0; +} + +int ne_meminfo_exit(struct flb_ne *ctx) +{ + return 0; +} diff --git a/plugins/in_node_exporter_metrics/ne_netdev.c b/plugins/in_node_exporter_metrics/ne_netdev.c index 848ca099597..0673ffd86bd 100644 --- a/plugins/in_node_exporter_metrics/ne_netdev.c +++ b/plugins/in_node_exporter_metrics/ne_netdev.c @@ -19,4 +19,6 @@ #ifdef __linux__ #include "ne_netdev_linux.c" +#elif __APPLE__ +#include "ne_netdev_darwin.c" #endif diff --git a/plugins/in_node_exporter_metrics/ne_netdev.h b/plugins/in_node_exporter_metrics/ne_netdev.h index 8155bc3f5b9..cc964ae128a 100644 --- a/plugins/in_node_exporter_metrics/ne_netdev.h +++ b/plugins/in_node_exporter_metrics/ne_netdev.h @@ -22,8 +22,25 @@ #include "ne.h" +#if defined(__linux__) || defined(__APPLE__) int ne_netdev_init(struct flb_ne *ctx); int ne_netdev_update(struct flb_ne *ctx); int ne_netdev_exit(struct flb_ne *ctx); +#else +static int ne_netdev_init(struct flb_ne *ctx) +{ + return 0; +} + +static int ne_netdev_update(struct flb_ne *ctx) +{ + return 0; +} + +static int ne_netdev_exit(struct flb_ne *ctx) +{ + return 0; +} +#endif #endif diff --git a/plugins/in_node_exporter_metrics/ne_netdev_darwin.c b/plugins/in_node_exporter_metrics/ne_netdev_darwin.c new file mode 100644 index 00000000000..4f3aaef36f8 --- /dev/null +++ b/plugins/in_node_exporter_metrics/ne_netdev_darwin.c @@ -0,0 +1,221 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +/* Fluent Bit + * ========== + * Copyright (C) 2023 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 +#include +#include + +#include "ne.h" +#include "ne_utils.h" + +#include +#include +#include + +static int netdev_configure(struct flb_ne *ctx) +{ + struct cmt_gauge *g; + + g = cmt_gauge_create(ctx->cmt, "node", "network", "receive_packets", + "network information for receive_packets", + 1, (char *[]){ "device" }); + if (!g) { + return -1; + } + ctx->darwin_receive_packets = g; + + g = cmt_gauge_create(ctx->cmt, "node", "network", "transmit_packets", + "network information for transmit_packets", + 1, (char *[]){ "device" }); + if (!g) { + return -1; + } + ctx->darwin_transmit_packets = g; + + g = cmt_gauge_create(ctx->cmt, "node", "network", "receive_bytes", + "network information for receive_bytes", + 1, (char *[]){ "device" }); + if (!g) { + return -1; + } + ctx->darwin_receive_bytes = g; + + g = cmt_gauge_create(ctx->cmt, "node", "network", "transmit_bytes", + "network information for transmit_bytes", + 1, (char *[]){ "device" }); + if (!g) { + return -1; + } + ctx->darwin_transmit_bytes = g; + + g = cmt_gauge_create(ctx->cmt, "node", "network", "receive_errors", + "network information for receive_errors", + 1, (char *[]){ "device" }); + if (!g) { + return -1; + } + ctx->darwin_receive_errors = g; + + g = cmt_gauge_create(ctx->cmt, "node", "network", "transmit_errors", + "network information for transmit_errors", + 1, (char *[]){ "device" }); + if (!g) { + return -1; + } + ctx->darwin_transmit_errors = g; + + g = cmt_gauge_create(ctx->cmt, "node", "network", "receive_dropped", + "network information for receive_dropped", + 1, (char *[]){ "device" }); + if (!g) { + return -1; + } + ctx->darwin_receive_dropped = g; + + g = cmt_gauge_create(ctx->cmt, "node", "network", "receive_multicast", + "network information for receive_multicast", + 1, (char *[]){ "device" }); + if (!g) { + return -1; + } + ctx->darwin_receive_multicast = g; + + g = cmt_gauge_create(ctx->cmt, "node", "network", "transmit_multicast", + "network information for transmit_multicast", + 1, (char *[]){ "device" }); + if (!g) { + return -1; + } + ctx->darwin_transmit_multicast = g; + + g = cmt_gauge_create(ctx->cmt, "node", "network", "collisions", + "network information for collisions", + 1, (char *[]){ "device" }); + if (!g) { + return -1; + } + ctx->darwin_collisions = g; + + g = cmt_gauge_create(ctx->cmt, "node", "network", "noproto", + "network information for noproto", + 1, (char *[]){ "device" }); + if (!g) { + return -1; + } + ctx->darwin_noproto = g; + + return 0; +} + +static int netdev_update(struct flb_ne *ctx) +{ + int ret; + int i; + int if_count; + size_t clen = sizeof(if_count); + int cmib[] = { CTL_NET, PF_LINK, NETLINK_GENERIC, IFMIB_SYSTEM, IFMIB_IFCOUNT }; + int mib[6]; + struct ifmibdata ifmd; + size_t ifmd_len = sizeof(ifmd); + char ifname[IF_NAMESIZE]; + uint64_t ts; + + ts = cfl_time_now(); + + ret = sysctl(cmib, 5, &if_count, &clen, NULL, 0); + if (ret < 0) { + flb_plg_error(ctx->ins, "failed to get count of interface(s) for network"); + return -1; + } + + for (i = 1; i <= if_count; i++) { + mib[0] = CTL_NET; + mib[1] = PF_LINK; + mib[2] = NETLINK_GENERIC; + mib[3] = IFMIB_IFDATA; + mib[4] = i; + mib[5] = IFDATA_GENERAL; + + /* Receive network metrics with struct ifmibdata. + * ref: https://developer.apple.com/documentation/kernel/ifmibdata/3753765-ifmd_data?changes=_5 + */ + ret = sysctl(mib, 6, &ifmd, &ifmd_len, NULL, 0); + if (ret < 0) { + continue; + } + + if (!if_indextoname(i, ifname)) { + flb_plg_debug(ctx->ins, "failed to if_index_toname for %d", i); + snprintf(ifname, IF_NAMESIZE, "(unknown %i)", i); + } + + cmt_gauge_set(ctx->darwin_receive_packets, ts, + (double)ifmd.ifmd_data.ifi_ipackets, 1, (char *[]) { ifname }); + + cmt_gauge_set(ctx->darwin_transmit_packets, ts, + (double)ifmd.ifmd_data.ifi_opackets, 1, (char *[]) { ifname }); + + cmt_gauge_set(ctx->darwin_receive_bytes, ts, + (double)ifmd.ifmd_data.ifi_ibytes, 1, (char *[]) { ifname }); + + cmt_gauge_set(ctx->darwin_transmit_bytes, ts, + (double)ifmd.ifmd_data.ifi_obytes, 1, (char *[]) { ifname }); + + cmt_gauge_set(ctx->darwin_receive_errors, ts, + (double)ifmd.ifmd_data.ifi_ierrors, 1, (char *[]) { ifname }); + + cmt_gauge_set(ctx->darwin_transmit_errors, ts, + (double)ifmd.ifmd_data.ifi_oerrors, 1, (char *[]) { ifname }); + + cmt_gauge_set(ctx->darwin_receive_dropped, ts, + (double)ifmd.ifmd_data.ifi_iqdrops, 1, (char *[]) { ifname }); + + cmt_gauge_set(ctx->darwin_receive_multicast, ts, + (double)ifmd.ifmd_data.ifi_imcasts, 1, (char *[]) { ifname }); + + cmt_gauge_set(ctx->darwin_transmit_multicast, ts, + (double)ifmd.ifmd_data.ifi_imcasts, 1, (char *[]) { ifname }); + + cmt_gauge_set(ctx->darwin_collisions, ts, + (double)ifmd.ifmd_data.ifi_collisions, 1, (char *[]) { ifname }); + + cmt_gauge_set(ctx->darwin_noproto, ts, + (double)ifmd.ifmd_data.ifi_noproto, 1, (char *[]) { ifname }); + + } + + return 0; +} + +int ne_netdev_init(struct flb_ne *ctx) +{ + netdev_configure(ctx); + return 0; +} + +int ne_netdev_update(struct flb_ne *ctx) +{ + netdev_update(ctx); + return 0; +} + +int ne_netdev_exit(struct flb_ne *ctx) +{ + return 0; +} diff --git a/plugins/in_node_exporter_metrics/ne_textfile.h b/plugins/in_node_exporter_metrics/ne_textfile.h index 7f67d817f3e..81ed25b2e41 100644 --- a/plugins/in_node_exporter_metrics/ne_textfile.h +++ b/plugins/in_node_exporter_metrics/ne_textfile.h @@ -22,7 +22,19 @@ #include "ne.h" +#ifdef __linux__ int ne_textfile_init(struct flb_ne *ctx); int ne_textfile_update(struct flb_ne *ctx); +#else +static int ne_textfile_init(struct flb_ne *ctx) +{ + return 0; +} + +static int ne_textfile_update(struct flb_ne *ctx) +{ + return 0; +} +#endif #endif diff --git a/plugins/in_node_exporter_metrics/ne_uname.c b/plugins/in_node_exporter_metrics/ne_uname.c index 7ab7b1613c8..e32830842d8 100644 --- a/plugins/in_node_exporter_metrics/ne_uname.c +++ b/plugins/in_node_exporter_metrics/ne_uname.c @@ -19,4 +19,6 @@ #ifdef __linux__ #include "ne_uname_linux.c" +#elif __APPLE__ +#include "ne_uname_darwin.c" #endif diff --git a/plugins/in_node_exporter_metrics/ne_uname.h b/plugins/in_node_exporter_metrics/ne_uname.h index dc94bc42b04..cdfb8ad4318 100644 --- a/plugins/in_node_exporter_metrics/ne_uname.h +++ b/plugins/in_node_exporter_metrics/ne_uname.h @@ -22,7 +22,19 @@ #include "ne.h" +#if defined(__linux__) || defined(__APPLE__) int ne_uname_init(struct flb_ne *ctx); int ne_uname_update(struct flb_ne *ctx); +#else +static int ne_uname_init(struct flb_ne *ctx) +{ + return 0; +} + +static int ne_uname_update(struct flb_ne *ctx) +{ + return 0; +} +#endif #endif diff --git a/plugins/in_node_exporter_metrics/ne_uname_darwin.c b/plugins/in_node_exporter_metrics/ne_uname_darwin.c new file mode 100644 index 00000000000..6d06bd420d3 --- /dev/null +++ b/plugins/in_node_exporter_metrics/ne_uname_darwin.c @@ -0,0 +1,100 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +/* Fluent Bit + * ========== + * Copyright (C) 2023 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. + */ + +#define _GNU_SOURCE + +#include +#include + +#include "ne.h" +#include "ne_utils.h" + +#include +#include + +static int uname_configure(struct flb_ne *ctx) +{ + struct cmt_gauge *g; + + g = cmt_gauge_create(ctx->cmt, "node", "uname", "info", + "Labeled system information as provided by the uname system call.", + 6, (char *[]) + { + "sysname", + "release", + "version", + "machine", + "nodename", + "domainname" + }); + if (!g) { + return -1; + } + ctx->uname = g; + return 0; +} + +static int uname_update(struct flb_ne *ctx) +{ + int ret; + uint64_t ts; + struct utsname u = {0}; + flb_sds_t tmp; + flb_sds_t nodename, domainname; + + uname(&u); + + tmp = strtok(u.nodename, "."); + nodename = strdup(tmp); + + /* Obtain domainname from string operation of u.nodename */ + domainname = "(none)"; + while (tmp != NULL) { + tmp = strtok(NULL, "."); + if (tmp != NULL) { + domainname = tmp; + } + } + + ts = cfl_time_now(); + ret = cmt_gauge_set(ctx->uname, ts, 1, 6, + (char *[]) { + u.sysname, + u.release, + u.version, + u.machine, + nodename, + domainname}); + + flb_free(nodename); + + return ret; +} + +int ne_uname_init(struct flb_ne *ctx) +{ + uname_configure(ctx); + return 0; +} + +int ne_uname_update(struct flb_ne *ctx) +{ + uname_update(ctx); + return 0; +}