mirror of
https://github.com/gabime/spdlog.git
synced 2025-09-29 01:29:35 +08:00
Compare commits
14 Commits
v1.15.3
...
fix-warnin
Author | SHA1 | Date | |
---|---|---|---|
![]() |
1d418eef5a | ||
![]() |
4a4acc31e6 | ||
![]() |
7c155b99c1 | ||
![]() |
e1d4ed9cef | ||
![]() |
9926fd8ff8 | ||
![]() |
6c174aa5b7 | ||
![]() |
a9e09baeec | ||
![]() |
13fbf73a70 | ||
![]() |
2d761504a3 | ||
![]() |
f9bf4511bf | ||
![]() |
37e24d6970 | ||
![]() |
de127876c7 | ||
![]() |
b0620c8523 | ||
![]() |
677a2d93e6 |
51
.github/workflows/coverity_scan.yml
vendored
Normal file
51
.github/workflows/coverity_scan.yml
vendored
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
name: coverity-linux
|
||||||
|
|
||||||
|
on: [pull_request]
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
coverity_scan:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
name: Coverity Scan
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y curl build-essential cmake pkg-config libsystemd-dev
|
||||||
|
|
||||||
|
- name: Download Coverity Tool
|
||||||
|
run: |
|
||||||
|
curl -s -L --output coverity_tool.tgz "https://scan.coverity.com/download/linux64?token=${{ secrets.COVERITY_TOKEN }}&project=gabime%2Fspdlog"
|
||||||
|
mkdir coverity_tool
|
||||||
|
tar -C coverity_tool --strip-components=1 -xf coverity_tool.tgz
|
||||||
|
echo "$PWD/coverity_tool/bin" >> $GITHUB_PATH
|
||||||
|
|
||||||
|
- name: Build with Coverity
|
||||||
|
run: |
|
||||||
|
mkdir build && cd build
|
||||||
|
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_STANDARD=17
|
||||||
|
cd ..
|
||||||
|
cov-build --dir cov-int make -C build -j4
|
||||||
|
|
||||||
|
- name: Submit results to Coverity
|
||||||
|
run: |
|
||||||
|
tar czf cov-int.tgz cov-int
|
||||||
|
response=$(curl --silent --show-error --fail \
|
||||||
|
--form token="${{ secrets.COVERITY_TOKEN }}" \
|
||||||
|
--form file=@cov-int.tgz \
|
||||||
|
--form version="GitHub PR #${{ github.event.pull_request.number }}" \
|
||||||
|
--form description="CI run for PR" \
|
||||||
|
https://scan.coverity.com/builds?project=gabime%2Fspdlog)
|
||||||
|
|
||||||
|
echo "$response"
|
||||||
|
|
||||||
|
if echo "$response" | grep -qi "Build successfully submitted"; then
|
||||||
|
echo "Coverity upload succeeded"
|
||||||
|
else
|
||||||
|
echo "Coverity upload failed or was rejected"
|
||||||
|
exit 1
|
||||||
|
fi
|
@@ -33,41 +33,41 @@ void mdc_example();
|
|||||||
#include "spdlog/fmt/ostr.h" // support for user defined types
|
#include "spdlog/fmt/ostr.h" // support for user defined types
|
||||||
|
|
||||||
int main(int, char *[]) {
|
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);
|
|
||||||
spdlog::info("Positional args are {1} {0}..", "too", "supported");
|
|
||||||
spdlog::info("{:>8} aligned, {:<8} aligned", "right", "left");
|
|
||||||
|
|
||||||
// Runtime log levels
|
|
||||||
spdlog::set_level(spdlog::level::info); // Set global log level to info
|
|
||||||
spdlog::debug("This message should not be displayed!");
|
|
||||||
spdlog::set_level(spdlog::level::trace); // Set specific logger's log level
|
|
||||||
spdlog::debug("This message should be displayed..");
|
|
||||||
|
|
||||||
// Customize msg format for all loggers
|
|
||||||
spdlog::set_pattern("[%H:%M:%S %z] [%^%L%$] [thread %t] %v");
|
|
||||||
spdlog::info("This an info message with custom format");
|
|
||||||
spdlog::set_pattern("%+"); // back to default format
|
|
||||||
spdlog::set_level(spdlog::level::info);
|
|
||||||
|
|
||||||
// Backtrace support
|
|
||||||
// Loggers can store in a ring buffer all messages (including debug/trace) for later inspection.
|
|
||||||
// When needed, call dump_backtrace() to see what happened:
|
|
||||||
spdlog::enable_backtrace(10); // create ring buffer with capacity of 10 messages
|
|
||||||
for (int i = 0; i < 100; i++) {
|
|
||||||
spdlog::debug("Backtrace message {}", i); // not logged..
|
|
||||||
}
|
|
||||||
// e.g. if some error happened:
|
|
||||||
spdlog::dump_backtrace(); // log them now!
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// 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);
|
||||||
|
spdlog::info("Positional args are {1} {0}..", "too", "supported");
|
||||||
|
spdlog::info("{:>8} aligned, {:<8} aligned", "right", "left");
|
||||||
|
|
||||||
|
// Runtime log levels
|
||||||
|
spdlog::set_level(spdlog::level::info); // Set global log level to info
|
||||||
|
spdlog::debug("This message should not be displayed!");
|
||||||
|
spdlog::set_level(spdlog::level::trace); // Set specific logger's log level
|
||||||
|
spdlog::debug("This message should be displayed..");
|
||||||
|
|
||||||
|
// Customize msg format for all loggers
|
||||||
|
spdlog::set_pattern("[%H:%M:%S %z] [%^%L%$] [thread %t] %v");
|
||||||
|
spdlog::info("This an info message with custom format");
|
||||||
|
spdlog::set_pattern("%+"); // back to default format
|
||||||
|
spdlog::set_level(spdlog::level::info);
|
||||||
|
|
||||||
|
// Backtrace support
|
||||||
|
// Loggers can store in a ring buffer all messages (including debug/trace) for later
|
||||||
|
// inspection. When needed, call dump_backtrace() to see what happened:
|
||||||
|
spdlog::enable_backtrace(10); // create ring buffer with capacity of 10 messages
|
||||||
|
for (int i = 0; i < 100; i++) {
|
||||||
|
spdlog::debug("Backtrace message {}", i); // not logged..
|
||||||
|
}
|
||||||
|
// e.g. if some error happened:
|
||||||
|
spdlog::dump_backtrace(); // log them now!
|
||||||
|
|
||||||
stdout_logger_example();
|
stdout_logger_example();
|
||||||
basic_example();
|
basic_example();
|
||||||
rotating_example();
|
rotating_example();
|
||||||
@@ -371,15 +371,13 @@ void replace_default_logger_example() {
|
|||||||
// store the old logger so we don't break other examples.
|
// store the old logger so we don't break other examples.
|
||||||
auto old_logger = spdlog::default_logger();
|
auto old_logger = spdlog::default_logger();
|
||||||
|
|
||||||
auto new_logger =
|
auto new_logger = spdlog::basic_logger_mt("new_default_logger", "logs/somelog.txt", true);
|
||||||
spdlog::basic_logger_mt("new_default_logger", "logs/new-default-log.txt", true);
|
spdlog::set_default_logger(std::move(new_logger));
|
||||||
spdlog::set_default_logger(new_logger);
|
|
||||||
spdlog::set_level(spdlog::level::info);
|
spdlog::set_level(spdlog::level::info);
|
||||||
spdlog::debug("This message should not be displayed!");
|
spdlog::debug("This message should not be displayed!");
|
||||||
spdlog::set_level(spdlog::level::trace);
|
spdlog::set_level(spdlog::level::trace);
|
||||||
spdlog::debug("This message should be displayed..");
|
spdlog::debug("This message should be displayed..");
|
||||||
|
spdlog::set_default_logger(std::move(old_logger));
|
||||||
spdlog::set_default_logger(old_logger);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mapped Diagnostic Context (MDC) is a map that stores key-value pairs (string values) in thread
|
// Mapped Diagnostic Context (MDC) is a map that stores key-value pairs (string values) in thread
|
||||||
|
@@ -9,7 +9,6 @@
|
|||||||
|
|
||||||
#include <spdlog/details/os.h>
|
#include <spdlog/details/os.h>
|
||||||
#include <spdlog/details/registry.h>
|
#include <spdlog/details/registry.h>
|
||||||
#include <spdlog/spdlog.h>
|
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
@@ -36,7 +35,7 @@ inline std::string &trim_(std::string &str) {
|
|||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
// return (name,value) trimmed pair from given "name=value" string.
|
// return (name,value) trimmed pair from the given "name = value" string.
|
||||||
// return empty string on missing parts
|
// return empty string on missing parts
|
||||||
// "key=val" => ("key", "val")
|
// "key=val" => ("key", "val")
|
||||||
// " key = val " => ("key", "val")
|
// " key = val " => ("key", "val")
|
||||||
@@ -55,7 +54,7 @@ inline std::pair<std::string, std::string> extract_kv_(char sep, const std::stri
|
|||||||
return std::make_pair(trim_(k), trim_(v));
|
return std::make_pair(trim_(k), trim_(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
// return vector of key/value pairs from sequence of "K1=V1,K2=V2,.."
|
// return vector of key/value pairs from a sequence of "K1=V1,K2=V2,.."
|
||||||
// "a=AAA,b=BBB,c=CCC,.." => {("a","AAA"),("b","BBB"),("c", "CCC"),...}
|
// "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) {
|
inline std::unordered_map<std::string, std::string> extract_key_vals_(const std::string &str) {
|
||||||
std::string token;
|
std::string token;
|
||||||
@@ -82,14 +81,14 @@ SPDLOG_INLINE void load_levels(const std::string &input) {
|
|||||||
bool global_level_found = false;
|
bool global_level_found = false;
|
||||||
|
|
||||||
for (auto &name_level : key_vals) {
|
for (auto &name_level : key_vals) {
|
||||||
auto &logger_name = name_level.first;
|
const auto &logger_name = name_level.first;
|
||||||
auto level_name = to_lower_(name_level.second);
|
const auto &level_name = to_lower_(name_level.second);
|
||||||
auto level = level::from_str(level_name);
|
auto level = level::from_str(level_name);
|
||||||
// ignore unrecognized level names
|
// ignore unrecognized level names
|
||||||
if (level == level::off && level_name != "off") {
|
if (level == level::off && level_name != "off") {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (logger_name.empty()) // no logger name indicate global level
|
if (logger_name.empty()) // no logger name indicates global level
|
||||||
{
|
{
|
||||||
global_level_found = true;
|
global_level_found = true;
|
||||||
global_level = level;
|
global_level = level;
|
||||||
|
@@ -11,10 +11,8 @@
|
|||||||
#include <spdlog/details/os.h>
|
#include <spdlog/details/os.h>
|
||||||
|
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
#include <chrono>
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <thread>
|
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
|
||||||
namespace spdlog {
|
namespace spdlog {
|
||||||
|
@@ -101,7 +101,7 @@ SPDLOG_INLINE std::shared_ptr<logger> registry::default_logger() {
|
|||||||
SPDLOG_INLINE logger *registry::get_default_raw() { return default_logger_.get(); }
|
SPDLOG_INLINE logger *registry::get_default_raw() { return default_logger_.get(); }
|
||||||
|
|
||||||
// set default logger.
|
// set default logger.
|
||||||
// default logger is stored in default_logger_ (for faster retrieval) and in the loggers_ map.
|
// the default logger is stored in default_logger_ (for faster retrieval) and in the loggers_ map.
|
||||||
SPDLOG_INLINE void registry::set_default_logger(std::shared_ptr<logger> new_default_logger) {
|
SPDLOG_INLINE void registry::set_default_logger(std::shared_ptr<logger> new_default_logger) {
|
||||||
std::lock_guard<std::mutex> lock(logger_map_mutex_);
|
std::lock_guard<std::mutex> lock(logger_map_mutex_);
|
||||||
if (new_default_logger != nullptr) {
|
if (new_default_logger != nullptr) {
|
||||||
|
@@ -35,7 +35,7 @@ SPDLOG_INLINE thread_pool::thread_pool(size_t q_max_items,
|
|||||||
SPDLOG_INLINE thread_pool::thread_pool(size_t q_max_items,
|
SPDLOG_INLINE thread_pool::thread_pool(size_t q_max_items,
|
||||||
size_t threads_n,
|
size_t threads_n,
|
||||||
std::function<void()> on_thread_start)
|
std::function<void()> on_thread_start)
|
||||||
: thread_pool(q_max_items, threads_n, on_thread_start, [] {}) {}
|
: thread_pool(q_max_items, threads_n, std::move(on_thread_start), [] {}) {}
|
||||||
|
|
||||||
SPDLOG_INLINE thread_pool::thread_pool(size_t q_max_items, size_t threads_n)
|
SPDLOG_INLINE thread_pool::thread_pool(size_t q_max_items, size_t threads_n)
|
||||||
: thread_pool(q_max_items, threads_n, [] {}, [] {}) {}
|
: thread_pool(q_max_items, threads_n, [] {}, [] {}) {}
|
||||||
@@ -94,8 +94,7 @@ void SPDLOG_INLINE thread_pool::worker_loop_() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// process next message in the queue
|
// process next message in the queue
|
||||||
// return true if this thread should still be active (while no terminate msg
|
// returns true if this thread should still be active (while no terminated msg was received)
|
||||||
// was received)
|
|
||||||
bool SPDLOG_INLINE thread_pool::process_next_msg_() {
|
bool SPDLOG_INLINE thread_pool::process_next_msg_() {
|
||||||
async_msg incoming_async_msg;
|
async_msg incoming_async_msg;
|
||||||
q_.dequeue(incoming_async_msg);
|
q_.dequeue(incoming_async_msg);
|
||||||
|
@@ -57,7 +57,7 @@ SPDLOG_INLINE void logger::swap(spdlog::logger &other) SPDLOG_NOEXCEPT {
|
|||||||
std::swap(tracer_, other.tracer_);
|
std::swap(tracer_, other.tracer_);
|
||||||
}
|
}
|
||||||
|
|
||||||
SPDLOG_INLINE void swap(logger &a, logger &b) { a.swap(b); }
|
SPDLOG_INLINE void swap(logger &a, logger &b) noexcept { a.swap(b); }
|
||||||
|
|
||||||
SPDLOG_INLINE void logger::set_level(level::level_enum log_level) { level_.store(log_level); }
|
SPDLOG_INLINE void logger::set_level(level::level_enum log_level) { level_.store(log_level); }
|
||||||
|
|
||||||
@@ -163,12 +163,12 @@ SPDLOG_INLINE void logger::dump_backtrace_() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SPDLOG_INLINE bool logger::should_flush_(const details::log_msg &msg) {
|
SPDLOG_INLINE bool logger::should_flush_(const details::log_msg &msg) const {
|
||||||
auto flush_level = flush_level_.load(std::memory_order_relaxed);
|
auto flush_level = flush_level_.load(std::memory_order_relaxed);
|
||||||
return (msg.level >= flush_level) && (msg.level != level::off);
|
return (msg.level >= flush_level) && (msg.level != level::off);
|
||||||
}
|
}
|
||||||
|
|
||||||
SPDLOG_INLINE void logger::err_handler_(const std::string &msg) {
|
SPDLOG_INLINE void logger::err_handler_(const std::string &msg) const {
|
||||||
if (custom_err_handler_) {
|
if (custom_err_handler_) {
|
||||||
custom_err_handler_(msg);
|
custom_err_handler_(msg);
|
||||||
} else {
|
} else {
|
||||||
|
@@ -363,14 +363,14 @@ protected:
|
|||||||
virtual void sink_it_(const details::log_msg &msg);
|
virtual void sink_it_(const details::log_msg &msg);
|
||||||
virtual void flush_();
|
virtual void flush_();
|
||||||
void dump_backtrace_();
|
void dump_backtrace_();
|
||||||
bool should_flush_(const details::log_msg &msg);
|
bool should_flush_(const details::log_msg &msg) const;
|
||||||
|
|
||||||
// handle errors during logging.
|
// handle errors during logging.
|
||||||
// default handler prints the error to stderr at max rate of 1 message/sec.
|
// default handler prints the error to stderr at max rate of 1 message/sec.
|
||||||
void err_handler_(const std::string &msg);
|
void err_handler_(const std::string &msg) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
void swap(logger &a, logger &b);
|
void swap(logger &a, logger &b) noexcept;
|
||||||
|
|
||||||
} // namespace spdlog
|
} // namespace spdlog
|
||||||
|
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
TEST_CASE("stopwatch1", "[stopwatch]") {
|
TEST_CASE("stopwatch1", "[stopwatch]") {
|
||||||
using std::chrono::milliseconds;
|
using std::chrono::milliseconds;
|
||||||
using clock = std::chrono::steady_clock;
|
using clock = std::chrono::steady_clock;
|
||||||
milliseconds wait_ms(200);
|
milliseconds wait_ms(500);
|
||||||
milliseconds tolerance_ms(250);
|
milliseconds tolerance_ms(250);
|
||||||
auto start = clock::now();
|
auto start = clock::now();
|
||||||
spdlog::stopwatch sw;
|
spdlog::stopwatch sw;
|
||||||
@@ -22,7 +22,7 @@ TEST_CASE("stopwatch2", "[stopwatch]") {
|
|||||||
using std::chrono::milliseconds;
|
using std::chrono::milliseconds;
|
||||||
using clock = std::chrono::steady_clock;
|
using clock = std::chrono::steady_clock;
|
||||||
|
|
||||||
clock::duration wait_duration(milliseconds(200));
|
clock::duration wait_duration(milliseconds(500));
|
||||||
clock::duration tolerance_duration(milliseconds(250));
|
clock::duration tolerance_duration(milliseconds(250));
|
||||||
|
|
||||||
auto test_sink = std::make_shared<test_sink_st>();
|
auto test_sink = std::make_shared<test_sink_st>();
|
||||||
|
Reference in New Issue
Block a user