Compare commits

...

16 Commits

Author SHA1 Message Date
gabime
ccd675a286 version 0.16.3 2018-01-12 14:09:34 +02:00
gabime
5372d58adc comment 2018-01-12 14:09:07 +02:00
Gabi Melman
751520f0cf Merge pull request #610 from joaomoreno/fix609
Use Sleep in Windows instead of sleep_for
2018-01-11 23:09:38 +02:00
Joao Moreno
357a63d914 fix spdlog namespace 2018-01-11 21:58:02 +01:00
Joao Moreno
a938045135 use Sleep in Windows instead of sleep_for
fixes #609
2018-01-11 14:50:47 +01:00
Gabi Melman
32177aa77a Merge pull request #604 from sam-lunt/improve-macros
Ensure marcos always expand to expressions
2018-01-03 18:05:25 +02:00
Gabi Melman
ce1df17262 Merge pull request #605 from sam-lunt/add-flush-on
Add global flush_on function
2018-01-03 18:00:08 +02:00
Sam Lunt
9f8413308a add global flush_on function 2018-01-03 09:36:09 -06:00
Sam Lunt
f25f0e0e40 add (void)0 when logging is disabled 2018-01-03 09:07:58 -06:00
Gabi Melman
a2890f2778 Merge pull request #596 from Broekman/master
Issue fix for spdlog #595. Conversion warning.
2017-12-26 21:22:08 +02:00
Stefan Broekman
de4644b44a Issue fix for spdlog #595. Conversion warning.
See: https://github.com/gabime/spdlog/issues/595

On line 85 in file sinks/wincolor_sink.h:
back_color &= ~(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE |
FOREGROUND_INTENSITY);

'back_color' is of type 'WORD' (unsigned short) whereas a bitwise
complement/NOT returns an int. This results in a conversion warning with
-Wconversion enabled.

85:20: warning: conversion to 'WORD {aka short unsigned int}' from 'int'
may alter its value [-Wconversion] back_color &= ~(FOREGROUND_RED |
FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY);

Possible solution:
We know that the result of ~(FOREGROUND_RED | FOREGROUND_GREEN |
FOREGROUND_BLUE | FOREGROUND_INTENSITY) is always within the limits of
an unsigned short so a simple cast should suffice (correct me if I'm
wrong):

back_color &= static_cast<unsigned short>(~(FOREGROUND_RED |
FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY));
2017-12-26 19:23:29 +01:00
Gabi Melman
03db102375 Update README.md 2017-12-26 13:26:04 +02:00
gabime
3d967dd716 added catch license in tests folder 2017-12-24 19:37:54 +02:00
Gabi Melman
b53d207f44 Update file_helper.h 2017-12-23 11:43:41 +02:00
Gabi Melman
fde12195ee Update file_helper.h 2017-12-22 19:06:01 +02:00
gabime
4ca6991828 astyle 2017-12-22 18:55:19 +02:00
12 changed files with 130 additions and 77 deletions

View File

@@ -21,7 +21,7 @@ Very fast, header only, C++ logging library. [![Build Status](https://travis-ci.
## Platforms
* Linux, FreeBSD, Solaris
* Windows (vc 2013+, cygwin/mingw)
* Windows (vc 2013+, cygwin)
* Mac OSX (clang 3.5+)
* Android

View File

@@ -282,7 +282,7 @@ inline void spdlog::details::async_log_helper::worker_loop()
}
catch(...)
{
_err_handler("Unknown exeption in async logger worker loop.");
_err_handler("Unknown exeption in async logger worker loop.");
}
}
if (_worker_teardown_cb) _worker_teardown_cb();
@@ -358,7 +358,6 @@ inline void spdlog::details::async_log_helper::set_formatter(formatter_ptr msg_f
// spin, yield or sleep. use the time passed since last message as a hint
inline void spdlog::details::async_log_helper::sleep_or_yield(const spdlog::log_clock::time_point& now, const spdlog::log_clock::time_point& last_op_time)
{
using namespace std::this_thread;
using std::chrono::milliseconds;
using std::chrono::microseconds;
@@ -374,10 +373,10 @@ inline void spdlog::details::async_log_helper::sleep_or_yield(const spdlog::log_
// sleep for 20 ms upto 200 ms
if (time_since_op <= milliseconds(200))
return sleep_for(milliseconds(20));
return details::os::sleep_for_millis(20);
// sleep for 500 ms
return sleep_for(milliseconds(500));
return details::os::sleep_for_millis(500);
}
// wait for the queue to be empty

View File

@@ -55,7 +55,7 @@ public:
if (!os::fopen_s(&_fd, fname, mode))
return;
std::this_thread::sleep_for(std::chrono::milliseconds(open_interval));
details::os::sleep_for_millis(open_interval);
}
throw spdlog_ex("Failed opening file " + os::filename_to_str(_filename) + " for writing", errno);
@@ -113,31 +113,30 @@ public:
//
// "mylog.txt" => ("mylog", ".txt")
// "mylog" => ("mylog", "")
// "mylog." => ("mylog.", "")
// "/dir1/dir2/mylog.txt" => ("/dir1/dir2/mylog", ".txt")
// "mylog." => ("mylog.", "")
// "/dir1/dir2/mylog.txt" => ("/dir1/dir2/mylog", ".txt")
//
// the starting dot in filenames is ignored (hidden files):
//
// ".mylog" => (".mylog". "")
// ".mylog" => (".mylog". "")
// "my_folder/.mylog" => ("my_folder/.mylog", "")
// "my_folder/.mylog.txt" => ("my_folder/.mylog", ".txt")
static std::tuple<filename_t, filename_t> split_by_extenstion(const spdlog::filename_t& fname)
{
auto ext_index = fname.rfind('.');
static std::tuple<filename_t, filename_t> split_by_extenstion(const spdlog::filename_t& fname)
{
auto ext_index = fname.rfind('.');
// no valid extension found - return whole path and empty string as extension
if (ext_index == filename_t::npos || ext_index == 0 || ext_index == fname.size() - 1)
return std::make_tuple(fname, spdlog::filename_t());
// no valid extension found - return whole path and empty string as extension
if (ext_index == filename_t::npos || ext_index == 0 || ext_index == fname.size() - 1)
return std::make_tuple(fname, spdlog::filename_t());
// treat casese like "/etc/rc.d/somelogfile or "/abc/.hiddenfile"
//auto folder_index = fname.find('\\', ext_index);
auto folder_index = fname.rfind(details::os::folder_sep);
if (folder_index != fname.npos && folder_index >= ext_index - 1)
return std::make_tuple(fname, spdlog::filename_t());
// treat casese like "/etc/rc.d/somelogfile or "/abc/.hiddenfile"
auto folder_index = fname.rfind(details::os::folder_sep);
if (folder_index != fname.npos && folder_index >= ext_index - 1)
return std::make_tuple(fname, spdlog::filename_t());
// finally - return a valid base and extnetion tuple
return std::make_tuple(fname.substr(0, ext_index), fname.substr(ext_index));
}
// finally - return a valid base and extension tuple
return std::make_tuple(fname.substr(0, ext_index), fname.substr(ext_index));
}
private:
FILE* _fd;
filename_t _filename;

View File

@@ -98,11 +98,11 @@ inline void spdlog::logger::log(level::level_enum lvl, const char* msg)
{
_err_handler(ex.what());
}
catch (...)
{
_err_handler("Unknown exception in logger " + _name);
throw;
}
catch (...)
{
_err_handler("Unknown exception in logger " + _name);
throw;
}
}
template<typename T>
@@ -119,11 +119,11 @@ inline void spdlog::logger::log(level::level_enum lvl, const T& msg)
{
_err_handler(ex.what());
}
catch (...)
{
_err_handler("Unknown exception in logger " + _name);
throw;
}
catch (...)
{
_err_handler("Unknown exception in logger " + _name);
throw;
}
}

View File

@@ -363,6 +363,17 @@ inline size_t thread_id()
}
// This is avoid msvc issue in sleep_for that happens if the clock changes.
// See https://github.com/gabime/spdlog/issues/609
inline void sleep_for_millis(int milliseconds)
{
#if defined(_WIN32)
Sleep(milliseconds);
#else
std::this_thread::sleep_for(std::chrono::milliseconds(milliseconds));
#endif
}
// wchar support for windows file names (SPDLOG_WCHAR_FILENAMES must be defined)
#if defined(_WIN32) && defined(SPDLOG_WCHAR_FILENAMES)
#define SPDLOG_FILENAME_T(s) L ## s

View File

@@ -64,6 +64,7 @@ public:
new_logger->set_error_handler(_err_handler);
new_logger->set_level(_level);
new_logger->flush_on(_flush_level);
//Add to registry
@@ -85,6 +86,7 @@ public:
new_logger->set_error_handler(_err_handler);
new_logger->set_level(_level);
new_logger->flush_on(_flush_level);
//Add to registry
_loggers[logger_name] = new_logger;
@@ -153,6 +155,14 @@ public:
_level = log_level;
}
void flush_on(level::level_enum log_level)
{
std::lock_guard<Mutex> lock(_mutex);
for (auto& l : _loggers)
l.second->flush_on(log_level);
_flush_level = log_level;
}
void set_error_handler(log_err_handler handler)
{
for (auto& l : _loggers)
@@ -197,6 +207,7 @@ private:
std::unordered_map <std::string, std::shared_ptr<logger>> _loggers;
formatter_ptr _formatter;
level::level_enum _level = level::info;
level::level_enum _flush_level = level::off;
log_err_handler _err_handler;
bool _async_mode = false;
size_t _async_q_size = 0;

View File

@@ -236,6 +236,11 @@ inline void spdlog::set_level(level::level_enum log_level)
return details::registry::instance().set_level(log_level);
}
inline void spdlog::flush_on(level::level_enum log_level)
{
return details::registry::instance().flush_on(log_level);
}
inline void spdlog::set_error_handler(log_err_handler handler)
{
return details::registry::instance().set_error_handler(handler);

View File

@@ -8,6 +8,7 @@
#if defined(__ANDROID__)
#include "sink.h"
#include "../details/os.h"
#include <mutex>
#include <string>
@@ -43,7 +44,7 @@ public:
int retry_count = 0;
while ((ret == -11/*EAGAIN*/) && (retry_count < SPDLOG_ANDROID_RETRIES))
{
std::this_thread::sleep_for(std::chrono::milliseconds(5));
details::os::sleep_for_millis(5);
ret = __android_log_write(priority, _tag.c_str(), msg_output);
retry_count++;
}

View File

@@ -82,7 +82,7 @@ private:
GetConsoleScreenBufferInfo(out_handle_, &orig_buffer_info);
WORD back_color = orig_buffer_info.wAttributes;
// retrieve the current background color
back_color &= ~(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
back_color &= static_cast<WORD>(~(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY));
// keep the background color unchanged
SetConsoleTextAttribute(out_handle_, attribs | back_color);
return orig_buffer_info.wAttributes; //return orig attribs

View File

@@ -7,7 +7,7 @@
#pragma once
#define SPDLOG_VERSION "0.16.2"
#define SPDLOG_VERSION "0.16.3"
#include "tweakme.h"
#include "common.h"
@@ -36,10 +36,15 @@ void set_pattern(const std::string& format_string);
void set_formatter(formatter_ptr f);
//
// Set global logging level for
// Set global logging level
//
void set_level(level::level_enum log_level);
//
// Set global flush level
//
void flush_on(level::level_enum log_level);
//
// Set global error handler
//
@@ -165,24 +170,23 @@ void drop_all();
///////////////////////////////////////////////////////////////////////////////
#ifdef SPDLOG_TRACE_ON
#define SPDLOG_STR_H(x) #x
#define SPDLOG_STR_HELPER(x) SPDLOG_STR_H(x)
#ifdef _MSC_VER
#define SPDLOG_TRACE(logger, ...) logger->trace("[ " __FILE__ "(" SPDLOG_STR_HELPER(__LINE__) ") ] " __VA_ARGS__)
# define SPDLOG_STR_H(x) #x
# define SPDLOG_STR_HELPER(x) SPDLOG_STR_H(x)
# ifdef _MSC_VER
# define SPDLOG_TRACE(logger, ...) logger->trace("[ " __FILE__ "(" SPDLOG_STR_HELPER(__LINE__) ") ] " __VA_ARGS__)
# else
# define SPDLOG_TRACE(logger, ...) logger->trace("[ " __FILE__ ":" SPDLOG_STR_HELPER(__LINE__) " ] " __VA_ARGS__)
# endif
#else
#define SPDLOG_TRACE(logger, ...) logger->trace("[ " __FILE__ ":" SPDLOG_STR_HELPER(__LINE__) " ] " __VA_ARGS__)
#endif
#else
#define SPDLOG_TRACE(logger, ...)
# define SPDLOG_TRACE(logger, ...) (void)0
#endif
#ifdef SPDLOG_DEBUG_ON
#define SPDLOG_DEBUG(logger, ...) logger->debug(__VA_ARGS__)
# define SPDLOG_DEBUG(logger, ...) logger->debug(__VA_ARGS__)
#else
#define SPDLOG_DEBUG(logger, ...)
# define SPDLOG_DEBUG(logger, ...) (void)0
#endif
}
#include "details/spdlog_impl.h"

23
tests/catch.license Normal file
View File

@@ -0,0 +1,23 @@
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

View File

@@ -76,42 +76,42 @@ TEST_CASE("file_helper_reopen2", "[file_helper::reopen(false)]]")
static void test_split_ext(const char* fname, const char* expect_base, const char* expect_ext)
{
spdlog::filename_t filename(fname);
spdlog::filename_t expected_base(expect_base);
spdlog::filename_t expected_ext(expect_ext);
{
spdlog::filename_t filename(fname);
spdlog::filename_t expected_base(expect_base);
spdlog::filename_t expected_ext(expect_ext);
#ifdef _WIN32 // replace folder sep
std::replace(filename.begin(), filename.end(), '/', '\\');
std::replace(expected_base.begin(), expected_base.end(), '/', '\\');
std::replace(filename.begin(), filename.end(), '/', '\\');
std::replace(expected_base.begin(), expected_base.end(), '/', '\\');
#endif
spdlog::filename_t basename, ext;
std::tie(basename, ext) = file_helper::split_by_extenstion(filename);
REQUIRE(basename == expected_base);
REQUIRE(ext == expected_ext);
spdlog::filename_t basename, ext;
std::tie(basename, ext) = file_helper::split_by_extenstion(filename);
REQUIRE(basename == expected_base);
REQUIRE(ext == expected_ext);
}
TEST_CASE("file_helper_split_by_extenstion", "[file_helper::split_by_extenstion()]]")
{
test_split_ext("mylog.txt", "mylog", ".txt");
test_split_ext(".mylog.txt", ".mylog", ".txt");
test_split_ext(".mylog", ".mylog", "");
test_split_ext("/aaa/bb.d/mylog", "/aaa/bb.d/mylog", "");
test_split_ext("/aaa/bb.d/mylog.txt", "/aaa/bb.d/mylog", ".txt");
test_split_ext("aaa/bbb/ccc/mylog.txt", "aaa/bbb/ccc/mylog", ".txt");
test_split_ext("aaa/bbb/ccc/mylog.", "aaa/bbb/ccc/mylog.", "");
test_split_ext("aaa/bbb/ccc/.mylog.txt", "aaa/bbb/ccc/.mylog", ".txt");
test_split_ext("/aaa/bbb/ccc/mylog.txt", "/aaa/bbb/ccc/mylog", ".txt");
test_split_ext("/aaa/bbb/ccc/.mylog", "/aaa/bbb/ccc/.mylog", "");
test_split_ext("../mylog.txt", "../mylog", ".txt");
test_split_ext(".././mylog.txt", ".././mylog", ".txt");
test_split_ext(".././mylog.txt/xxx", ".././mylog.txt/xxx", "");
test_split_ext("/mylog.txt", "/mylog", ".txt");
test_split_ext("//mylog.txt", "//mylog", ".txt");
test_split_ext("", "", "");
test_split_ext(".", ".", "");
test_split_ext("..txt", ".", ".txt");
{
test_split_ext("mylog.txt", "mylog", ".txt");
test_split_ext(".mylog.txt", ".mylog", ".txt");
test_split_ext(".mylog", ".mylog", "");
test_split_ext("/aaa/bb.d/mylog", "/aaa/bb.d/mylog", "");
test_split_ext("/aaa/bb.d/mylog.txt", "/aaa/bb.d/mylog", ".txt");
test_split_ext("aaa/bbb/ccc/mylog.txt", "aaa/bbb/ccc/mylog", ".txt");
test_split_ext("aaa/bbb/ccc/mylog.", "aaa/bbb/ccc/mylog.", "");
test_split_ext("aaa/bbb/ccc/.mylog.txt", "aaa/bbb/ccc/.mylog", ".txt");
test_split_ext("/aaa/bbb/ccc/mylog.txt", "/aaa/bbb/ccc/mylog", ".txt");
test_split_ext("/aaa/bbb/ccc/.mylog", "/aaa/bbb/ccc/.mylog", "");
test_split_ext("../mylog.txt", "../mylog", ".txt");
test_split_ext(".././mylog.txt", ".././mylog", ".txt");
test_split_ext(".././mylog.txt/xxx", ".././mylog.txt/xxx", "");
test_split_ext("/mylog.txt", "/mylog", ".txt");
test_split_ext("//mylog.txt", "//mylog", ".txt");
test_split_ext("", "", "");
test_split_ext(".", ".", "");
test_split_ext("..txt", ".", ".txt");
}