Skip to content

Commit

Permalink
Make log levels type safe
Browse files Browse the repository at this point in the history
  • Loading branch information
imwints committed Sep 19, 2023
1 parent 30aec9a commit b37e6b1
Show file tree
Hide file tree
Showing 8 changed files with 183 additions and 183 deletions.
17 changes: 10 additions & 7 deletions src/btop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -819,16 +819,19 @@ int main(int argc, char **argv) {
}
}
if (Global::debug) {
Logger::set("DEBUG");
Logger::set(Logger::Level::DEBUG);
Logger::debug("Starting in DEBUG mode!");
}
else if (v_contains(Logger::log_levels, log_level_env)) {
Logger::set(log_level_env);
Logger::info("Log level set to {}", log_level_env);
}
else {
Logger::set(Config::getS("log_level"));
Logger::info("Log level set to {}", Config::getS("log_level"));
const auto level = Logger::level_from_string(log_level_env);
if (level.has_value()) {
Logger::set(level.value());
Logger::info("Log level set to {}", log_level_env);
}
else {
Logger::set(Logger::level_from_string(Config::getS("log_level")).value_or(Logger::Level::WARNING));
Logger::info("Log level set to {}", Config::getS("log_level"));
}
}

for (const auto& err_str : load_warnings) Logger::warning("{}", err_str);
Expand Down
2 changes: 1 addition & 1 deletion src/btop_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,7 @@ namespace Config {
}

bool stringValid(const std::string_view name, const string& value) {
if (name == "log_level" and not v_contains(Logger::log_levels, value))
if (name == "log_level" and not Logger::level_from_string(value).has_value())
validError = "Invalid log_level: " + value;

else if (name == "graph_symbol" and not v_contains(valid_graph_symbols, value))
Expand Down
3 changes: 3 additions & 0 deletions src/btop_config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ tab-size = 4

#include <robin_hood.h>

#include "btop_log.hpp"

using std::string;
using std::vector;
using robin_hood::unordered_flat_map;
Expand All @@ -45,6 +47,7 @@ namespace Config {
const vector<string> valid_graph_symbols_def = { "default", "braille", "block", "tty" };
const vector<string> valid_boxes = { "cpu", "mem", "net", "proc" };
const vector<string> temp_scales = { "celsius", "fahrenheit", "kelvin", "rankine" };
const vector<string> valid_log_levels = { "DISABLED", "ERROR", "WARNING", "INFO", "DEBUG" };

extern vector<string> current_boxes;
extern vector<string> preset_list;
Expand Down
35 changes: 28 additions & 7 deletions src/btop_log.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <filesystem>
#include <iostream>
#include <mutex>
#include <optional>
#include <source_location>
#include <string>
#include <string_view>
Expand All @@ -26,7 +27,7 @@ namespace fs = std::filesystem;
namespace Logger {
using namespace Tools;

size_t loglevel;
Level log_level;
std::mutex log_mtx{};

#if !(defined(HAVE_SYSLOG) || defined(HAVE_JOURNALD))
Expand All @@ -40,12 +41,12 @@ namespace Logger {
int status = -1;

public:
DropPrivileges() noexcept {
DropPrivileges() {
if (geteuid() != Global::real_uid) {
this->status = seteuid(Global::real_uid);
}
}
~DropPrivileges() noexcept {
~DropPrivileges() {
if (status == 0) {
status = seteuid(Global::set_uid);
}
Expand All @@ -57,10 +58,30 @@ namespace Logger {
DropPrivileges&& operator=(DropPrivileges&&) = delete;
};

void set(const string& level) noexcept { loglevel = v_index(log_levels, level); }
std::optional<Level> level_from_string(const std::string_view level_str) {
if (level_str == "DISABLED") { return Level::DISABLED; }
else if (level_str == "ERROR") { return Level::ERROR; }
else if (level_str == "WARNING") { return Level::WARNING; }
else if (level_str == "INFO") { return Level::INFO; }
else if (level_str == "DEBUG") { return Level::DEBUG; }
else { return {}; }
}

std::string_view string_from_level(const Level level) {
switch (level) {
case Level::DISABLED: return "DISABLED";
case Level::ERROR: return "ERROR";
case Level::WARNING: return "WARNING";
case Level::INFO: return "INFO";
case Level::DEBUG: return "DEBUG";
default: return "";
}
}

void set(const Level level) { log_level = level; }

void log(const size_t level, const std::string_view msg, [[maybe_unused]] const std::source_location location) {
if (loglevel < level) {
void log(const Level level, const std::string_view msg, [[maybe_unused]] const std::source_location location) {
if (level > log_level || level == Level::DISABLED) {
return;
}

Expand Down Expand Up @@ -112,7 +133,7 @@ namespace Logger {
std::call_once(log_file_header, [&lwrite] {
fmt::print(lwrite, "\n{}===> btop++ v.{}\n", strf_time(tdf), Global::Version);
});
fmt::print(lwrite, "{}{}: {}\n", strf_time(tdf), log_levels.at(level), msg);
fmt::print(lwrite, "{}{}: {}\n", strf_time(tdf), string_from_level(level), msg);
}
else {
logfile.clear();
Expand Down
31 changes: 17 additions & 14 deletions src/btop_log.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,38 @@
#pragma once

#include <filesystem>
#include <optional>
#include <source_location>
#include <string_view>
#include <vector>

#include <fmt/core.h>

namespace Logger {
const std::vector<std::string> log_levels = {
"DISABLED",
"ERROR",
"WARNING",
"INFO",
"DEBUG",
enum class Level {
DISABLED = 0x00,
ERROR = 0x01,
WARNING = 0x02,
INFO = 0x04,
DEBUG = 0x08,
};

extern std::filesystem::path logfile;

//* Set log level, valid arguments: "DISABLED", "ERROR", "WARNING", "INFO" and "DEBUG"
void set(const std::string& level) noexcept;
std::optional<Level> level_from_string(const std::string_view level_str);

void log(const size_t level, const std::string_view msg, const std::source_location location);
std::string_view string_from_level(const Level level);

void set(const Level level);

void log(const Level level, const std::string_view msg, const std::source_location location);

template<typename... Args>
struct error { // NOLINT(readability-identifier-naming)
constexpr error(
const fmt::format_string<Args...> fmt, Args&&... args,
const std::source_location location = std::source_location::current()
) {
log(1, fmt::format(fmt, std::forward<Args>(args)...), location);
log(Level::ERROR, fmt::format(fmt, std::forward<Args>(args)...), location);
}
};

Expand All @@ -41,7 +44,7 @@ namespace Logger {
const fmt::format_string<Args...> fmt, Args&&... args,
const std::source_location location = std::source_location::current()
) {
log(2, fmt::format(fmt, std::forward<Args>(args)...), location);
log(Level::WARNING, fmt::format(fmt, std::forward<Args>(args)...), location);
}
};

Expand All @@ -51,7 +54,7 @@ namespace Logger {
const fmt::format_string<Args...> fmt, Args&&... args,
const std::source_location location = std::source_location::current()
) {
log(3, fmt::format(fmt, std::forward<Args>(args)...), location);
log(Level::INFO, fmt::format(fmt, std::forward<Args>(args)...), location);
}
};

Expand All @@ -61,7 +64,7 @@ namespace Logger {
const fmt::format_string<Args...> fmt, Args&&... args,
const std::source_location location = std::source_location::current()
) {
log(4, fmt::format(fmt, std::forward<Args>(args)...), location);
log(Level::DEBUG, fmt::format(fmt, std::forward<Args>(args)...), location);
}
};

Expand Down
7 changes: 4 additions & 3 deletions src/btop_menu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1018,7 +1018,7 @@ namespace Menu {
static bitset<8> selPred;
static const unordered_flat_map<string, std::reference_wrapper<const vector<string>>> optionsList = {
{"color_theme", std::cref(Theme::themes)},
{"log_level", std::cref(Logger::log_levels)},
{"log_level", std::cref(Config::valid_log_levels)},
{"temp_scale", std::cref(Config::temp_scales)},
{"proc_sorting", std::cref(Proc::sort_vector)},
{"graph_symbol", std::cref(Config::valid_graph_symbols)},
Expand Down Expand Up @@ -1211,8 +1211,9 @@ namespace Menu {
if (option == "color_theme")
theme_refresh = true;
else if (option == "log_level") {
Logger::set(optList.at(i));
Logger::info("Logger set to {}", optList.at(i));
const auto level = Logger::level_from_string(optList.at(i)).value_or(Logger::Level::WARNING);
Logger::set(level);
Logger::info("Log level set to {}", Logger::string_from_level(level));
}
else if (is_in(option, "proc_sorting", "cpu_sensor") or option.starts_with("graph_symbol") or option.starts_with("cpu_graph_"))
screen_redraw = true;
Expand Down
Loading

0 comments on commit b37e6b1

Please sign in to comment.