Resolve "Client logging: Add per process log option"

Closes #278 (closed)

Merge request reports

Loading
+2 −1
Changes for docs/sphinx/users/running.md: 2 added lines, 1 removed line.
Original line number Diff line number Diff line
@@ -180,7 +180,8 @@ usage: gkfs [-h/--help] [-r/--rootdir <path>] [-m/--mountdir <path>] [-a/--args
The following environment variables can be used to enable logging in the client library: `LIBGKFS_LOG=<module>`
and `LIBGKFS_LOG_OUTPUT=<path/to/file>` to configure the output module and set the path to the log file of the client
library. If not path is specified in `LIBGKFS_LOG_OUTPUT`, the client library will send log messages
to `/tmp/gkfs_client.log`.
to `/tmp/gkfs_client.log`. Use `LIBGKFS_LOG_PER_PROCESS=ON` to write separate logs per client process.
When enabled, the path specified with `LIBGKFS_LOG_OUTPUT=<path/to/dir>` is used as a directory.

The following modules are available:

+1 −0
Changes for include/client/env.hpp: 1 added line, 0 removed lines.
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@ static constexpr auto LOG_SYSCALL_FILTER = ADD_PREFIX("LOG_SYSCALL_FILTER");
#endif

static constexpr auto LOG_OUTPUT = ADD_PREFIX("LOG_OUTPUT");
static constexpr auto LOG_PER_PROCESS = ADD_PREFIX("LOG_PER_PROCESS");
static constexpr auto LOG_OUTPUT_TRUNC = ADD_PREFIX("LOG_OUTPUT_TRUNC");
static constexpr auto CWD = ADD_PREFIX("CWD");
static constexpr auto HOSTS_FILE = ADD_PREFIX("HOSTS_FILE");
+5 −3
Changes for include/client/logging.hpp: 5 added lines, 3 removed lines.
Original line number Diff line number Diff line
@@ -273,7 +273,8 @@ protected:

struct logger {

    logger(const std::string& opts, const std::string& path, bool trunc
    logger(const std::string& opts, const std::string& path,
           bool log_per_process, bool trunc
#ifdef GKFS_DEBUG_BUILD
           ,
           const std::string& filter, int verbosity
@@ -293,7 +294,7 @@ struct logger {

        static_buffer buffer;
        detail::format_timestamp_to(buffer, timezone_);
        fmt::format_to(buffer, "[{}] [{}] ", ::syscall_no_intercept(SYS_gettid),
        fmt::format_to(buffer, "[{}] [{}] ", log_process_id_,
                       lookup_level_name(level));

        if(!!(level & log::debug)) {
@@ -336,7 +337,7 @@ struct logger {

        static_buffer prefix;
        detail::format_timestamp_to(prefix);
        fmt::format_to(prefix, "[{}] [{}] ", ::syscall_no_intercept(SYS_gettid),
        fmt::format_to(prefix, "[{}] [{}] ", log_process_id_,
                       lookup_level_name(level));

        char buffer[max_buffer_size];
@@ -402,6 +403,7 @@ struct logger {
    }

    int log_fd_;
    int log_process_id_;
    log_level log_mask_;

#ifdef GKFS_DEBUG_BUILD
+16 −2
Changes for src/client/logging.cpp: 16 added lines, 2 removed lines.
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@
#include <client/env.hpp>
#include <client/make_array.hpp>
#include <regex>
#include <filesystem>

extern "C" {
#include <date/tz.h>
@@ -43,6 +44,8 @@ extern "C" {

#endif

namespace fs = std::filesystem;

namespace {
enum class split_str_mode {
    is_any_of,
@@ -280,7 +283,8 @@ process_log_filter(const std::string& log_filter) {

#endif // GKFS_DEBUG_BUILD

logger::logger(const std::string& opts, const std::string& path, bool trunc
logger::logger(const std::string& opts, const std::string& path,
               bool log_per_process, bool trunc
#ifdef GKFS_DEBUG_BUILD
               ,
               const std::string& filter, int verbosity
@@ -290,6 +294,7 @@ logger::logger(const std::string& opts, const std::string& path, bool trunc

    /* use stderr by default */
    log_fd_ = 2;
    log_process_id_ = ::syscall_no_intercept(SYS_gettid);
    log_mask_ = process_log_options(opts);

#ifdef GKFS_DEBUG_BUILD
@@ -304,11 +309,20 @@ logger::logger(const std::string& opts, const std::string& path, bool trunc
            flags &= ~O_TRUNC;
        }

        std::string file_path = path;
        if(log_per_process) {
            if(fs::is_regular_file(file_path) && fs::exists(file_path)) {
                fs::remove(file_path);
            }
            fs::create_directories(path);
            file_path = fmt::format("{}/{}", path, log_process_id_);
        }

        // we use ::open() here rather than ::syscall_no_intercept(SYS_open)
        // because we want the call to be intercepted by our hooks, which
        // allows us to categorize the resulting fd as 'internal' and
        // relocate it to our private range
        int fd = ::open(path.c_str(), flags, 0600);
        int fd = ::open(file_path.c_str(), flags, 0600);

        if(fd == -1) {
            log(gkfs::log::error, __func__, __LINE__,
+6 −1
Changes for src/client/preload_context.cpp: 6 added lines, 1 removed line.
Original line number Diff line number Diff line
@@ -76,6 +76,10 @@ PreloadContext::init_logging() {
    const std::string log_output = gkfs::env::get_var(
            gkfs::env::LOG_OUTPUT, gkfs::config::log::client_log_path);

    const bool log_per_process =
            gkfs::env::get_var(gkfs::env::LOG_PER_PROCESS).empty() ? false
                                                                   : true;

#ifdef GKFS_DEBUG_BUILD
    // atoi returns 0 if no int conversion can be performed, which works
    // for us since if the user provides a non-numeric value we can just treat
@@ -92,7 +96,8 @@ PreloadContext::init_logging() {

    const bool log_trunc = (!trunc_val.empty() && trunc_val[0] != '0');

    gkfs::log::create_global_logger(log_opts, log_output, log_trunc
    gkfs::log::create_global_logger(log_opts, log_output, log_per_process,
                                    log_trunc
#ifdef GKFS_DEBUG_BUILD
                                    ,
                                    log_filter, log_verbosity
Loading
Loading