<commit_before>#pragma once

#include <iostream>
#include <functional>
#include <vector>
#include <mutex>
#include <boost/format.hpp>
#include <crossbow/singleton.hpp>
#include <crossbow/string.hpp>

namespace tell {
namespace store {

enum class LogLevel
    : unsigned char {
    TRACE = 0,
    DEBUG,
    INFO,
    WARN,
    ERROR,
    FATAL
};

template<class... Args>
struct LogFormatter;

template<class Head, class... Tail>
struct LogFormatter<Head, Tail...> {
    LogFormatter<Tail...> base;

    void format(boost::format& f, Head h, Tail... tail) const {
        f % h;
        base.format(f, tail...);
    }
};

template<>
struct LogFormatter<> {
    void format(boost::format&) const {
        return;
    }
};

struct LoggerConfig {
    using DestructFunction = std::function<void()>;
    std::vector<DestructFunction> destructFunctions;
    LogLevel level;
    std::ostream* traceOut = &std::cout;
    std::ostream* debugOut = &std::cout;
    std::ostream* infoOut = &std::cout;
    std::ostream* warnOut = &std::clog;
    std::ostream* errorOut = &std::cerr;
    std::ostream* fatalOut = &std::cerr;
};

class LoggerT {
    std::mutex mTraceMutex;
    std::mutex mDebugMutex;
    std::mutex mInfoMutex;
    std::mutex mWarnMutex;
    std::mutex mErrorMutex;
    std::mutex mFatalMutex;

    template<class...Args>
    void log(
        LogLevel level,
        std::ostream& stream,
        std::mutex& mutex,
        const char* file,
        unsigned line,
        const char* function,
        const crossbow::string& str,
        Args... args) {
        if (config.level > level) return;
        boost::format formatter(str.c_str());
        LogFormatter<Args...> fmt;
        fmt.format(formatter, args...);
        std::lock_guard<std::mutex> _(mutex);
        stream << formatter.str();
        stream << " (in " << function << " at " << file << ':' << line << ')' << std::endl;
    }

public:
    LoggerConfig config;

    ~LoggerT();

    template<class...Args>
    void trace(const char* file, unsigned line, const char* function, const crossbow::string& str, Args... args) {
        log(LogLevel::TRACE, *(config.traceOut), mTraceMutex, file, line, function, str, args...);
    }

    template<class...Args>
    void debug(const char* file, unsigned line, const char* function, const crossbow::string& str, Args... args) {
        log(LogLevel::DEBUG, *(config.debugOut), mDebugMutex, file, line, function, str, args...);
    }

    template<class...Args>
    void info(const char* file, unsigned line, const char* function, const crossbow::string& str, Args... args) {
        log(LogLevel::INFO, *(config.infoOut), mInfoMutex, file, line, function, str, args...);
    }

    template<class...Args>
    void warn(const char* file, unsigned line, const char* function, const crossbow::string& str, Args... args) {
        log(LogLevel::WARN, *(config.warnOut), mWarnMutex, file, line, function, str, args...);
    }

    template<class...Args>
    void error(const char* file, unsigned line, const char* function, const crossbow::string& str, Args... args) {
        log(LogLevel::ERROR, *(config.errorOut), mInfoMutex, file, line, function, str, args...);
    }

    template<class...Args>
    void fatal(const char* file, unsigned line, const char* function, const crossbow::string& str, Args... args) {
        log(LogLevel::FATAL, *(config.fatalOut), mInfoMutex, file, line, function, str, args...);
    }
};

using Logger = crossbow::singleton<LoggerT>;

extern Logger logger;

#define LOG_TRACE(...) logger->trace(__FILE__, __LINE__, __FUNCTION__, __VA_ARGS__)
#define LOG_DEBUG(...) logger->debug(__FILE__, __LINE__, __FUNCTION__, __VA_ARGS__)
#define LOG_INFO(...) logger->info(__FILE__, __LINE__, __FUNCTION__, __VA_ARGS__)
#define LOG_WARN(...) logger->warn(__FILE__, __LINE__, __FUNCTION__, __VA_ARGS__)
#define LOG_ERROR(...) logger->error(__FILE__, __LINE__, __FUNCTION__, __VA_ARGS__)
#define LOG_FATAL(...) logger->fatal(__FILE__, __LINE__, __FUNCTION__, __VA_ARGS__)
#ifdef NDEBUG
#   define LOG_ASSERT(...)
#else
#   define LOG_ASSERT(Cond, ...) if (!(Cond)) { std::cerr << "Assertion Failed: " #Cond ":" << std::endl; LOG_FATAL(__VA_ARGS__); std::terminate(); }
#endif // NDEBUG

} // namespace store
} // namespace tell
<commit_msg>Use full namespace name in logger macros<commit_after>#pragma once

#include <iostream>
#include <functional>
#include <vector>
#include <mutex>
#include <boost/format.hpp>
#include <crossbow/singleton.hpp>
#include <crossbow/string.hpp>

namespace tell {
namespace store {

enum class LogLevel
    : unsigned char {
    TRACE = 0,
    DEBUG,
    INFO,
    WARN,
    ERROR,
    FATAL
};

template<class... Args>
struct LogFormatter;

template<class Head, class... Tail>
struct LogFormatter<Head, Tail...> {
    LogFormatter<Tail...> base;

    void format(boost::format& f, Head h, Tail... tail) const {
        f % h;
        base.format(f, tail...);
    }
};

template<>
struct LogFormatter<> {
    void format(boost::format&) const {
        return;
    }
};

struct LoggerConfig {
    using DestructFunction = std::function<void()>;
    std::vector<DestructFunction> destructFunctions;
    LogLevel level;
    std::ostream* traceOut = &std::cout;
    std::ostream* debugOut = &std::cout;
    std::ostream* infoOut = &std::cout;
    std::ostream* warnOut = &std::clog;
    std::ostream* errorOut = &std::cerr;
    std::ostream* fatalOut = &std::cerr;
};

class LoggerT {
    std::mutex mTraceMutex;
    std::mutex mDebugMutex;
    std::mutex mInfoMutex;
    std::mutex mWarnMutex;
    std::mutex mErrorMutex;
    std::mutex mFatalMutex;

    template<class...Args>
    void log(
        LogLevel level,
        std::ostream& stream,
        std::mutex& mutex,
        const char* file,
        unsigned line,
        const char* function,
        const crossbow::string& str,
        Args... args) {
        if (config.level > level) return;
        boost::format formatter(str.c_str());
        LogFormatter<Args...> fmt;
        fmt.format(formatter, args...);
        std::lock_guard<std::mutex> _(mutex);
        stream << formatter.str();
        stream << " (in " << function << " at " << file << ':' << line << ')' << std::endl;
    }

public:
    LoggerConfig config;

    ~LoggerT();

    template<class...Args>
    void trace(const char* file, unsigned line, const char* function, const crossbow::string& str, Args... args) {
        log(LogLevel::TRACE, *(config.traceOut), mTraceMutex, file, line, function, str, args...);
    }

    template<class...Args>
    void debug(const char* file, unsigned line, const char* function, const crossbow::string& str, Args... args) {
        log(LogLevel::DEBUG, *(config.debugOut), mDebugMutex, file, line, function, str, args...);
    }

    template<class...Args>
    void info(const char* file, unsigned line, const char* function, const crossbow::string& str, Args... args) {
        log(LogLevel::INFO, *(config.infoOut), mInfoMutex, file, line, function, str, args...);
    }

    template<class...Args>
    void warn(const char* file, unsigned line, const char* function, const crossbow::string& str, Args... args) {
        log(LogLevel::WARN, *(config.warnOut), mWarnMutex, file, line, function, str, args...);
    }

    template<class...Args>
    void error(const char* file, unsigned line, const char* function, const crossbow::string& str, Args... args) {
        log(LogLevel::ERROR, *(config.errorOut), mInfoMutex, file, line, function, str, args...);
    }

    template<class...Args>
    void fatal(const char* file, unsigned line, const char* function, const crossbow::string& str, Args... args) {
        log(LogLevel::FATAL, *(config.fatalOut), mInfoMutex, file, line, function, str, args...);
    }
};

using Logger = crossbow::singleton<LoggerT>;

extern Logger logger;

#define LOG_TRACE(...) tell::store::logger->trace(__FILE__, __LINE__, __FUNCTION__, __VA_ARGS__)
#define LOG_DEBUG(...) tell::store::logger->debug(__FILE__, __LINE__, __FUNCTION__, __VA_ARGS__)
#define LOG_INFO(...) tell::store::logger->info(__FILE__, __LINE__, __FUNCTION__, __VA_ARGS__)
#define LOG_WARN(...) tell::store::logger->warn(__FILE__, __LINE__, __FUNCTION__, __VA_ARGS__)
#define LOG_ERROR(...) tell::store::logger->error(__FILE__, __LINE__, __FUNCTION__, __VA_ARGS__)
#define LOG_FATAL(...) tell::store::logger->fatal(__FILE__, __LINE__, __FUNCTION__, __VA_ARGS__)
#ifdef NDEBUG
#   define LOG_ASSERT(...)
#else
#   define LOG_ASSERT(Cond, ...) if (!(Cond)) { std::cerr << "Assertion Failed: " #Cond ":" << std::endl; LOG_FATAL(__VA_ARGS__); std::terminate(); }
#endif // NDEBUG

} // namespace store
} // namespace tell

{'fraction_non_alphanumeric': 0.16010165184243966, 'fraction_numerical': 0.00023102691463555504, 'mean_word_length': 3.401626842907982, 'pattern_counts': {'":': 2, '<': 97, '<?xml version=': 0, '>': 67, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6767469', 'n_tokens_mistral': 2706, 'n_tokens_neox': 2708, 'n_words': 714}