source/Log.cpp (81 lines of code) (raw):

/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #include <cstdio> #include <cstdlib> #include <mutex> #include <mariana-trench/Log.h> namespace { struct LoggerImplementation { public: LoggerImplementation() : level_(0), file_(stderr) { const char* env = std::getenv("TRACE"); if (env) { parse_environment(env); } } LoggerImplementation(const LoggerImplementation&) = delete; LoggerImplementation(LoggerImplementation&&) = delete; LoggerImplementation& operator=(const LoggerImplementation&) = delete; LoggerImplementation& operator=(LoggerImplementation&&) = delete; ~LoggerImplementation() = default; void set_level(int level) { level_ = level; } int get_level() { return level_; } bool enabled(int level) const { return level <= level_; } void log(std::string_view section, int level, std::string_view message) { if (!enabled(level)) { return; } std::string line = fmt::format("{} {}\n", section, message); std::lock_guard<std::mutex> guard(mutex_); fwrite(line.c_str(), line.size(), 1, file_); fflush(file_); } private: void parse_environment(std::string_view configuration) { // This needs to be consistent with redex. std::string module; std::string token; while (!configuration.empty()) { auto next_token_position = configuration.find_first_of(",: "); if (next_token_position != std::string::npos) { token = configuration.substr(0, next_token_position); configuration = configuration.substr(next_token_position + 1); } else { token = configuration; configuration = {}; } int level = std::atoi(token.c_str()); if (!level) { module = token; } else if (module == "MARIANA_TRENCH") { level_ = level; } } } private: int level_; FILE* file_; std::mutex mutex_; }; static LoggerImplementation logger; } // namespace namespace marianatrench { void Logger::set_level(int level) { logger.set_level(level); } int Logger::get_level() { return logger.get_level(); } bool Logger::enabled(int level) { return logger.enabled(level); } void Logger::log( std::string_view section, int level, std::string_view message) { logger.log(section, level, message); } } // namespace marianatrench