pull/230/merge
Kevin Godby 9 years ago committed by GitHub
commit 38388635e0

@ -13,6 +13,7 @@
void async_example();
void syslog_example();
void test_custom_error_handler();
namespace spd = spdlog;
int main(int, char*[])
@ -68,6 +69,7 @@ int main(int, char*[])
// syslog example. linux/osx only..
syslog_example();
test_custom_error_handler();
// Release and close all loggers
spdlog::drop_all();
@ -101,6 +103,31 @@ void syslog_example()
#endif
}
// Example of user-provided error handler
void test_custom_error_handler()
{
// Trigger default error handler
try {
spd::error("test default error handler (throw an exception)");
} catch (const spd::spdlog_ex& e) {
std::cerr << "caught spdlog_ex: " << e.what() << std::endl;
}
// Set custom error handler
spd::set_error_handler(
[](const std::string& message) {
std::cerr << "SPDLOG ERROR " << message << std::endl;
}
);
// Trigger custom error handler
try {
spd::error("test custom error handler");
} catch (const spd::spdlog_ex& e) {
std::cerr << "caught spdlog_ex: " << e.what() << std::endl;
}
}
// Example of user defined class with operator<<
class some_class {};

@ -12,7 +12,7 @@
// Upon each log write the logger:
// 1. Checks if its log level is enough to log the message
// 2. Push a new copy of the message to a queue (or block the caller until space is available in the queue)
// 3. will throw spdlog_ex upon log exceptions
// 3. will call error handler upon log exceptions (which, by default, will throw spdlog_ex exception)
// Upon destruction, logs all remaining messages in the queue before destructing..
#include <spdlog/common.h>

@ -15,6 +15,7 @@
#include <codecvt>
#include <locale>
#endif
#include <functional>
#include <spdlog/details/null_mutex.h>
@ -107,6 +108,32 @@ private:
};
// Function pointer to error handler. Defaults to throwing a spdlog_ex
// exception. May be overridden by the user with set_error_handler().
static std::function<void(const std::string&)> error_handler = [](const std::string& message) {
throw spdlog_ex(message);
};
// Call the user-provided error handler when an internal spdlog error occurs.
inline void error(const std::string& message)
{
error_handler(message);
}
// Set an error handler to be called in case of errors during logging (e.g.,
// can't write to file because the disk is full). Defaults to an error handler
// which logs the errors to the console.
//
// Function must have the following signature (but can be named whatever you
// like):
//
// void error_handler(const std::string &message);
//
inline void set_error_handler(std::function<void(const std::string&)> func)
{
error_handler = func;
}
//
// wchar support for windows file names (SPDLOG_WCHAR_FILENAMES must be defined)
//

@ -8,10 +8,11 @@
// Helper class for file sink
// When failing to open a file, retry several times(5) with small delay between the tries(10 ms)
// Can be set to auto flush on every line
// Throw spdlog_ex exception on errors
// Call error handler on errors (default: throw spdlog_ex)
#include <spdlog/details/os.h>
#include <spdlog/details/log_msg.h>
#include <spdlog/common.h>
#include <chrono>
#include <cstdio>
@ -58,13 +59,15 @@ public:
std::this_thread::sleep_for(std::chrono::milliseconds(open_interval));
}
throw spdlog_ex("Failed opening file " + os::filename_to_str(_filename) + " for writing");
error("Failed opening file " + os::filename_to_str(_filename) + " for writing");
}
void reopen(bool truncate)
{
if (_filename.empty())
throw spdlog_ex("Failed re opening file - was not opened before");
if (_filename.empty()) {
error("Failed re opening file - was not opened before");
return;
}
open(_filename, truncate);
}
@ -88,8 +91,10 @@ public:
size_t msg_size = msg.formatted.size();
auto data = msg.formatted.data();
if (std::fwrite(data, 1, msg_size, _fd) != msg_size)
throw spdlog_ex("Failed writing to file " + os::filename_to_str(_filename));
if (std::fwrite(data, 1, msg_size, _fd) != msg_size) {
error("Failed writing to file " + os::filename_to_str(_filename));
return;
}
if (_force_flush)
std::fflush(_fd);
@ -97,20 +102,26 @@ public:
long size()
{
if (!_fd)
throw spdlog_ex("Cannot use size() on closed file " + os::filename_to_str(_filename));
if (!_fd) {
error("Cannot use size() on closed file " + os::filename_to_str(_filename));
return -1;
}
auto pos = ftell(_fd);
if (fseek(_fd, 0, SEEK_END) != 0)
throw spdlog_ex("fseek failed on file " + os::filename_to_str(_filename));
error("fseek failed on file " + os::filename_to_str(_filename));
auto file_size = ftell(_fd);
if(fseek(_fd, pos, SEEK_SET) !=0)
throw spdlog_ex("fseek failed on file " + os::filename_to_str(_filename));
if(fseek(_fd, pos, SEEK_SET) !=0) {
error("fseek failed on file " + os::filename_to_str(_filename));
return -1;
}
if (file_size == -1)
throw spdlog_ex("ftell failed on file " + os::filename_to_str(_filename));
if (file_size == -1) {
error("ftell failed on file " + os::filename_to_str(_filename));
return -1;
}
return file_size;
}

@ -70,7 +70,7 @@ inline void spdlog::details::line_logger::write(const char* fmt, const Args&...
}
catch (const fmt::FormatError& e)
{
throw spdlog_ex(fmt::format("formatting error while processing format string '{}': {}", fmt, e.what()));
error(fmt::format("formatting error while processing format string '{}': {}", fmt, e.what()));
}
}

@ -64,8 +64,11 @@ public:
buffer_mask_(buffer_size - 1)
{
//queue size must be power of two
if(!((buffer_size >= 2) && ((buffer_size & (buffer_size - 1)) == 0)))
if(!((buffer_size >= 2) && ((buffer_size & (buffer_size - 1)) == 0))) {
// FIXME: call error() instead
// FIXME: can we just round buffer_size down to the next power of two and skip the error altogether?
throw spdlog_ex("async logger queue size must be power of two");
}
for (size_t i = 0; i != buffer_size; i += 1)
buffer_[i].sequence_.store(i, std::memory_order_relaxed);

@ -198,8 +198,10 @@ inline int utc_minutes_offset(const std::tm& tm = details::os::localtime())
DYNAMIC_TIME_ZONE_INFORMATION tzinfo;
auto rv = GetDynamicTimeZoneInformation(&tzinfo);
#endif
if (rv == TIME_ZONE_ID_INVALID)
throw spdlog::spdlog_ex("Failed getting timezone info. Last error: " + std::to_string(GetLastError()));
if (rv == TIME_ZONE_ID_INVALID) {
error("Failed getting timezone info. Last error: " + std::to_string(GetLastError()));
return 0;
}
int offset = -tzinfo.Bias;
if (tm.tm_isdst)

@ -9,6 +9,7 @@
#include <spdlog/details/log_msg.h>
#include <spdlog/details/os.h>
#include <spdlog/details/format.h>
#include <spdlog/common.h>
#include <chrono>
#include <ctime>
@ -623,6 +624,6 @@ inline void spdlog::pattern_formatter::format(details::log_msg& msg)
}
catch(const fmt::FormatError& e)
{
throw spdlog_ex(fmt::format("formatting error while processing format string: {}", e.what()));
error(fmt::format("formatting error while processing format string: {}", e.what()));
}
}

@ -34,7 +34,7 @@ public:
{
std::lock_guard<Mutex> lock(_mutex);
auto logger_name = logger->name();
throw_if_exists(logger_name);
error_if_exists(logger_name);
_loggers[logger_name] = logger;
}
@ -50,7 +50,7 @@ public:
std::shared_ptr<logger> create(const std::string& logger_name, const It& sinks_begin, const It& sinks_end)
{
std::lock_guard<Mutex> lock(_mutex);
throw_if_exists(logger_name);
error_if_exists(logger_name);
std::shared_ptr<logger> new_logger;
if (_async_mode)
new_logger = std::make_shared<async_logger>(logger_name, sinks_begin, sinks_end, _async_q_size, _overflow_policy, _worker_warmup_cb, _flush_interval_ms, _worker_teardown_cb);
@ -140,10 +140,10 @@ private:
registry_t<Mutex>(const registry_t<Mutex>&) = delete;
registry_t<Mutex>& operator=(const registry_t<Mutex>&) = delete;
void throw_if_exists(const std::string &logger_name)
void error_if_exists(const std::string &logger_name)
{
if (_loggers.find(logger_name) != _loggers.end())
throw spdlog_ex("logger with name '" + logger_name + "' already exists");
error("logger with name '" + logger_name + "' already exists");
}
Mutex _mutex;
std::unordered_map <std::string, std::shared_ptr<logger>> _loggers;
@ -155,6 +155,7 @@ private:
std::function<void()> _worker_warmup_cb = nullptr;
std::chrono::milliseconds _flush_interval_ms;
std::function<void()> _worker_teardown_cb = nullptr;
std::function<void(std::string)> _error_handler = [](const std::string& message) { throw spdlog_ex(message); };
};
#ifdef SPDLOG_NO_REGISTRY_MUTEX
typedef registry_t<spdlog::details::null_mutex> registry;

@ -151,3 +151,4 @@ inline void spdlog::drop_all()
{
details::registry::instance().drop_all();
}

@ -9,6 +9,7 @@
#include <spdlog/sinks/base_sink.h>
#include <spdlog/details/null_mutex.h>
#include <spdlog/common.h>
#include <android/log.h>
@ -48,7 +49,7 @@ protected:
}
else
{
throw spdlog_ex("Send to Android logcat failed");
error("Send to Android logcat failed");
}
}
@ -76,7 +77,8 @@ private:
case spdlog::level::emerg:
return ANDROID_LOG_FATAL;
default:
throw spdlog_ex("Incorrect level value");
error("Incorrect level value");
return ANDROID_LOG_INFO;
}
}

@ -9,6 +9,7 @@
#include <spdlog/details/null_mutex.h>
#include <spdlog/details/file_helper.h>
#include <spdlog/details/format.h>
#include <spdlog/common.h>
#include <algorithm>
#include <chrono>
@ -119,12 +120,14 @@ private:
{
if (details::os::remove(target) != 0)
{
throw spdlog_ex("rotating_file_sink: failed removing " + filename_to_str(target));
error("rotating_file_sink: failed removing " + filename_to_str(target));
return;
}
}
if (details::file_helper::file_exists(src) && details::os::rename(src, target))
{
throw spdlog_ex("rotating_file_sink: failed renaming " + filename_to_str(src) + " to " + filename_to_str(target));
error("rotating_file_sink: failed renaming " + filename_to_str(src) + " to " + filename_to_str(target));
return;
}
}
_file_helper.reopen(true);
@ -189,8 +192,16 @@ public:
_rotation_m(rotation_minute),
_file_helper(force_flush)
{
if (rotation_hour < 0 || rotation_hour > 23 || rotation_minute < 0 || rotation_minute > 59)
throw spdlog_ex("daily_file_sink: Invalid rotation time in ctor");
if (rotation_hour < 0 || rotation_hour > 23) {
error("daily_file_sink: Invalid rotation hour (" + std::to_string(rotation_hour) + "). Must be between 0 and 23.");
rotation_hour = 0;
}
if (rotation_minute < 0 || rotation_minute > 59) {
error("daily_file_sink: Invalid rotation minute (" + std::to_string(rotation_minute) + "). Must be between 0 and 59.");
rotation_minute = 0;
}
_rotation_tp = _next_rotation_tp();
_file_helper.open(FileNameCalc::calc_filename(_base_filename, _extension));
}

@ -115,7 +115,6 @@ void drop(const std::string &name);
// Drop all references
void drop_all();
///////////////////////////////////////////////////////////////////////////////
//
// Macros to be display source file & line

Loading…
Cancel
Save