mirror of
https://github.com/gabime/spdlog.git
synced 2025-01-16 01:37:58 +00:00
Compare commits
74 Commits
8284865f9a
...
54be9bd8b9
Author | SHA1 | Date | |
---|---|---|---|
|
54be9bd8b9 | ||
|
06d0299639 | ||
|
84851e230f | ||
|
52aed9e0de | ||
|
ead9a550fd | ||
|
cf80b492a3 | ||
|
69f3d2678e | ||
|
8038bc2fc8 | ||
|
f20b12cf3f | ||
|
c8bd53509c | ||
|
006124d816 | ||
|
efd73ac956 | ||
|
b7d7334451 | ||
|
c861e2d9cf | ||
|
e696978d11 | ||
|
fbf2e942a9 | ||
|
d18f282938 | ||
|
c10be7eaec | ||
|
5bf99dfd61 | ||
|
bc42415ceb | ||
|
284e6a80ac | ||
|
0243882238 | ||
|
877eee408e | ||
|
8dd54de326 | ||
|
2544fca519 | ||
|
0b55e2c332 | ||
|
b105046202 | ||
|
de20255c71 | ||
|
1a1c37db7c | ||
|
a87700a28c | ||
|
1f8e9ad0fc | ||
|
e13e978af4 | ||
|
28e334c728 | ||
|
15a9427112 | ||
|
010b0e1d75 | ||
|
cd5ddca00d | ||
|
f18e1fccfd | ||
|
773b8c5a54 | ||
|
fc3d18ed64 | ||
|
68ed281461 | ||
|
65ada37399 | ||
|
9f539d7028 | ||
|
0dfb1d264e | ||
|
a056b9115b | ||
|
62ecc04212 | ||
|
4a0f4fc186 | ||
|
3a61dcd360 | ||
|
04d0240f8d | ||
|
13ebfc0779 | ||
|
d70d5aa9d8 | ||
|
70d3c2cd3e | ||
|
6fbe0dec2c | ||
|
9d3591dcd5 | ||
|
8992f36fbf | ||
|
3d203aa7c4 | ||
|
cd8d7e6de9 | ||
|
5d4e6f17ee | ||
|
49f707ec93 | ||
|
6a305df46d | ||
|
35e9482574 | ||
|
dac61d4e9c | ||
|
4fa463dff6 | ||
|
8d9d9899b7 | ||
|
cff7448fb2 | ||
|
3812c22f86 | ||
|
2b3000dddc | ||
|
b278baf94e | ||
|
4119b72d50 | ||
|
da2c15ecb4 | ||
|
d0ed873ab6 | ||
|
0f24399887 | ||
|
abbbda6f74 | ||
|
1a5ee7ab83 | ||
|
4d41fdf0fc |
@ -117,7 +117,8 @@ set(SPDLOG_SRCS
|
||||
src/stdout_sinks.cpp
|
||||
src/color_sinks.cpp
|
||||
src/file_sinks.cpp
|
||||
src/async.cpp)
|
||||
src/async.cpp
|
||||
src/cfg.cpp)
|
||||
|
||||
|
||||
if(NOT SPDLOG_FMT_EXTERNAL AND NOT SPDLOG_FMT_EXTERNAL_HO)
|
||||
|
22
README.md
22
README.md
@ -36,7 +36,7 @@ $ cmake .. && make -j
|
||||
|
||||
## Features
|
||||
* Very fast (see [benchmarks](#benchmarks) below).
|
||||
* Headers only, just copy and use. Or use as a compiled library.
|
||||
* Headers only or compiled version
|
||||
* Feature rich formatting, using the excellent [fmt](https://github.com/fmtlib/fmt) library.
|
||||
* **New!** [Backtrace](#backtrace-support) support - store debug messages in a ring buffer and display later on demand.
|
||||
* Asynchronous mode (optional)
|
||||
@ -49,7 +49,8 @@ $ cmake .. && make -j
|
||||
* syslog.
|
||||
* Windows debugger (```OutputDebugString(..)```)
|
||||
* Easily extendable with custom log targets (just implement a single function in the [sink](include/spdlog/sinks/sink.h) interface).
|
||||
* Severity based filtering - threshold levels can be modified in runtime as well as in compile time.
|
||||
* Log filtering - log levels can be modified in runtime as well as in compile time.
|
||||
* Support for loading log levels from argv or from environment var.
|
||||
|
||||
|
||||
## Usage samples
|
||||
@ -85,8 +86,23 @@ int main()
|
||||
auto file_logger = spdlog::basic_logger_mt("basic_logger", "logs/basic.txt");
|
||||
spdlog::set_default_logger(file_logger);
|
||||
}
|
||||
|
||||
```
|
||||
#### create stdout/stderr logger object
|
||||
#### Load log levels from env variable or from argv
|
||||
```c++
|
||||
#include "spdlog/cfg/env.h"
|
||||
void load_levels_example()
|
||||
{
|
||||
// Set the log level to "info" and mylogger to to "trace":
|
||||
// SPDLOG_LEVEL=info,mylogger=trace && ./example
|
||||
spdlog::cfg::load_env_levels();
|
||||
// or from command line:
|
||||
// ./example SPDLOG_LEVEL=info,mylogger=trace
|
||||
// #include "spdlog/cfg/argv.h" // for loading levels from argv
|
||||
// spdlog::cfg::load_argv_levels(args, argv);
|
||||
}
|
||||
```
|
||||
#### Create stdout/stderr logger object
|
||||
```c++
|
||||
#include "spdlog/spdlog.h"
|
||||
#include "spdlog/sinks/stdout_color_sinks.h"
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
void load_levels_example();
|
||||
void stdout_logger_example();
|
||||
void basic_example();
|
||||
void rotating_example();
|
||||
@ -19,10 +20,15 @@ void err_handler_example();
|
||||
void syslog_example();
|
||||
|
||||
#include "spdlog/spdlog.h"
|
||||
#include "spdlog/cfg/env.h" // for loading levels from the environment variables
|
||||
|
||||
int main(int, char *[])
|
||||
{
|
||||
// Log levels can be loaded from argv/env using "SPDLOG_LEVEL"
|
||||
load_levels_example();
|
||||
|
||||
spdlog::info("Welcome to spdlog version {}.{}.{} !", SPDLOG_VER_MAJOR, SPDLOG_VER_MINOR, SPDLOG_VER_PATCH);
|
||||
|
||||
spdlog::warn("Easy padding in numbers like {:08d}", 12);
|
||||
spdlog::critical("Support for int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}", 42);
|
||||
spdlog::info("Support for floats {:03.2f}", 1.23456);
|
||||
@ -116,6 +122,18 @@ void daily_example()
|
||||
auto daily_logger = spdlog::daily_logger_mt("daily_logger", "logs/daily.txt", 2, 30);
|
||||
}
|
||||
|
||||
#include "spdlog/cfg/env.h"
|
||||
void load_levels_example()
|
||||
{
|
||||
// Set the log level to "info" and mylogger to to "trace":
|
||||
// SPDLOG_LEVEL=info,mylogger=trace && ./example
|
||||
spdlog::cfg::load_env_levels();
|
||||
// or from command line:
|
||||
// ./example SPDLOG_LEVEL=info,mylogger=trace
|
||||
// #include "spdlog/cfg/argv.h" // for loading levels from argv
|
||||
// spdlog::cfg::load_argv_levels(args, argv);
|
||||
}
|
||||
|
||||
#include "spdlog/async.h"
|
||||
void async_example()
|
||||
{
|
||||
|
40
include/spdlog/cfg/argv.h
Normal file
40
include/spdlog/cfg/argv.h
Normal file
@ -0,0 +1,40 @@
|
||||
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||
|
||||
#pragma once
|
||||
#include <spdlog/cfg/helpers.h>
|
||||
#include <spdlog/details/os.h>
|
||||
|
||||
//
|
||||
// Init log levels using each argv entry that starts with "SPDLOG_LEVEL="
|
||||
//
|
||||
// set all loggers to debug level:
|
||||
// example.exe "SPDLOG_LEVEL=debug"
|
||||
|
||||
// set logger1 to trace level
|
||||
// example.exe "SPDLOG_LEVEL=logger1=trace"
|
||||
|
||||
// turn off all logging except for logger1 and logger2:
|
||||
// example.exe "SPDLOG_LEVEL=off,logger1=debug,logger2=info"
|
||||
|
||||
namespace spdlog {
|
||||
namespace cfg {
|
||||
|
||||
// search for SPDLOG_LEVEL= in the args and use it to init the levels
|
||||
void load_argv_levels(int args, char **argv)
|
||||
{
|
||||
const std::string spdlog_level_prefix = "SPDLOG_LEVEL=";
|
||||
for (int i = 1; i < args; i++)
|
||||
{
|
||||
std::string arg = argv[i];
|
||||
if (arg.find(spdlog_level_prefix) == 0)
|
||||
{
|
||||
auto levels_string = arg.substr(spdlog_level_prefix.size());
|
||||
auto levels = helpers::extract_levels(levels_string);
|
||||
details::registry::instance().update_levels(std::move(levels));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace cfg
|
||||
} // namespace spdlog
|
36
include/spdlog/cfg/env.h
Normal file
36
include/spdlog/cfg/env.h
Normal file
@ -0,0 +1,36 @@
|
||||
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||
|
||||
#pragma once
|
||||
#include <spdlog/cfg/helpers.h>
|
||||
#include <spdlog/details/registry.h>
|
||||
#include <spdlog/details/os.h>
|
||||
|
||||
//
|
||||
// Init levels and patterns from env variables SPDLOG_LEVEL
|
||||
// Inspired from Rust's "env_logger" crate (https://crates.io/crates/env_logger).
|
||||
// Note - fallback to "info" level on unrecognized levels
|
||||
//
|
||||
// Examples:
|
||||
//
|
||||
// set global level to debug:
|
||||
// export SPDLOG_LEVEL=debug
|
||||
//
|
||||
// turn off all logging except for logger1:
|
||||
// export SPDLOG_LEVEL="off,logger1=debug"
|
||||
//
|
||||
|
||||
// turn off all logging except for logger1 and logger2:
|
||||
// export SPDLOG_LEVEL="off,logger1=debug,logger2=info"
|
||||
|
||||
namespace spdlog {
|
||||
namespace cfg {
|
||||
void load_env_levels()
|
||||
{
|
||||
auto env_val = details::os::getenv("SPDLOG_LEVEL");
|
||||
auto levels = helpers::extract_levels(env_val);
|
||||
details::registry::instance().update_levels(std::move(levels));
|
||||
}
|
||||
|
||||
} // namespace cfg
|
||||
} // namespace spdlog
|
103
include/spdlog/cfg/helpers-inl.h
Normal file
103
include/spdlog/cfg/helpers-inl.h
Normal file
@ -0,0 +1,103 @@
|
||||
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef SPDLOG_HEADER_ONLY
|
||||
#include <spdlog/cfg/helpers.h>
|
||||
#endif
|
||||
|
||||
#include <spdlog/spdlog.h>
|
||||
#include <spdlog/details/os.h>
|
||||
#include <spdlog/details/registry.h>
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <sstream>
|
||||
|
||||
namespace spdlog {
|
||||
namespace cfg {
|
||||
namespace helpers {
|
||||
|
||||
// inplace convert to lowercase
|
||||
inline std::string &to_lower_(std::string &str)
|
||||
{
|
||||
std::transform(
|
||||
str.begin(), str.end(), str.begin(), [](char ch) { return static_cast<char>((ch >= 'A' && ch <= 'Z') ? ch + ('a' - 'A') : ch); });
|
||||
return str;
|
||||
}
|
||||
|
||||
// inplace trim spaces
|
||||
inline std::string &trim_(std::string &str)
|
||||
{
|
||||
const char *spaces = " \n\r\t";
|
||||
str.erase(str.find_last_not_of(spaces) + 1);
|
||||
str.erase(0, str.find_first_not_of(spaces));
|
||||
return str;
|
||||
}
|
||||
|
||||
// return (name,value) trimmed pair from given "name=value" string.
|
||||
// return empty string on missing parts
|
||||
// "key=val" => ("key", "val")
|
||||
// " key = val " => ("key", "val")
|
||||
// "key=" => ("key", "")
|
||||
// "val" => ("", "val")
|
||||
|
||||
inline std::pair<std::string, std::string> extract_kv_(char sep, const std::string &str)
|
||||
{
|
||||
auto n = str.find(sep);
|
||||
std::string k, v;
|
||||
if (n == std::string::npos)
|
||||
{
|
||||
v = str;
|
||||
}
|
||||
else
|
||||
{
|
||||
k = str.substr(0, n);
|
||||
v = str.substr(n + 1);
|
||||
}
|
||||
return std::make_pair(trim_(k), trim_(v));
|
||||
}
|
||||
|
||||
// return vector of key/value pairs from sequence of "K1=V1,K2=V2,.."
|
||||
// "a=AAA,b=BBB,c=CCC,.." => {("a","AAA"),("b","BBB"),("c", "CCC"),...}
|
||||
inline std::unordered_map<std::string, std::string> extract_key_vals_(const std::string &str)
|
||||
{
|
||||
std::string token;
|
||||
std::istringstream token_stream(str);
|
||||
std::unordered_map<std::string, std::string> rv{};
|
||||
while (std::getline(token_stream, token, ','))
|
||||
{
|
||||
if (token.empty())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
auto kv = extract_kv_('=', token);
|
||||
rv[kv.first] = kv.second;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
SPDLOG_INLINE log_levels extract_levels(const std::string &input)
|
||||
{
|
||||
auto key_vals = extract_key_vals_(input);
|
||||
log_levels rv;
|
||||
|
||||
for (auto &name_level : key_vals)
|
||||
{
|
||||
auto &logger_name = name_level.first;
|
||||
auto level_name = to_lower_(name_level.second);
|
||||
auto level = level::from_str(level_name);
|
||||
// fallback to "info" if unrecognized level name
|
||||
if (level == level::off && level_name != "off")
|
||||
{
|
||||
level = level::info;
|
||||
}
|
||||
rv.set(logger_name, level);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
} // namespace helpers
|
||||
} // namespace cfg
|
||||
} // namespace spdlog
|
28
include/spdlog/cfg/helpers.h
Normal file
28
include/spdlog/cfg/helpers.h
Normal file
@ -0,0 +1,28 @@
|
||||
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <spdlog/cfg/log_levels.h>
|
||||
|
||||
namespace spdlog {
|
||||
namespace cfg {
|
||||
namespace helpers {
|
||||
//
|
||||
// Init levels from given string
|
||||
//
|
||||
// Examples:
|
||||
//
|
||||
// set global level to debug: "debug"
|
||||
// turn off all logging except for logger1: "off,logger1=debug"
|
||||
// turn off all logging except for logger1 and logger2: "off,logger1=debug,logger2=info"
|
||||
//
|
||||
log_levels extract_levels(const std::string &txt);
|
||||
} // namespace helpers
|
||||
|
||||
} // namespace cfg
|
||||
} // namespace spdlog
|
||||
|
||||
#ifdef SPDLOG_HEADER_ONLY
|
||||
#include "helpers-inl.h"
|
||||
#endif // SPDLOG_HEADER_ONLY
|
47
include/spdlog/cfg/log_levels.h
Normal file
47
include/spdlog/cfg/log_levels.h
Normal file
@ -0,0 +1,47 @@
|
||||
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <spdlog/common.h>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace spdlog {
|
||||
namespace cfg {
|
||||
class log_levels
|
||||
{
|
||||
std::unordered_map<std::string, spdlog::level::level_enum> levels_;
|
||||
spdlog::level::level_enum default_level_ = level::info;
|
||||
|
||||
public:
|
||||
void set(const std::string &logger_name, level::level_enum lvl)
|
||||
{
|
||||
if (logger_name.empty())
|
||||
{
|
||||
default_level_ = lvl;
|
||||
}
|
||||
else
|
||||
{
|
||||
levels_[logger_name] = lvl;
|
||||
}
|
||||
}
|
||||
|
||||
void set_default(level::level_enum lvl)
|
||||
{
|
||||
default_level_ = lvl;
|
||||
}
|
||||
|
||||
level::level_enum get(const std::string &logger_name)
|
||||
{
|
||||
auto it = levels_.find(logger_name);
|
||||
return it != levels_.end() ? it->second : default_level_;
|
||||
}
|
||||
|
||||
level::level_enum default_level()
|
||||
{
|
||||
return default_level_;
|
||||
}
|
||||
};
|
||||
} // namespace cfg
|
||||
} // namespace spdlog
|
@ -34,6 +34,15 @@ SPDLOG_INLINE spdlog::level::level_enum from_str(const std::string &name) SPDLOG
|
||||
}
|
||||
level++;
|
||||
}
|
||||
// check also for "warn" and "err" before giving up..
|
||||
if (name == "warn")
|
||||
{
|
||||
return level::warn;
|
||||
}
|
||||
if (name == "err")
|
||||
{
|
||||
return level::err;
|
||||
}
|
||||
return level::off;
|
||||
}
|
||||
} // namespace level
|
||||
|
@ -530,6 +530,24 @@ SPDLOG_INLINE filename_t dir_name(filename_t path)
|
||||
return pos != filename_t::npos ? path.substr(0, pos) : filename_t{};
|
||||
}
|
||||
|
||||
std::string SPDLOG_INLINE getenv(const char *field)
|
||||
{
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#if defined(__cplusplus_winrt)
|
||||
return std::string{}; // not supported under uwp
|
||||
#else
|
||||
size_t len = 0;
|
||||
char buf[128];
|
||||
bool ok = ::getenv_s(&len, buf, sizeof(buf), field) == 0;
|
||||
return ok ? buf : std::string{};
|
||||
#endif
|
||||
#else // revert to getenv
|
||||
char *buf = ::getenv(field);
|
||||
return buf ? buf : std::string{};
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace os
|
||||
} // namespace details
|
||||
} // namespace spdlog
|
||||
|
@ -98,6 +98,10 @@ filename_t dir_name(filename_t path);
|
||||
// Return true if succeeded or if this dir already exists.
|
||||
bool create_dir(filename_t path);
|
||||
|
||||
// non thread safe, cross platform getenv/getenv_s
|
||||
// return empty string if field not found
|
||||
std::string getenv(const char *field);
|
||||
|
||||
} // namespace os
|
||||
} // namespace details
|
||||
} // namespace spdlog
|
||||
|
@ -64,7 +64,7 @@ SPDLOG_INLINE void registry::initialize_logger(std::shared_ptr<logger> new_logge
|
||||
new_logger->set_error_handler(err_handler_);
|
||||
}
|
||||
|
||||
new_logger->set_level(level_);
|
||||
new_logger->set_level(levels_.get(new_logger->name()));
|
||||
new_logger->flush_on(flush_level_);
|
||||
|
||||
if (backtrace_n_messages_ > 0)
|
||||
@ -168,7 +168,7 @@ SPDLOG_INLINE void registry::set_level(level::level_enum log_level)
|
||||
{
|
||||
l.second->set_level(log_level);
|
||||
}
|
||||
level_ = log_level;
|
||||
levels_.set_default(log_level);
|
||||
}
|
||||
|
||||
SPDLOG_INLINE void registry::flush_on(level::level_enum log_level)
|
||||
@ -260,6 +260,17 @@ SPDLOG_INLINE void registry::set_automatic_registration(bool automatic_registrat
|
||||
automatic_registration_ = automatic_registration;
|
||||
}
|
||||
|
||||
SPDLOG_INLINE void registry::update_levels(cfg::log_levels levels)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(logger_map_mutex_);
|
||||
levels_ = std::move(levels);
|
||||
for (auto &l : loggers_)
|
||||
{
|
||||
auto &logger = l.second;
|
||||
logger->set_level(levels_.get(logger->name()));
|
||||
}
|
||||
}
|
||||
|
||||
SPDLOG_INLINE registry ®istry::instance()
|
||||
{
|
||||
static registry s_instance;
|
||||
@ -280,5 +291,6 @@ SPDLOG_INLINE void registry::register_logger_(std::shared_ptr<logger> new_logger
|
||||
throw_if_exists_(logger_name);
|
||||
loggers_[logger_name] = std::move(new_logger);
|
||||
}
|
||||
|
||||
} // namespace details
|
||||
} // namespace spdlog
|
||||
|
@ -9,6 +9,7 @@
|
||||
// This class is thread safe
|
||||
|
||||
#include <spdlog/common.h>
|
||||
#include <spdlog/cfg/log_levels.h>
|
||||
|
||||
#include <chrono>
|
||||
#include <functional>
|
||||
@ -79,6 +80,8 @@ public:
|
||||
|
||||
void set_automatic_registration(bool automatic_registration);
|
||||
|
||||
void update_levels(cfg::log_levels levels);
|
||||
|
||||
static registry &instance();
|
||||
|
||||
private:
|
||||
@ -90,8 +93,8 @@ private:
|
||||
std::mutex logger_map_mutex_, flusher_mutex_;
|
||||
std::recursive_mutex tp_mutex_;
|
||||
std::unordered_map<std::string, std::shared_ptr<logger>> loggers_;
|
||||
cfg::log_levels levels_;
|
||||
std::unique_ptr<formatter> formatter_;
|
||||
level::level_enum level_ = level::info;
|
||||
level::level_enum flush_level_ = level::off;
|
||||
void (*err_handler_)(const std::string &msg);
|
||||
std::shared_ptr<thread_pool> tp_;
|
||||
|
@ -4,7 +4,7 @@
|
||||
#pragma once
|
||||
|
||||
#define SPDLOG_VER_MAJOR 1
|
||||
#define SPDLOG_VER_MINOR 5
|
||||
#define SPDLOG_VER_MINOR 6
|
||||
#define SPDLOG_VER_PATCH 0
|
||||
|
||||
#define SPDLOG_VERSION (SPDLOG_VER_MAJOR * 10000 + SPDLOG_VER_MINOR * 100 + SPDLOG_VER_PATCH)
|
||||
|
@ -82,7 +82,8 @@ spdlog_srcs = files([
|
||||
'src/color_sinks.cpp',
|
||||
'src/file_sinks.cpp',
|
||||
'src/spdlog.cpp',
|
||||
'src/stdout_sinks.cpp'
|
||||
'src/stdout_sinks.cpp',
|
||||
'src/cfg.cpp'
|
||||
])
|
||||
|
||||
if not get_option('external_fmt')
|
||||
|
@ -5,8 +5,9 @@
|
||||
#error Please define SPDLOG_COMPILED_LIB to compile this file.
|
||||
#endif
|
||||
|
||||
#include "spdlog/async.h"
|
||||
#include "spdlog/async_logger-inl.h"
|
||||
#include "spdlog/details/periodic_worker-inl.h"
|
||||
#include "spdlog/details/thread_pool-inl.h"
|
||||
#include <spdlog/async.h>
|
||||
#include <spdlog/async_logger-inl.h>
|
||||
#include <spdlog/details/periodic_worker-inl.h>
|
||||
#include <spdlog/details/thread_pool-inl.h>
|
||||
|
||||
template class spdlog::details::mpmc_blocking_queue<spdlog::details::async_msg>;
|
8
src/cfg.cpp
Normal file
8
src/cfg.cpp
Normal file
@ -0,0 +1,8 @@
|
||||
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
|
||||
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
|
||||
|
||||
#ifndef SPDLOG_COMPILED_LIB
|
||||
#error Please define SPDLOG_COMPILED_LIB to compile this file.
|
||||
#endif
|
||||
|
||||
#include <spdlog/cfg/helpers-inl.h>
|
@ -7,13 +7,13 @@
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#include "spdlog/details/null_mutex.h"
|
||||
#include "spdlog/async.h"
|
||||
#include <spdlog/details/null_mutex.h>
|
||||
#include <spdlog/async.h>
|
||||
//
|
||||
// color sinks
|
||||
//
|
||||
#ifdef _WIN32
|
||||
#include "spdlog/sinks/wincolor_sink-inl.h"
|
||||
#include <spdlog/sinks/wincolor_sink-inl.h>
|
||||
template class spdlog::sinks::wincolor_sink<spdlog::details::console_mutex>;
|
||||
template class spdlog::sinks::wincolor_sink<spdlog::details::console_nullmutex>;
|
||||
template class spdlog::sinks::wincolor_stdout_sink<spdlog::details::console_mutex>;
|
||||
|
@ -5,14 +5,15 @@
|
||||
#error Please define SPDLOG_COMPILED_LIB to compile this file.
|
||||
#endif
|
||||
|
||||
#include <spdlog/details/null_mutex.h>
|
||||
#include <spdlog/details/file_helper-inl.h>
|
||||
#include <spdlog/sinks/basic_file_sink-inl.h>
|
||||
|
||||
#include <mutex>
|
||||
#include "spdlog/details/null_mutex.h"
|
||||
#include "spdlog/details/file_helper-inl.h"
|
||||
#include "spdlog/sinks/basic_file_sink-inl.h"
|
||||
|
||||
template class spdlog::sinks::basic_file_sink<std::mutex>;
|
||||
template class spdlog::sinks::basic_file_sink<spdlog::details::null_mutex>;
|
||||
|
||||
#include "spdlog/sinks/rotating_file_sink-inl.h"
|
||||
#include <spdlog/sinks/rotating_file_sink-inl.h>
|
||||
template class spdlog::sinks::rotating_file_sink<std::mutex>;
|
||||
template class spdlog::sinks::rotating_file_sink<spdlog::details::null_mutex>;
|
@ -7,7 +7,7 @@
|
||||
// All rights reserved.
|
||||
|
||||
#if !defined(SPDLOG_FMT_EXTERNAL)
|
||||
#include "spdlog/fmt/bundled/format-inl.h"
|
||||
#include <spdlog/fmt/bundled/format-inl.h>
|
||||
|
||||
FMT_BEGIN_NAMESPACE
|
||||
namespace internal {
|
||||
|
@ -5,18 +5,18 @@
|
||||
#error Please define SPDLOG_COMPILED_LIB to compile this file.
|
||||
#endif
|
||||
|
||||
#include "spdlog/spdlog-inl.h"
|
||||
#include "spdlog/common-inl.h"
|
||||
#include "spdlog/details/backtracer-inl.h"
|
||||
#include "spdlog/details/registry-inl.h"
|
||||
#include "spdlog/details/os-inl.h"
|
||||
#include "spdlog/details/pattern_formatter-inl.h"
|
||||
#include "spdlog/details/log_msg-inl.h"
|
||||
#include "spdlog/details/log_msg_buffer-inl.h"
|
||||
#include "spdlog/logger-inl.h"
|
||||
#include "spdlog/sinks/sink-inl.h"
|
||||
#include "spdlog/sinks/base_sink-inl.h"
|
||||
#include "spdlog/details/null_mutex.h"
|
||||
#include <spdlog/spdlog-inl.h>
|
||||
#include <spdlog/common-inl.h>
|
||||
#include <spdlog/details/backtracer-inl.h>
|
||||
#include <spdlog/details/registry-inl.h>
|
||||
#include <spdlog/details/os-inl.h>
|
||||
#include <spdlog/details/pattern_formatter-inl.h>
|
||||
#include <spdlog/details/log_msg-inl.h>
|
||||
#include <spdlog/details/log_msg_buffer-inl.h>
|
||||
#include <spdlog/logger-inl.h>
|
||||
#include <spdlog/sinks/sink-inl.h>
|
||||
#include <spdlog/sinks/base_sink-inl.h>
|
||||
#include <spdlog/details/null_mutex.h>
|
||||
|
||||
#include <mutex>
|
||||
|
||||
|
@ -7,9 +7,9 @@
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#include "spdlog/details/null_mutex.h"
|
||||
#include "spdlog/async.h"
|
||||
#include "spdlog/sinks/stdout_sinks-inl.h"
|
||||
#include <spdlog/details/null_mutex.h>
|
||||
#include <spdlog/async.h>
|
||||
#include <spdlog/sinks/stdout_sinks-inl.h>
|
||||
|
||||
template class spdlog::sinks::stdout_sink_base<spdlog::details::console_mutex>;
|
||||
template class spdlog::sinks::stdout_sink_base<spdlog::details::console_nullmutex>;
|
||||
|
@ -31,7 +31,8 @@ set(SPDLOG_UTESTS_SOURCES
|
||||
test_fmt_helper.cpp
|
||||
test_stdout_api.cpp
|
||||
test_backtrace.cpp
|
||||
test_create_dir.cpp)
|
||||
test_create_dir.cpp
|
||||
test_cfg.cpp)
|
||||
|
||||
if(NOT SPDLOG_NO_EXCEPTIONS)
|
||||
list(APPEND SPDLOG_UTESTS_SOURCES test_errors.cpp)
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <iomanip>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_DEBUG
|
||||
|
||||
|
@ -14,7 +14,8 @@ test_sources = files([
|
||||
'test_fmt_helper.cpp',
|
||||
'test_stdout_api.cpp',
|
||||
'test_backtrace.cpp',
|
||||
'test_create_dir.cpp'
|
||||
'test_create_dir.cpp',
|
||||
'test_cfg.cpp',
|
||||
])
|
||||
|
||||
if not get_option('no_exceptions')
|
||||
|
93
tests/test_cfg.cpp
Normal file
93
tests/test_cfg.cpp
Normal file
@ -0,0 +1,93 @@
|
||||
#include "includes.h"
|
||||
#include "test_sink.h"
|
||||
|
||||
#include <spdlog/cfg/env.h>
|
||||
#include <spdlog/cfg/argv.h>
|
||||
|
||||
using spdlog::cfg::load_argv_levels;
|
||||
using spdlog::cfg::load_env_levels;
|
||||
using spdlog::sinks::test_sink_st;
|
||||
|
||||
TEST_CASE("env", "[cfg]")
|
||||
{
|
||||
spdlog::drop("l1");
|
||||
auto l1 = spdlog::create<test_sink_st>("l1");
|
||||
#ifdef _MSC_VER
|
||||
_putenv_s("SPDLOG_LEVEL", "l1=warn");
|
||||
#else
|
||||
setenv("SPDLOG_LEVEL", "l1=warn", 1);
|
||||
#endif
|
||||
load_env_levels();
|
||||
REQUIRE(l1->level() == spdlog::level::warn);
|
||||
spdlog::set_default_logger(spdlog::create<test_sink_st>("cfg-default"));
|
||||
REQUIRE(spdlog::default_logger()->level() == spdlog::level::info);
|
||||
}
|
||||
|
||||
TEST_CASE("argv1", "[cfg]")
|
||||
{
|
||||
spdlog::drop("l1");
|
||||
const char *argv[] = {"ignore", "SPDLOG_LEVEL=l1=warn"};
|
||||
load_argv_levels(2, const_cast<char **>(argv));
|
||||
auto l1 = spdlog::create<spdlog::sinks::test_sink_st>("l1");
|
||||
REQUIRE(l1->level() == spdlog::level::warn);
|
||||
REQUIRE(spdlog::default_logger()->level() == spdlog::level::info);
|
||||
}
|
||||
|
||||
TEST_CASE("argv2", "[cfg]")
|
||||
{
|
||||
spdlog::drop("l1");
|
||||
const char *argv[] = {"ignore", "SPDLOG_LEVEL=l1=warn,trace"};
|
||||
load_argv_levels(2, const_cast<char **>(argv));
|
||||
auto l1 = spdlog::create<test_sink_st>("l1");
|
||||
REQUIRE(l1->level() == spdlog::level::warn);
|
||||
REQUIRE(spdlog::default_logger()->level() == spdlog::level::trace);
|
||||
spdlog::set_level(spdlog::level::info);
|
||||
}
|
||||
|
||||
TEST_CASE("argv3", "[cfg]")
|
||||
{
|
||||
spdlog::drop("l1");
|
||||
const char *argv[] = {"ignore", "SPDLOG_LEVEL="};
|
||||
load_argv_levels(2, const_cast<char **>(argv));
|
||||
auto l1 = spdlog::create<test_sink_st>("l1");
|
||||
REQUIRE(l1->level() == spdlog::level::info);
|
||||
REQUIRE(spdlog::default_logger()->level() == spdlog::level::info);
|
||||
}
|
||||
|
||||
TEST_CASE("argv4", "[cfg]")
|
||||
{
|
||||
spdlog::drop("l1");
|
||||
const char *argv[] = {"ignore", "SPDLOG_LEVEL=junk"};
|
||||
load_argv_levels(2, const_cast<char **>(argv));
|
||||
auto l1 = spdlog::create<test_sink_st>("l1");
|
||||
REQUIRE(l1->level() == spdlog::level::info);
|
||||
}
|
||||
|
||||
TEST_CASE("argv5", "[cfg]")
|
||||
{
|
||||
spdlog::drop("l1");
|
||||
const char *argv[] = {"ignore", "ignore", "SPDLOG_LEVEL=l1=warn,trace"};
|
||||
load_argv_levels(3, const_cast<char **>(argv));
|
||||
auto l1 = spdlog::create<test_sink_st>("l1");
|
||||
REQUIRE(l1->level() == spdlog::level::warn);
|
||||
REQUIRE(spdlog::default_logger()->level() == spdlog::level::trace);
|
||||
spdlog::set_level(spdlog::level::info);
|
||||
}
|
||||
|
||||
TEST_CASE("argv6", "[cfg]")
|
||||
{
|
||||
spdlog::set_level(spdlog::level::err);
|
||||
const char *argv[] = {""};
|
||||
load_argv_levels(1, const_cast<char **>(argv));
|
||||
REQUIRE(spdlog::default_logger()->level() == spdlog::level::err);
|
||||
spdlog::set_level(spdlog::level::info);
|
||||
}
|
||||
|
||||
TEST_CASE("argv7", "[cfg]")
|
||||
{
|
||||
spdlog::set_level(spdlog::level::err);
|
||||
const char *argv[] = {""};
|
||||
load_argv_levels(0, const_cast<char **>(argv));
|
||||
REQUIRE(spdlog::default_logger()->level() == spdlog::level::err);
|
||||
spdlog::set_level(spdlog::level::info);
|
||||
}
|
@ -72,6 +72,7 @@ TEST_CASE("to_level_enum", "[convert_to_level_enum]")
|
||||
REQUIRE(spdlog::level::from_str("debug") == spdlog::level::debug);
|
||||
REQUIRE(spdlog::level::from_str("info") == spdlog::level::info);
|
||||
REQUIRE(spdlog::level::from_str("warning") == spdlog::level::warn);
|
||||
REQUIRE(spdlog::level::from_str("warn") == spdlog::level::warn);
|
||||
REQUIRE(spdlog::level::from_str("error") == spdlog::level::err);
|
||||
REQUIRE(spdlog::level::from_str("critical") == spdlog::level::critical);
|
||||
REQUIRE(spdlog::level::from_str("off") == spdlog::level::off);
|
||||
|
Loading…
Reference in New Issue
Block a user