Verified Commit 1aedb01c authored by Alberto Miranda's avatar Alberto Miranda ♨️
Browse files

Logger module can now be used in native C code

parent c44468fb
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -24,6 +24,6 @@

add_library(_logger INTERFACE)

target_sources(_logger INTERFACE logger.hpp)
target_sources(_logger INTERFACE logger.h logger.hpp macros.h logger.cpp)

target_link_libraries(_logger INTERFACE spdlog::spdlog fmt::fmt)
+71 −0
Original line number Diff line number Diff line
/******************************************************************************
 * Copyright 2021-2023, Barcelona Supercomputing Center (BSC), Spain
 *
 * This software was partially supported by the EuroHPC-funded project ADMIRE
 *   (Project ID: 956748, https://www.admire-eurohpc.eu).
 *
 * This file is part of scord.
 *
 * scord 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.
 *
 * scord 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 scord.  If not, see <https://www.gnu.org/licenses/>.
 *
 * SPDX-License-Identifier: GPL-3.0-or-later
 *****************************************************************************/

#include <utils/utils.hpp>
#include <cstdarg>
#include "logger.hpp"
#include "logger.h"

void
logger_setup(const char* ident, const char* type, const char* log_file) {
    scord::logger::create_global_logger(ident, type, log_file);
}

void
logger_log(enum logger_level level, const char* fmt, ...) {

    if(const auto logger = scord::logger::get_global_logger(); logger) {

        std::array<char, LOGGER_MSG_MAX_LEN> msg; // NOLINT
        va_list args;
        va_start(args, fmt);
        vsnprintf(msg.data(), msg.size(), fmt, args);
        va_end(args);

        switch(level) {
            case info:
                logger->info(msg.data());
                break;
            case debug:
                logger->debug(msg.data());
                break;
            case warn:
                logger->warn(msg.data());
                break;
            case error:
                logger->error(msg.data());
                break;
            case critical:
                logger->critical(msg.data());
                break;
        }
    }
}

void
logger_destroy() {
    if(scord::logger::get_global_logger()) {
        scord::logger::destroy_global_logger();
    }
}
+73 −0
Original line number Diff line number Diff line
/******************************************************************************
 * Copyright 2021-2023, Barcelona Supercomputing Center (BSC), Spain
 *
 * This software was partially supported by the EuroHPC-funded project ADMIRE
 *   (Project ID: 956748, https://www.admire-eurohpc.eu).
 *
 * This file is part of scord.
 *
 * scord 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.
 *
 * scord 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 scord.  If not, see <https://www.gnu.org/licenses/>.
 *
 * SPDX-License-Identifier: GPL-3.0-or-later
 *****************************************************************************/

#ifndef SCORD_LOGGER_H
#define SCORD_LOGGER_H

#include "macros.h"

#ifdef __cplusplus
extern "C" {
#endif

#define LOGGER_MSG_MAX_LEN 2048

enum logger_level { info, debug, warn, error, critical };

/**
 * Initialize a global logger.
 *
 * Valid logger types:
 *  - console
 *  - console color
 *  - file
 *
 * @param ident The identifier that should be used when emitting messages
 * @param type The type of logger desired.
 * @param log_file The path to the log file where messages should be written.
 */
void
setup_logger(const char* ident, const char* type, const char* log_file);

/**
 * Emit a message.
 *
 * @param level The level for the message.
 * @param fmt A vprintf()-compatible format string.
 * @param ... A sequence of arguments corresponding to the format string.
 */
void
logger_log(enum logger_level level, const char* fmt, ...);

/**
 * Destroy the global logger.
 */
void
destroy_logger();

#ifdef __cplusplus
}; // extern "C"
#endif

#endif // SCORD_LOGGER_H
+2 −81
Original line number Diff line number Diff line
@@ -34,6 +34,8 @@
#include <filesystem>
#include <sstream>

#include "macros.h"

#if FMT_VERSION < 50000
namespace fmt {
template <typename T>
@@ -279,85 +281,4 @@ private:

} // namespace scord

// some macros to make it more convenient to use the global logger
#define LOGGER_INFO(...)                                                       \
    do {                                                                       \
        using scord::logger;                                                   \
        if(logger::get_global_logger()) {                                      \
            logger::get_global_logger()->info(__VA_ARGS__);                    \
        }                                                                      \
    } while(0);


#ifdef __LOGGER_ENABLE_DEBUG__

#define LOGGER_DEBUG(...)                                                      \
    do {                                                                       \
        using scord::logger;                                                   \
        if(logger::get_global_logger()) {                                      \
            logger::get_global_logger()->debug(__VA_ARGS__);                   \
        }                                                                      \
    } while(0);

#define LOGGER_FLUSH()                                                         \
    do {                                                                       \
        using scord::logger;                                                   \
        if(logger::get_global_logger()) {                                      \
            logger::get_global_logger()->flush();                              \
        }                                                                      \
    } while(0);

#else

#define LOGGER_DEBUG(...)                                                      \
    do {                                                                       \
    } while(0);
#define LOGGER_FLUSH()                                                         \
    do {                                                                       \
    } while(0);

#endif // __LOGGER_ENABLE_DEBUG__

#define LOGGER_WARN(...)                                                       \
    do {                                                                       \
        using scord::logger;                                                   \
        if(logger::get_global_logger()) {                                      \
            logger::get_global_logger()->warn(__VA_ARGS__);                    \
        }                                                                      \
    } while(0);

#define LOGGER_ERROR(...)                                                      \
    do {                                                                       \
        using scord::logger;                                                   \
        if(logger::get_global_logger()) {                                      \
            logger::get_global_logger()->error(__VA_ARGS__);                   \
        }                                                                      \
    } while(0);

#define LOGGER_ERRNO(...)                                                      \
    do {                                                                       \
        using scord::logger;                                                   \
        if(logger::get_global_logger()) {                                      \
            logger::get_global_logger()->error_errno(__VA_ARGS__);             \
        }                                                                      \
    } while(0);

#define LOGGER_CRITICAL(...)                                                   \
    do {                                                                       \
        using scord::logger;                                                   \
        if(logger::get_global_logger()) {                                      \
            logger::get_global_logger()->critical(__VA_ARGS__);                \
        }                                                                      \
    } while(0);


#define LOGGER_EVAL(expr, L1, L2, ...)                                         \
    do {                                                                       \
        if(expr) {                                                             \
            LOGGER_##L1(__VA_ARGS__);                                          \
        } else {                                                               \
            LOGGER_##L2(__VA_ARGS__);                                          \
        }                                                                      \
    } while(0);

#endif /* SCORD_LOGGER_HPP */
+159 −0
Original line number Diff line number Diff line
/******************************************************************************
 * Copyright 2021-2023, Barcelona Supercomputing Center (BSC), Spain
 *
 * This software was partially supported by the EuroHPC-funded project ADMIRE
 *   (Project ID: 956748, https://www.admire-eurohpc.eu).
 *
 * This file is part of scord.
 *
 * scord 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.
 *
 * scord 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 scord.  If not, see <https://www.gnu.org/licenses/>.
 *
 * SPDX-License-Identifier: GPL-3.0-or-later
 *****************************************************************************/


#ifndef SCORD_MACROS_H
#define SCORD_MACROS_H

/* logger macros for C++ code */
#ifdef __cplusplus

#define LOGGER_INFO(...)                                                       \
    do {                                                                       \
        using scord::logger;                                                   \
        if(logger::get_global_logger()) {                                      \
            logger::get_global_logger()->info(__VA_ARGS__);                    \
        }                                                                      \
    } while(0);


#ifdef __LOGGER_ENABLE_DEBUG__

#define LOGGER_DEBUG(...)                                                      \
    do {                                                                       \
        using scord::logger;                                                   \
        if(logger::get_global_logger()) {                                      \
            logger::get_global_logger()->debug(__VA_ARGS__);                   \
        }                                                                      \
    } while(0);

#define LOGGER_FLUSH()                                                         \
    do {                                                                       \
        using scord::logger;                                                   \
        if(logger::get_global_logger()) {                                      \
            logger::get_global_logger()->flush();                              \
        }                                                                      \
    } while(0);

#else // ! __LOGGER_ENABLE_DEBUG__

#define LOGGER_DEBUG(...)                                                      \
    do {                                                                       \
    } while(0);
#define LOGGER_FLUSH()                                                         \
    do {                                                                       \
    } while(0);

#endif // __LOGGER_ENABLE_DEBUG__

#define LOGGER_WARN(...)                                                       \
    do {                                                                       \
        using scord::logger;                                                   \
        if(logger::get_global_logger()) {                                      \
            logger::get_global_logger()->warn(__VA_ARGS__);                    \
        }                                                                      \
    } while(0);

#define LOGGER_ERROR(...)                                                      \
    do {                                                                       \
        using scord::logger;                                                   \
        if(logger::get_global_logger()) {                                      \
            logger::get_global_logger()->error(__VA_ARGS__);                   \
        }                                                                      \
    } while(0);

#define LOGGER_ERRNO(...)                                                      \
    do {                                                                       \
        using scord::logger;                                                   \
        if(logger::get_global_logger()) {                                      \
            logger::get_global_logger()->error_errno(__VA_ARGS__);             \
        }                                                                      \
    } while(0);

#define LOGGER_CRITICAL(...)                                                   \
    do {                                                                       \
        using scord::logger;                                                   \
        if(logger::get_global_logger()) {                                      \
            logger::get_global_logger()->critical(__VA_ARGS__);                \
        }                                                                      \
    } while(0);

#else // ! __cplusplus

/* logger macros for C code */

// clang-format off
#define ARGSN(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, N, ...) N
#define RSEQN() 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
// clang-format on
#define EXPAND(x)                x
#define COUNT_ARGS(...)          EXPAND(COUNT_ARGS_HELPER(__VA_ARGS__, RSEQN()))
#define COUNT_ARGS_HELPER(...)   EXPAND(ARGSN(__VA_ARGS__))
#define GET_NAME_HELPER(name, n) name##n
#define GET_NAME(name, n)        GET_NAME_HELPER(name, n)
#define GET_MACRO(func, ...)                                                   \
    GET_NAME(func, EXPAND(COUNT_ARGS(__VA_ARGS__)))(__VA_ARGS__)

#define LOGGER_LOG(level, ...)       GET_MACRO(LOGGER_LOG, level, __VA_ARGS__)
#define LOGGER_LOG2(level, msg)      logger_log(level, "%s", msg)
#define LOGGER_LOG3                  LOGGER_LOGN
#define LOGGER_LOG4                  LOGGER_LOGN
#define LOGGER_LOG5                  LOGGER_LOGN
#define LOGGER_LOG6                  LOGGER_LOGN
#define LOGGER_LOG7                  LOGGER_LOGN
#define LOGGER_LOG8                  LOGGER_LOGN
#define LOGGER_LOG9                  LOGGER_LOGN
#define LOGGER_LOG10                 LOGGER_LOGN
#define LOGGER_LOG11                 LOGGER_LOGN
#define LOGGER_LOG12                 LOGGER_LOGN
#define LOGGER_LOG13                 LOGGER_LOGN
#define LOGGER_LOG14                 LOGGER_LOGN
#define LOGGER_LOG15                 LOGGER_LOGN
#define LOGGER_LOG16                 LOGGER_LOGN
#define LOGGER_LOGN(level, fmt, ...) logger_log(level, fmt, __VA_ARGS__)

#define LOGGER_INFO(fmt, ...) LOGGER_LOG(info, fmt __VA_OPT__(, ) __VA_ARGS__);

#ifdef __LOGGER_ENABLE_DEBUG__
#define LOGGER_DEBUG(fmt, ...)                                                 \
    LOGGER_LOG(debug, fmt __VA_OPT__(, ) __VA_ARGS__);
#endif

#define LOGGER_WARN(fmt, ...) LOGGER_LOG(warn, fmt __VA_OPT__(, ) __VA_ARGS__);

#define LOGGER_ERROR(fmt, ...)                                                 \
    LOGGER_LOG(error, fmt __VA_OPT__(, ) __VA_ARGS__);

#endif

#define LOGGER_EVAL(expr, L1, L2, ...)                                         \
    do {                                                                       \
        if(expr) {                                                             \
            LOGGER_##L1(__VA_ARGS__);                                          \
        } else {                                                               \
            LOGGER_##L2(__VA_ARGS__);                                          \
        }                                                                      \
    } while(0);

#endif // SCORD_MACROS_H
Loading