1
0
mirror of https://github.com/gabime/spdlog.git synced 2025-01-16 01:37:58 +00:00

Compare commits

...

19 Commits

Author SHA1 Message Date
gabime
69f3d2678e Updated readme. 2020-03-06 15:30:14 +02:00
gabime
8038bc2fc8 Update example 2020-03-06 15:21:21 +02:00
gabime
f20b12cf3f Update example 2020-03-06 15:16:48 +02:00
gabime
c8bd53509c Update example 2020-03-06 15:15:59 +02:00
gabime
006124d816 Update example 2020-03-06 15:15:10 +02:00
gabime
efd73ac956 Merge remote-tracking branch 'origin/v1.x' into conf-env3 2020-03-06 15:10:24 +02:00
gabime
b7d7334451 Renamed level loaders 2020-03-06 15:09:46 +02:00
gabime
8284865f9a Fix tidy warning 2020-03-04 16:21:07 +02:00
gabime
1f8b04cbd1 Fix tidy warning 2020-03-04 16:09:04 +02:00
gabime
b3402a0b9f Fix tidy warning 2020-03-04 16:08:35 +02:00
gabime
4037959945 Fix tidy warning 2020-03-04 15:59:45 +02:00
gabime
d7313a3274 Fix tidy warning 2020-03-04 15:52:42 +02:00
gabime
8302086942 Fixed tcp_client 2020-03-04 15:40:04 +02:00
Gabi Melman
6095db951b
Update README.md 2020-03-04 14:12:56 +02:00
gabime
817d2764b6 Fix bench tidy warning 2020-03-03 23:53:28 +02:00
Gabi Melman
62189602cb
Update README.md 2020-03-03 09:51:56 +02:00
Gabi Melman
0120dcc787
Update logger-inl.h 2020-02-29 13:20:26 +02:00
Gabi Melman
6bfc0ec3a7
Merge pull request #1457 from Ruffel/fix-clang-tidy-warning
Resolve erroneous clang-tidy warning about using a moved from pointer
2020-02-29 13:16:49 +02:00
Steven Cartmell
f999d879d5
fix: Break from loop on last iteration to resolve clang-tidy warning
The clang-tidy warning `clang-analyzer-cplusplus.Move` warns when a
moved from object is deferenced. This is triggered in spdlog because
clang-tidy fails to detect that the `logger:set_formatter` will only
move the unique_ptr on the last iteration of the loop, assuming that
`f->clone` may be called on it afterwards.

To fix, add a break statement after moving the pointer (on the last
iteration) to let clang-tidy know the logger pointer is not used after
this point.
2020-02-28 21:09:31 +00:00
13 changed files with 58 additions and 43 deletions

View File

@ -36,10 +36,10 @@ $ 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.
* Fast asynchronous mode (optional)
* Asynchronous mode (optional)
* [Custom](https://github.com/gabime/spdlog/wiki/3.-Custom-formatting) formatting.
* Multi/Single threaded loggers.
* Various log targets:
@ -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 can be argv or env vars
## Usage samples
@ -85,6 +86,21 @@ int main()
auto file_logger = spdlog::basic_logger_mt("basic_logger", "logs/basic.txt");
spdlog::set_default_logger(file_logger);
}
```
#### load log levels from env variable
```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++
@ -300,15 +316,6 @@ void android_example()
android_logger->critical("Use \"adb shell logcat\" to view this message.");
}
```
---
#### Compile-time format string syntax checking
```C++
#include "spdlog/spdlog.h"
int main()
{
spdlog::info(FMT_STRING("{:d} is an invalid format tag"));
}
```
## Benchmarks

View File

@ -6,6 +6,7 @@
#include <cstdio>
void load_levels_example();
void stdout_logger_example();
void basic_example();
void rotating_example();
@ -23,17 +24,11 @@ void syslog_example();
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);
// Optionally load log levels from the SPDLOG_LEVEL env variable or from argv.
// For example: set the global level to info and mylogger to to trace:
// SPDLOG_LEVEL=info,mylogger=trace && ./example
spdlog::cfg::load_env();
// or from command line: "./example SPDLOG_LEVEL=info,mylogger=trace"
// #include "spdlog/cfg/argv.h" // for loading levels from argv
// spdlog::cfg::load_argv(args, argv);
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);
@ -127,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()
{

View File

@ -21,7 +21,7 @@ namespace spdlog {
namespace cfg {
// search for SPDLOG_LEVEL= in the args and use it to init the levels
void load_argv(int args, char **argv)
void load_argv_levels(int args, char **argv)
{
const std::string spdlog_level_prefix = "SPDLOG_LEVEL=";
for (int i = 1; i < args; i++)

View File

@ -25,7 +25,7 @@
namespace spdlog {
namespace cfg {
void load_env()
void load_env_levels()
{
auto env_val = details::os::getenv("SPDLOG_LEVEL");
auto levels = helpers::extract_levels(env_val);

View File

@ -390,13 +390,13 @@ SPDLOG_INLINE int pid() SPDLOG_NOEXCEPT
}
// Determine if the terminal supports colors
// Source: https://github.com/agauniyal/rang/
// Based on: https://github.com/agauniyal/rang/
SPDLOG_INLINE bool is_color_terminal() SPDLOG_NOEXCEPT
{
#ifdef _WIN32
return true;
#else
static constexpr std::array<const char *, 14> Terms = {
static constexpr std::array<const char *, 14> terms = {
{"ansi", "color", "console", "cygwin", "gnome", "konsole", "kterm", "linux", "msys", "putty", "rxvt", "screen", "vt100", "xterm"}};
const char *env_p = std::getenv("TERM");
@ -406,7 +406,7 @@ SPDLOG_INLINE bool is_color_terminal() SPDLOG_NOEXCEPT
}
static const bool result =
std::any_of(std::begin(Terms), std::end(Terms), [&](const char *term) { return std::strstr(env_p, term) != nullptr; });
std::any_of(terms.begin(), terms.end(), [&](const char *term) { return std::strstr(env_p, term) != nullptr; });
return result;
#endif
}

View File

@ -92,7 +92,7 @@ private:
// Extract given pad spec (e.g. %8X)
// Advance the given it pass the end of the padding spec found (if any)
// Return padding.
details::padding_info handle_padspec_(std::string::const_iterator &it, std::string::const_iterator end);
static details::padding_info handle_padspec_(std::string::const_iterator &it, std::string::const_iterator end);
void compile_pattern_(const std::string &pattern);
};

View File

@ -184,7 +184,7 @@ SPDLOG_INLINE void registry::flush_on(level::level_enum log_level)
SPDLOG_INLINE void registry::flush_every(std::chrono::seconds interval)
{
std::lock_guard<std::mutex> lock(flusher_mutex_);
std::function<void()> clbk = std::bind(&registry::flush_all, this);
auto clbk = [this](){this->flush_all();};
periodic_flusher_ = details::make_unique<periodic_worker>(clbk, interval);
}

View File

@ -54,8 +54,8 @@ public:
void connect(const std::string &host, int port)
{
close();
spdlog::info("Connecting..");
struct addrinfo hints{};
struct addrinfo hints
{};
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_INET; // IPv4
hints.ai_socktype = SOCK_STREAM; // TCP

View File

@ -113,7 +113,7 @@ bool SPDLOG_INLINE thread_pool::process_next_msg_()
}
default: {
assert(false && "Unexpected async_msg_type");
assert(false);
}
}

View File

@ -89,6 +89,7 @@ SPDLOG_INLINE void logger::set_formatter(std::unique_ptr<formatter> f)
{
// last element - we can be move it.
(*it)->set_formatter(std::move(f));
break; // to prevent clang-tidy warning
}
else
{

View File

@ -73,7 +73,7 @@ struct win32_error : public spdlog_ex
return fmt::format("{}: {}{}", user_message, error_code, system_message);
}
win32_error(std::string const &func_name, DWORD error = GetLastError())
explicit win32_error(std::string const &func_name, DWORD error = GetLastError())
: spdlog_ex(format(func_name, error))
{}
};

View File

@ -4,8 +4,8 @@
#include <spdlog/cfg/env.h>
#include <spdlog/cfg/argv.h>
using spdlog::cfg::load_argv;
using spdlog::cfg::load_env;
using spdlog::cfg::load_argv_levels;
using spdlog::cfg::load_env_levels;
using spdlog::sinks::test_sink_st;
TEST_CASE("env", "[cfg]")
@ -17,7 +17,7 @@ TEST_CASE("env", "[cfg]")
#else
setenv("SPDLOG_LEVEL", "l1=warn", 1);
#endif
load_env();
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);
@ -27,7 +27,7 @@ TEST_CASE("argv1", "[cfg]")
{
spdlog::drop("l1");
const char *argv[] = {"ignore", "SPDLOG_LEVEL=l1=warn"};
load_argv(2, const_cast<char**>(argv));
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);
@ -37,7 +37,7 @@ TEST_CASE("argv2", "[cfg]")
{
spdlog::drop("l1");
const char *argv[] = {"ignore", "SPDLOG_LEVEL=l1=warn,trace"};
load_argv(2, const_cast<char**>(argv));
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);
@ -48,7 +48,7 @@ TEST_CASE("argv3", "[cfg]")
{
spdlog::drop("l1");
const char *argv[] = {"ignore", "SPDLOG_LEVEL="};
load_argv(2, const_cast<char**>(argv));
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);
@ -58,7 +58,7 @@ TEST_CASE("argv4", "[cfg]")
{
spdlog::drop("l1");
const char *argv[] = {"ignore", "SPDLOG_LEVEL=junk"};
load_argv(2, const_cast<char**>(argv));
load_argv_levels(2, const_cast<char **>(argv));
auto l1 = spdlog::create<test_sink_st>("l1");
REQUIRE(l1->level() == spdlog::level::info);
}
@ -67,7 +67,7 @@ TEST_CASE("argv5", "[cfg]")
{
spdlog::drop("l1");
const char *argv[] = {"ignore", "ignore", "SPDLOG_LEVEL=l1=warn,trace"};
load_argv(3, const_cast<char**>(argv));
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);
@ -78,7 +78,7 @@ TEST_CASE("argv6", "[cfg]")
{
spdlog::set_level(spdlog::level::err);
const char *argv[] = {""};
load_argv(1, const_cast<char**>(argv));
load_argv_levels(1, const_cast<char **>(argv));
REQUIRE(spdlog::default_logger()->level() == spdlog::level::err);
spdlog::set_level(spdlog::level::info);
}
@ -87,7 +87,7 @@ TEST_CASE("argv7", "[cfg]")
{
spdlog::set_level(spdlog::level::err);
const char *argv[] = {""};
load_argv(0, const_cast<char**>(argv));
load_argv_levels(0, const_cast<char **>(argv));
REQUIRE(spdlog::default_logger()->level() == spdlog::level::err);
spdlog::set_level(spdlog::level::info);
}

View File

@ -9,7 +9,7 @@ class failing_sink : public spdlog::sinks::base_sink<std::mutex>
{
public:
failing_sink() = default;
~failing_sink() final = default;
~failing_sink() = default;
protected:
void sink_it_(const spdlog::details::log_msg &) final