Loading README.md +10 −7 Original line number Diff line number Diff line Loading @@ -392,25 +392,28 @@ the `default_zmq` dependency profile. In addition, GekkoFS must be compiled with client metrics enabled (disabled by default) via the CMake argument `-DGKFS_ENABLE_CLIENT_METRICS=ON`. Client metrics are individually enabled per GekkoFS client process via the following environment variables: Client metrics/messages are enabled with common `GKFS_` environment variables. Exporting the same variables to both clients and daemons enables client-side message emission and, when requested, the daemon-side relay: - `LIBGKFS_ENABLE_METRICS=ON` enables capturing client-side metrics. - `GKFS_ENABLE_METRICS=ON` enables capturing client-side metrics/messages. Daemons also honor this same variable when deciding whether to start the optional relay, so no daemon-specific enable variable is needed. - `LIBGKFS_METRICS_FLUSH_INTERVAL=10` sets the flush interval to 10 seconds (defaults to 5). All outstanding client metrics are flushed when the process ends. - `LIBGKFS_METRICS_PATH=<path>` sets the path to flush client-metrics (defaults to `/tmp/gkfs_client_metrics`). - `LIBGKFS_METRICS_IP_PORT=127.0.0.1:5555` enables flushing to a set ZeroMQ server. This option disables flushing to a - `GKFS_METRICS_IP_PORT=127.0.0.1:5555` enables flushing to a set ZeroMQ server. This option disables flushing to a file. - `LIBGKFS_METRICS_IO_TYPE=w` restricts which of the two `ClientMetrics` instances (write, read) get created at all. Defaults to `wr` (both, unchanged behavior). A write-only workload that never reads back what it wrote can set this to `w` to skip the read-side thread and socket entirely, since a receiver that only consumes `io_type=="w"` messages (e.g. FTIO's default prediction mode) would otherwise unpack and discard every read message anyway. - `LIBGKFS_METRICS_AGGREGATOR=on` routes a client's metrics through the local per-node daemon instead of dialing the - `GKFS_METRICS_AGGREGATOR=on` routes a client's metrics through the local per-node daemon instead of dialing the ZeroMQ sink directly. At high rank density, every rank normally opens its own connection to one remote sink node; this collapses that fan-in to one connection per node, and the daemon batches whatever it receives within a short window into a single message before forwarding -- so the sink also receives O(nodes) messages instead of O(ranks). The daemon needs the same `LIBGKFS_METRICS_AGGREGATOR` and `LIBGKFS_METRICS_IP_PORT` set in its own environment to actually start the aggregator thread. The receiving end needs no configuration: a batched message O(ranks). The daemon needs the same `GKFS_ENABLE_METRICS`, `GKFS_METRICS_AGGREGATOR`, and `GKFS_METRICS_IP_PORT` set in its own environment to actually start the aggregator thread. The receiving end needs no configuration: a batched message is a single top-level msgpack array, a direct message is a flat sequence of scalar fields, and the two are told apart by inspecting the first unpacked object's type. Loading @@ -420,7 +423,7 @@ option `-DGKFS_BUILD_TOOLS=ON`: - Starting the ZeroMQ server: `gkfs_clientmetrics2json tcp://127.0.0.1:5555` - `gkfs_clientmetrics2json <path>` can also be used to unpack the Messagepack export from a file. Examplarily output with the ZeroMQ sink enabled when running: `LD_PRELOAD=libgkfs_intercept.so LIBGKFS_ENABLE_METRICS=ON LIBGKFS_METRICS_IP_PORT=127.0.0.1:5555 gkfs cp testfile /tmp/gkfs_mountdir/testfile`: `LD_PRELOAD=libgkfs_intercept.so GKFS_ENABLE_METRICS=ON GKFS_METRICS_IP_PORT=127.0.0.1:5555 gkfs cp testfile /tmp/gkfs_mountdir/testfile`: ```bash ~ $ gkfs_clientmetrics2json tcp://127.0.0.1:5555 Loading include/client/env.hpp +3 −5 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ #define GKFS_CLIENT_ENV #include <config.hpp> #include <common/env.hpp> #define ADD_PREFIX(str) CLIENT_ENV_PREFIX str Loading @@ -61,11 +62,9 @@ static constexpr auto CWD = ADD_PREFIX("CWD"); static constexpr auto HOSTS_FILE = ADD_PREFIX("HOSTS_FILE"); static constexpr auto FORWARDING_MAP_FILE = ADD_PREFIX("FORWARDING_MAP_FILE"); #ifdef GKFS_ENABLE_CLIENT_METRICS static constexpr auto ENABLE_METRICS = ADD_PREFIX("ENABLE_METRICS"); static constexpr auto METRICS_FLUSH_INTERVAL = ADD_PREFIX("METRICS_FLUSH_INTERVAL"); static constexpr auto METRICS_PATH = ADD_PREFIX("METRICS_PATH"); static constexpr auto METRICS_IP_PORT = ADD_PREFIX("METRICS_IP_PORT"); // "w", "r", or "wr"/"rw" (default) -- which ClientMetrics instances to // create at all. A consumer that only ever reads io_type=="w" messages // (e.g. FTIO's default prediction mode) shouldn't pay for a read-metrics Loading @@ -73,9 +72,8 @@ static constexpr auto METRICS_IP_PORT = ADD_PREFIX("METRICS_IP_PORT"); static constexpr auto METRICS_IO_TYPE = ADD_PREFIX("METRICS_IO_TYPE"); // Opt-in, test-only: when set, connect to the local daemon's relay socket // instead of dialing FTIO directly -- collapses per-rank connections down // to one per node. The daemon must have the same var set to actually start // the relay (see daemon/env.hpp). static constexpr auto METRICS_AGGREGATOR = ADD_PREFIX("METRICS_AGGREGATOR"); // to one per node. The daemon must have GKFS_ENABLE_METRICS and the same // routing vars set to actually start the relay (see daemon/env.hpp). #endif static constexpr auto PROTECT_FD = ADD_PREFIX("PROTECT_FD"); Loading include/common/env.hpp 0 → 100644 +59 −0 Original line number Diff line number Diff line /* Copyright 2018-2025, Barcelona Supercomputing Center (BSC), Spain Copyright 2015-2025, Johannes Gutenberg Universitaet Mainz, Germany This software was partially supported by the EC H2020 funded project NEXTGenIO (Project ID: 671951, www.nextgenio.eu). This software was partially supported by the ADA-FS project under the SPPEXA project funded by the DFG. This software was partially supported by the the European Union’s Horizon 2020 JTI-EuroHPC research and innovation programme, by the project ADMIRE (Project ID: 956748, admire-eurohpc.eu) This project was partially promoted by the Ministry for Digital Transformation and the Civil Service, within the framework of the Recovery, Transformation and Resilience Plan - Funded by the European Union -NextGenerationEU. This file is part of GekkoFS. GekkoFS is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. GekkoFS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GekkoFS. If not, see <https://www.gnu.org/licenses/>. SPDX-License-Identifier: GPL-3.0-or-later */ #ifndef GKFS_COMMON_ENV_HPP #define GKFS_COMMON_ENV_HPP #include <config.hpp> #define ADD_PREFIX(str) COMMON_ENV_PREFIX str /* Environment variables shared by GekkoFS clients and daemons */ namespace gkfs::env { #ifdef GKFS_ENABLE_CLIENT_METRICS static constexpr auto ENABLE_METRICS = ADD_PREFIX("ENABLE_METRICS"); static constexpr auto METRICS_IP_PORT = ADD_PREFIX("METRICS_IP_PORT"); static constexpr auto METRICS_AGGREGATOR = ADD_PREFIX("METRICS_AGGREGATOR"); #endif } // namespace gkfs::env #undef ADD_PREFIX #endif // GKFS_COMMON_ENV_HPP No newline at end of file include/daemon/env.hpp +1 −17 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ #define GKFS_DAEMON_ENV #include <config.hpp> #include <common/env.hpp> #define ADD_PREFIX(str) COMMON_ENV_PREFIX str Loading @@ -66,23 +67,6 @@ static constexpr auto DAEMON_USE_INLINE_DATA = ADD_PREFIX("DAEMON_USE_INLINE_DATA"); static constexpr auto KEEP_HOSTS_FILE = ADD_PREFIX("KEEP_HOSTS_FILE"); #ifdef GKFS_ENABLE_CLIENT_METRICS // these two intentionally use CLIENT_ENV_PREFIX ("LIBGKFS_"), not // this file's own ADD_PREFIX/COMMON_ENV_PREFIX ("GKFS_") -- they name the // exact same env vars the client already reads (client/env.hpp), so one // --export=ALL,LIBGKFS_METRICS_IP_PORT=...,LIBGKFS_METRICS_AGGREGATOR=... // reaches both sides without the caller needing to set two differently // -prefixed vars for one concept. static constexpr auto METRICS_IP_PORT = CLIENT_ENV_PREFIX "METRICS_IP_PORT"; // Opt-in: when set, the daemon relays local ranks' metrics messages to FTIO // over one shared connection instead of each rank dialing FTIO directly. // See metrics_daemon_relay.md discussion -- test-only for now, not a // default. Client side must set the same var to redirect its own socket at // the local daemon instead of FTIO's real address. static constexpr auto METRICS_AGGREGATOR = CLIENT_ENV_PREFIX "METRICS_AGGREGATOR"; #endif } // namespace gkfs::env #undef ADD_PREFIX Loading src/client/preload_context.cpp +3 −2 Original line number Diff line number Diff line Loading @@ -195,14 +195,15 @@ PreloadContext::init_metrics() { // directly, so many ranks converge on one node-local connection // instead of each dialing FTIO's remote node individually. The // daemon (daemon.cpp: start_metrics_relay()) must have the same // var set to actually bind that socket. // enable/routing vars set to actually bind that socket. bool via_relay = gkfs::env::var_is_set(gkfs::env::METRICS_AGGREGATOR); // error level is deliberate diagnostic-only visibility // for this test-only feature -- the JIT harness hardcodes // LIBGKFS_LOG=errors, so info-level never reaches the log file. if(via_relay) LOG(ERROR, "Client metrics: via_relay=true, connecting to " LOG(ERROR, "Client metrics: via_relay=true, connecting to " "local daemon relay instead of {}", metrics_ip); if(want_write) { Loading Loading
README.md +10 −7 Original line number Diff line number Diff line Loading @@ -392,25 +392,28 @@ the `default_zmq` dependency profile. In addition, GekkoFS must be compiled with client metrics enabled (disabled by default) via the CMake argument `-DGKFS_ENABLE_CLIENT_METRICS=ON`. Client metrics are individually enabled per GekkoFS client process via the following environment variables: Client metrics/messages are enabled with common `GKFS_` environment variables. Exporting the same variables to both clients and daemons enables client-side message emission and, when requested, the daemon-side relay: - `LIBGKFS_ENABLE_METRICS=ON` enables capturing client-side metrics. - `GKFS_ENABLE_METRICS=ON` enables capturing client-side metrics/messages. Daemons also honor this same variable when deciding whether to start the optional relay, so no daemon-specific enable variable is needed. - `LIBGKFS_METRICS_FLUSH_INTERVAL=10` sets the flush interval to 10 seconds (defaults to 5). All outstanding client metrics are flushed when the process ends. - `LIBGKFS_METRICS_PATH=<path>` sets the path to flush client-metrics (defaults to `/tmp/gkfs_client_metrics`). - `LIBGKFS_METRICS_IP_PORT=127.0.0.1:5555` enables flushing to a set ZeroMQ server. This option disables flushing to a - `GKFS_METRICS_IP_PORT=127.0.0.1:5555` enables flushing to a set ZeroMQ server. This option disables flushing to a file. - `LIBGKFS_METRICS_IO_TYPE=w` restricts which of the two `ClientMetrics` instances (write, read) get created at all. Defaults to `wr` (both, unchanged behavior). A write-only workload that never reads back what it wrote can set this to `w` to skip the read-side thread and socket entirely, since a receiver that only consumes `io_type=="w"` messages (e.g. FTIO's default prediction mode) would otherwise unpack and discard every read message anyway. - `LIBGKFS_METRICS_AGGREGATOR=on` routes a client's metrics through the local per-node daemon instead of dialing the - `GKFS_METRICS_AGGREGATOR=on` routes a client's metrics through the local per-node daemon instead of dialing the ZeroMQ sink directly. At high rank density, every rank normally opens its own connection to one remote sink node; this collapses that fan-in to one connection per node, and the daemon batches whatever it receives within a short window into a single message before forwarding -- so the sink also receives O(nodes) messages instead of O(ranks). The daemon needs the same `LIBGKFS_METRICS_AGGREGATOR` and `LIBGKFS_METRICS_IP_PORT` set in its own environment to actually start the aggregator thread. The receiving end needs no configuration: a batched message O(ranks). The daemon needs the same `GKFS_ENABLE_METRICS`, `GKFS_METRICS_AGGREGATOR`, and `GKFS_METRICS_IP_PORT` set in its own environment to actually start the aggregator thread. The receiving end needs no configuration: a batched message is a single top-level msgpack array, a direct message is a flat sequence of scalar fields, and the two are told apart by inspecting the first unpacked object's type. Loading @@ -420,7 +423,7 @@ option `-DGKFS_BUILD_TOOLS=ON`: - Starting the ZeroMQ server: `gkfs_clientmetrics2json tcp://127.0.0.1:5555` - `gkfs_clientmetrics2json <path>` can also be used to unpack the Messagepack export from a file. Examplarily output with the ZeroMQ sink enabled when running: `LD_PRELOAD=libgkfs_intercept.so LIBGKFS_ENABLE_METRICS=ON LIBGKFS_METRICS_IP_PORT=127.0.0.1:5555 gkfs cp testfile /tmp/gkfs_mountdir/testfile`: `LD_PRELOAD=libgkfs_intercept.so GKFS_ENABLE_METRICS=ON GKFS_METRICS_IP_PORT=127.0.0.1:5555 gkfs cp testfile /tmp/gkfs_mountdir/testfile`: ```bash ~ $ gkfs_clientmetrics2json tcp://127.0.0.1:5555 Loading
include/client/env.hpp +3 −5 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ #define GKFS_CLIENT_ENV #include <config.hpp> #include <common/env.hpp> #define ADD_PREFIX(str) CLIENT_ENV_PREFIX str Loading @@ -61,11 +62,9 @@ static constexpr auto CWD = ADD_PREFIX("CWD"); static constexpr auto HOSTS_FILE = ADD_PREFIX("HOSTS_FILE"); static constexpr auto FORWARDING_MAP_FILE = ADD_PREFIX("FORWARDING_MAP_FILE"); #ifdef GKFS_ENABLE_CLIENT_METRICS static constexpr auto ENABLE_METRICS = ADD_PREFIX("ENABLE_METRICS"); static constexpr auto METRICS_FLUSH_INTERVAL = ADD_PREFIX("METRICS_FLUSH_INTERVAL"); static constexpr auto METRICS_PATH = ADD_PREFIX("METRICS_PATH"); static constexpr auto METRICS_IP_PORT = ADD_PREFIX("METRICS_IP_PORT"); // "w", "r", or "wr"/"rw" (default) -- which ClientMetrics instances to // create at all. A consumer that only ever reads io_type=="w" messages // (e.g. FTIO's default prediction mode) shouldn't pay for a read-metrics Loading @@ -73,9 +72,8 @@ static constexpr auto METRICS_IP_PORT = ADD_PREFIX("METRICS_IP_PORT"); static constexpr auto METRICS_IO_TYPE = ADD_PREFIX("METRICS_IO_TYPE"); // Opt-in, test-only: when set, connect to the local daemon's relay socket // instead of dialing FTIO directly -- collapses per-rank connections down // to one per node. The daemon must have the same var set to actually start // the relay (see daemon/env.hpp). static constexpr auto METRICS_AGGREGATOR = ADD_PREFIX("METRICS_AGGREGATOR"); // to one per node. The daemon must have GKFS_ENABLE_METRICS and the same // routing vars set to actually start the relay (see daemon/env.hpp). #endif static constexpr auto PROTECT_FD = ADD_PREFIX("PROTECT_FD"); Loading
include/common/env.hpp 0 → 100644 +59 −0 Original line number Diff line number Diff line /* Copyright 2018-2025, Barcelona Supercomputing Center (BSC), Spain Copyright 2015-2025, Johannes Gutenberg Universitaet Mainz, Germany This software was partially supported by the EC H2020 funded project NEXTGenIO (Project ID: 671951, www.nextgenio.eu). This software was partially supported by the ADA-FS project under the SPPEXA project funded by the DFG. This software was partially supported by the the European Union’s Horizon 2020 JTI-EuroHPC research and innovation programme, by the project ADMIRE (Project ID: 956748, admire-eurohpc.eu) This project was partially promoted by the Ministry for Digital Transformation and the Civil Service, within the framework of the Recovery, Transformation and Resilience Plan - Funded by the European Union -NextGenerationEU. This file is part of GekkoFS. GekkoFS is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. GekkoFS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GekkoFS. If not, see <https://www.gnu.org/licenses/>. SPDX-License-Identifier: GPL-3.0-or-later */ #ifndef GKFS_COMMON_ENV_HPP #define GKFS_COMMON_ENV_HPP #include <config.hpp> #define ADD_PREFIX(str) COMMON_ENV_PREFIX str /* Environment variables shared by GekkoFS clients and daemons */ namespace gkfs::env { #ifdef GKFS_ENABLE_CLIENT_METRICS static constexpr auto ENABLE_METRICS = ADD_PREFIX("ENABLE_METRICS"); static constexpr auto METRICS_IP_PORT = ADD_PREFIX("METRICS_IP_PORT"); static constexpr auto METRICS_AGGREGATOR = ADD_PREFIX("METRICS_AGGREGATOR"); #endif } // namespace gkfs::env #undef ADD_PREFIX #endif // GKFS_COMMON_ENV_HPP No newline at end of file
include/daemon/env.hpp +1 −17 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ #define GKFS_DAEMON_ENV #include <config.hpp> #include <common/env.hpp> #define ADD_PREFIX(str) COMMON_ENV_PREFIX str Loading @@ -66,23 +67,6 @@ static constexpr auto DAEMON_USE_INLINE_DATA = ADD_PREFIX("DAEMON_USE_INLINE_DATA"); static constexpr auto KEEP_HOSTS_FILE = ADD_PREFIX("KEEP_HOSTS_FILE"); #ifdef GKFS_ENABLE_CLIENT_METRICS // these two intentionally use CLIENT_ENV_PREFIX ("LIBGKFS_"), not // this file's own ADD_PREFIX/COMMON_ENV_PREFIX ("GKFS_") -- they name the // exact same env vars the client already reads (client/env.hpp), so one // --export=ALL,LIBGKFS_METRICS_IP_PORT=...,LIBGKFS_METRICS_AGGREGATOR=... // reaches both sides without the caller needing to set two differently // -prefixed vars for one concept. static constexpr auto METRICS_IP_PORT = CLIENT_ENV_PREFIX "METRICS_IP_PORT"; // Opt-in: when set, the daemon relays local ranks' metrics messages to FTIO // over one shared connection instead of each rank dialing FTIO directly. // See metrics_daemon_relay.md discussion -- test-only for now, not a // default. Client side must set the same var to redirect its own socket at // the local daemon instead of FTIO's real address. static constexpr auto METRICS_AGGREGATOR = CLIENT_ENV_PREFIX "METRICS_AGGREGATOR"; #endif } // namespace gkfs::env #undef ADD_PREFIX Loading
src/client/preload_context.cpp +3 −2 Original line number Diff line number Diff line Loading @@ -195,14 +195,15 @@ PreloadContext::init_metrics() { // directly, so many ranks converge on one node-local connection // instead of each dialing FTIO's remote node individually. The // daemon (daemon.cpp: start_metrics_relay()) must have the same // var set to actually bind that socket. // enable/routing vars set to actually bind that socket. bool via_relay = gkfs::env::var_is_set(gkfs::env::METRICS_AGGREGATOR); // error level is deliberate diagnostic-only visibility // for this test-only feature -- the JIT harness hardcodes // LIBGKFS_LOG=errors, so info-level never reaches the log file. if(via_relay) LOG(ERROR, "Client metrics: via_relay=true, connecting to " LOG(ERROR, "Client metrics: via_relay=true, connecting to " "local daemon relay instead of {}", metrics_ip); if(want_write) { Loading