Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
S
spdlog
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
spdlog
Commits
6f4cd8d3
Commit
6f4cd8d3
authored
Apr 14, 2018
by
gabime
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
thread_pool and refactoring async
parent
5e08950e
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
184 additions
and
256 deletions
+184
-256
bench.cpp
example/bench.cpp
+4
-5
example.cpp
example/example.cpp
+10
-5
async_logger.h
include/spdlog/async_logger.h
+17
-30
README.md
include/spdlog/contrib/README.md
+0
-1
.gitignore
include/spdlog/contrib/sinks/.gitignore
+0
-1
async_log_helper.h
include/spdlog/details/async_log_helper.h
+1
-2
async_logger_impl.h
include/spdlog/details/async_logger_impl.h
+75
-48
log_msg.h
include/spdlog/details/log_msg.h
+2
-2
logger_impl.h
include/spdlog/details/logger_impl.h
+17
-24
registry.h
include/spdlog/details/registry.h
+40
-106
spdlog_impl.h
include/spdlog/details/spdlog_impl.h
+0
-0
format.h
include/spdlog/fmt/bundled/format.h
+1
-1
logger.h
include/spdlog/logger.h
+8
-12
ansicolor_sink.h
include/spdlog/sinks/ansicolor_sink.h
+1
-1
stdout_sinks.h
include/spdlog/sinks/stdout_sinks.h
+0
-12
spdlog.h
include/spdlog/spdlog.h
+0
-0
errors.cpp
tests/errors.cpp
+7
-6
includes.h
tests/includes.h
+1
-0
No files found.
example/bench.cpp
View file @
6f4cd8d3
...
...
@@ -6,10 +6,10 @@
//
// bench.cpp : spdlog benchmarks
//
#include "spdlog/async_logger.h"
#include "spdlog/sinks/file_sinks.h"
#include "spdlog/async.h"
#include "spdlog/sinks/null_sink.h"
#include "spdlog/spdlog.h"
#include "utils.h"
#include <atomic>
#include <cstdlib> // EXIT_FAILURE
...
...
@@ -71,11 +71,10 @@ int main(int argc, char *argv[])
cout
<<
"async logging.. "
<<
threads
<<
" threads sharing same logger, "
<<
format
(
howmany
)
<<
" iterations "
<<
endl
;
cout
<<
"*******************************************************************************
\n
"
;
spdlog
::
set_async_mode
(
queue_size
);
for
(
int
i
=
0
;
i
<
3
;
++
i
)
{
auto
as
=
spdlog
::
daily_logger_st
(
"as"
,
"logs/daily_async.log"
);
spdlog
::
init_thread_pool
(
queue_size
,
1
);
auto
as
=
spdlog
::
daily_logger_mt
<
spdlog
::
create_async
>
(
"as"
,
"logs/daily_async.log"
);
bench_mt
(
howmany
,
as
,
threads
);
spdlog
::
drop
(
"as"
);
}
...
...
example/example.cpp
View file @
6f4cd8d3
...
...
@@ -10,6 +10,7 @@
#define SPDLOG_TRACE_ON
#define SPDLOG_DEBUG_ON
#include "spdlog/async.h"
#include "spdlog/spdlog.h"
#include <iostream>
...
...
@@ -27,9 +28,10 @@ int main(int, char *[])
try
{
// Console logger with color
auto
console
=
spd
::
stdout_color_mt
(
"console"
);
auto
console
=
spdlog
::
console
<
spd
::
stdout_color_mt
>
(
"console"
);
auto
console2
=
spdlog
::
console
<
spd
::
stdout_color_mt
>
(
"console"
);
console
->
info
(
"Welcome to spdlog!"
);
console
->
error
(
"Some error message with arg
{}..
"
,
1
);
console
->
error
(
"Some error message with arg
: {}
"
,
1
);
// Formatting examples
console
->
warn
(
"Easy padding in numbers like {:08d}"
,
12
);
...
...
@@ -105,13 +107,16 @@ int main(int, char *[])
void
async_example
()
{
size_t
q_size
=
4096
;
// queue size must be power of 2
spdlog
::
set_async_mode
(
q_size
);
auto
async_file
=
spd
::
daily_logger_st
(
"async_file_logger"
,
"logs/async_log.txt"
);
auto
async_file
=
spd
::
basic_logger_mt
<
spdlog
::
create_async
>
(
"async_file_logger"
,
"logs/async_log.txt"
);
for
(
int
i
=
0
;
i
<
100
;
++
i
)
{
async_file
->
info
(
"Async message #{}"
,
i
);
}
// optional change thread pool settings *before* creating the logger:
// spdlog::init_thread_pool(8192, 1);
// if not called a defaults are: 8192 queue size and 1 worker thread.
}
// syslog example (linux/osx/freebsd)
...
...
include/spdlog/async_logger.h
View file @
6f4cd8d3
...
...
@@ -20,52 +20,39 @@
#include <chrono>
#include <functional>
#include <iostream>
#include <memory>
#include <string>
namespace
spdlog
{
namespace
details
{
class
async_log_helper
;
class
thread_pool
;
}
class
async_logger
SPDLOG_FINAL
:
public
logger
class
async_logger
SPDLOG_FINAL
:
public
std
::
enable_shared_from_this
<
async_logger
>
,
public
logger
{
friend
class
details
::
thread_pool
;
public
:
template
<
class
It
>
async_logger
(
const
std
::
string
&
logger_name
,
const
It
&
begin
,
const
It
&
end
,
size_t
queue_size
,
const
async_overflow_policy
overflow_policy
=
async_overflow_policy
::
block_retry
,
const
std
::
function
<
void
()
>
&
worker_warmup_cb
=
nullptr
,
const
std
::
chrono
::
milliseconds
&
flush_interval_ms
=
std
::
chrono
::
milliseconds
::
zero
(),
const
std
::
function
<
void
()
>
&
worker_teardown_cb
=
nullptr
);
async_logger
(
const
std
::
string
&
logger_name
,
const
It
&
begin
,
const
It
&
end
,
std
::
weak_ptr
<
details
::
thread_pool
>
tp
,
async_overflow_policy
overflow_policy
=
async_overflow_policy
::
block_retry
);
async_logger
(
const
std
::
string
&
logger_name
,
sinks_init_list
sinks
,
size_t
queue_size
,
const
async_overflow_policy
overflow_policy
=
async_overflow_policy
::
block_retry
,
const
std
::
function
<
void
()
>
&
worker_warmup_cb
=
nullptr
,
const
std
::
chrono
::
milliseconds
&
flush_interval_ms
=
std
::
chrono
::
milliseconds
::
zero
(),
const
std
::
function
<
void
()
>
&
worker_teardown_cb
=
nullptr
);
async_logger
(
const
std
::
string
&
logger_name
,
sinks_init_list
sinks
,
std
::
weak_ptr
<
details
::
thread_pool
>
tp
,
async_overflow_policy
overflow_policy
=
async_overflow_policy
::
block_retry
);
async_logger
(
const
std
::
string
&
logger_name
,
sink_ptr
single_sink
,
size_t
queue_size
,
const
async_overflow_policy
overflow_policy
=
async_overflow_policy
::
block_retry
,
const
std
::
function
<
void
()
>
&
worker_warmup_cb
=
nullptr
,
const
std
::
chrono
::
milliseconds
&
flush_interval_ms
=
std
::
chrono
::
milliseconds
::
zero
(),
const
std
::
function
<
void
()
>
&
worker_teardown_cb
=
nullptr
);
// Wait for the queue to be empty, and flush synchronously
// Warning: this can potentially last forever as we wait it to complete
void
flush
()
override
;
// Error handler
void
set_error_handler
(
log_err_handler
)
override
;
log_err_handler
error_handler
()
override
;
async_logger
(
const
std
::
string
&
logger_name
,
sink_ptr
single_sink
,
std
::
weak_ptr
<
details
::
thread_pool
>
tp
,
async_overflow_policy
overflow_policy
=
async_overflow_policy
::
block_retry
);
protected
:
void
_sink_it
(
details
::
log_msg
&
msg
)
override
;
void
_set_formatter
(
spdlog
::
formatter_ptr
msg_formatter
)
override
;
void
_set_pattern
(
const
std
::
string
&
pattern
,
pattern_time_type
pattern_time
)
override
;
void
_flush
()
override
;
void
_backend_log
(
details
::
log_msg
&
incoming_log_msg
);
void
_backend_flush
();
private
:
std
::
unique_ptr
<
details
::
async_log_helper
>
_async_log_helper
;
std
::
weak_ptr
<
details
::
thread_pool
>
_thread_pool
;
async_overflow_policy
_overflow_policy
;
};
}
// namespace spdlog
...
...
include/spdlog/contrib/README.md
deleted
100644 → 0
View file @
5e08950e
Please put here your contribs. Popular contribs will be moved to main tree after stablization
include/spdlog/contrib/sinks/.gitignore
deleted
100644 → 0
View file @
5e08950e
include/spdlog/details/async_log_helper.h
View file @
6f4cd8d3
...
...
@@ -72,8 +72,7 @@ class async_log_helper
msg_id
(
other
.
msg_id
)
{
}
async_msg
&
operator
=
(
async_msg
&&
other
)
SPDLOG_NOEXCEPT
dsdfsfs
async_msg
&
operator
=
(
async_msg
&&
other
)
SPDLOG_NOEXCEPT
{
logger_name
=
std
::
move
(
other
.
logger_name
);
level
=
other
.
level
;
...
...
include/spdlog/details/async_logger_impl.h
View file @
6f4cd8d3
...
...
@@ -5,82 +5,110 @@
#pragma once
//
Async L
ogger implementation
//
Use an async_sink (queue per logger) to perform the logging in a worker thread
//
async l
ogger implementation
//
uses a thread pool to perform the actual logging
#include "../async_logger.h"
#include "../details/async_log_helper.h"
#include "../details/thread_pool.h"
#include <chrono>
#include <functional>
#include <memory>
#include <string>
template
<
class
It
>
inline
spdlog
::
async_logger
::
async_logger
(
const
std
::
string
&
logger_name
,
const
It
&
begin
,
const
It
&
end
,
size_t
queue_size
,
const
async_overflow_policy
overflow_policy
,
const
std
::
function
<
void
()
>
&
worker_warmup_cb
,
const
std
::
chrono
::
milliseconds
&
flush_interval_ms
,
const
std
::
function
<
void
()
>
&
worker_teardown_cb
)
inline
spdlog
::
async_logger
::
async_logger
(
const
std
::
string
&
logger_name
,
const
It
&
begin
,
const
It
&
end
,
std
::
weak_ptr
<
details
::
thread_pool
>
tp
,
async_overflow_policy
overflow_policy
)
:
logger
(
logger_name
,
begin
,
end
)
,
_
async_log_helper
(
new
details
::
async_log_helper
(
_formatter
,
_sinks
,
queue_size
,
_err_handler
,
overflow_policy
,
worker_warmup_cb
,
flush_interval_ms
,
worker_teardown_cb
)
)
,
_
thread_pool
(
tp
)
,
_overflow_policy
(
overflow_policy
)
{
}
inline
spdlog
::
async_logger
::
async_logger
(
const
std
::
string
&
logger_name
,
sinks_init_list
sinks_list
,
size_t
queue_size
,
const
async_overflow_policy
overflow_policy
,
const
std
::
function
<
void
()
>
&
worker_warmup_cb
,
const
std
::
chrono
::
milliseconds
&
flush_interval_ms
,
const
std
::
function
<
void
()
>
&
worker_teardown_cb
)
:
async_logger
(
logger_name
,
sinks_list
.
begin
(),
sinks_list
.
end
(),
queue_size
,
overflow_policy
,
worker_warmup_cb
,
flush_interval_ms
,
worker_teardown_cb
)
inline
spdlog
::
async_logger
::
async_logger
(
const
std
::
string
&
logger_name
,
sinks_init_list
sinks_list
,
std
::
weak_ptr
<
details
::
thread_pool
>
tp
,
async_overflow_policy
overflow_policy
)
:
async_logger
(
logger_name
,
sinks_list
.
begin
(),
sinks_list
.
end
(),
tp
,
overflow_policy
)
{
}
inline
spdlog
::
async_logger
::
async_logger
(
const
std
::
string
&
logger_name
,
sink_ptr
single_sink
,
size_t
queue_size
,
const
async_overflow_policy
overflow_policy
,
const
std
::
function
<
void
()
>
&
worker_warmup_cb
,
const
std
::
chrono
::
milliseconds
&
flush_interval_ms
,
const
std
::
function
<
void
()
>
&
worker_teardown_cb
)
:
async_logger
(
logger_name
,
{
std
::
move
(
single_sink
)},
queue_size
,
overflow_policy
,
worker_warmup_cb
,
flush_interval_ms
,
worker_teardown_cb
)
inline
spdlog
::
async_logger
::
async_logger
(
const
std
::
string
&
logger_name
,
sink_ptr
single_sink
,
std
::
weak_ptr
<
details
::
thread_pool
>
tp
,
async_overflow_policy
overflow_policy
)
:
async_logger
(
logger_name
,
{
single_sink
},
tp
,
overflow_policy
)
{
}
inline
void
spdlog
::
async_logger
::
flush
()
{
_async_log_helper
->
flush
(
true
);
}
// Error handler
inline
void
spdlog
::
async_logger
::
set_error_handler
(
spdlog
::
log_err_handler
err_handler
)
{
_err_handler
=
err_handler
;
_async_log_helper
->
set_error_handler
(
err_handler
);
}
inline
spdlog
::
log_err_handler
spdlog
::
async_logger
::
error_handler
()
// send the log message to the thread pool
inline
void
spdlog
::
async_logger
::
_sink_it
(
details
::
log_msg
&
msg
)
{
return
_err_handler
;
try
{
#if defined(SPDLOG_ENABLE_MESSAGE_COUNTER)
_incr_msg_counter
(
msg
);
#endif
if
(
auto
pool_ptr
=
_thread_pool
.
lock
())
{
pool_ptr
->
post_log
(
shared_from_this
(),
std
::
move
(
msg
),
_overflow_policy
);
}
else
{
throw
spdlog_ex
(
"async log: thread pool doens't exist anymore"
);
}
}
catch
(
const
std
::
exception
&
ex
)
{
_err_handler
(
ex
.
what
());
}
catch
(...)
{
_err_handler
(
"Unknown exception in async logger "
+
_name
);
}
}
inline
void
spdlog
::
async_logger
::
_set_formatter
(
spdlog
::
formatter_ptr
msg_formatter
)
// send flush request to the thread pool
inline
void
spdlog
::
async_logger
::
_flush
()
{
_formatter
=
msg_formatter
;
_async_log_helper
->
set_formatter
(
_formatter
);
if
(
auto
pool_ptr
=
_thread_pool
.
lock
())
{
pool_ptr
->
post_flush
(
shared_from_this
(),
_overflow_policy
);
}
else
{
throw
spdlog_ex
(
"async flush: thread pool doens't exist anymore"
);
}
}
inline
void
spdlog
::
async_logger
::
_set_pattern
(
const
std
::
string
&
pattern
,
pattern_time_type
pattern_time
)
//
// backend functions - called from the thread pool to do the actual job
//
inline
void
spdlog
::
async_logger
::
_backend_log
(
details
::
log_msg
&
incoming_log_msg
)
{
_formatter
=
std
::
make_shared
<
pattern_formatter
>
(
pattern
,
pattern_time
);
_async_log_helper
->
set_formatter
(
_formatter
);
try
{
_formatter
->
format
(
incoming_log_msg
);
for
(
auto
&
s
:
_sinks
)
{
if
(
s
->
should_log
(
incoming_log_msg
.
level
))
{
s
->
log
(
incoming_log_msg
);
}
}
}
catch
(
const
std
::
exception
&
ex
)
{
_err_handler
(
ex
.
what
());
}
catch
(...)
{
_err_handler
(
"Unknown exception in async logger "
+
_name
);
}
}
inline
void
spdlog
::
async_logger
::
_
sink_it
(
details
::
log_msg
&
msg
)
inline
void
spdlog
::
async_logger
::
_
backend_flush
(
)
{
try
{
#if defined(SPDLOG_ENABLE_MESSAGE_COUNTER)
_incr_msg_counter
(
msg
);
#endif
_async_log_helper
->
log
(
msg
);
if
(
_should_flush_on
(
msg
))
for
(
auto
&
sink
:
_sinks
)
{
_async_log_helper
->
flush
(
false
);
// do async flush
sink
->
flush
();
}
}
catch
(
const
std
::
exception
&
ex
)
...
...
@@ -89,7 +117,6 @@ inline void spdlog::async_logger::_sink_it(details::log_msg &msg)
}
catch
(...)
{
_err_handler
(
"Unknown exception in logger "
+
_name
);
throw
;
_err_handler
(
"Unknown exception in async logger "
+
_name
);
}
}
include/spdlog/details/log_msg.h
View file @
6f4cd8d3
...
...
@@ -30,8 +30,8 @@ struct log_msg
}
log_msg
(
const
log_msg
&
other
)
=
delete
;
log_msg
&
operator
=
(
log_msg
&&
other
)
=
delete
;
log_msg
(
log_msg
&&
other
)
=
delete
;
log_msg
&
operator
=
(
log_msg
&&
other
)
=
delete
;
const
std
::
string
*
logger_name
{
nullptr
};
level
::
level_enum
level
;
...
...
@@ -40,7 +40,7 @@ struct log_msg
fmt
::
MemoryWriter
raw
;
fmt
::
MemoryWriter
formatted
;
size_t
msg_id
{
0
};
//
wrap this range with color codes
//
info about wrapping the formatted text with color
size_t
color_range_start
{
0
};
size_t
color_range_end
{
0
};
};
...
...
include/spdlog/details/logger_impl.h
View file @
6f4cd8d3
...
...
@@ -42,12 +42,12 @@ inline spdlog::logger::~logger() = default;
inline
void
spdlog
::
logger
::
set_formatter
(
spdlog
::
formatter_ptr
msg_formatter
)
{
_
set_formatter
(
std
::
move
(
msg_formatter
)
);
_
formatter
=
std
::
move
(
msg_formatter
);
}
inline
void
spdlog
::
logger
::
set_pattern
(
const
std
::
string
&
pattern
,
pattern_time_type
pattern_time
)
{
_
set_pattern
(
pattern
,
pattern_time
);
_
formatter
=
std
::
make_shared
<
pattern_formatter
>
(
pattern
,
pattern_time
);
}
template
<
typename
...
Args
>
...
...
@@ -282,11 +282,22 @@ inline spdlog::log_err_handler spdlog::logger::error_handler()
return
_err_handler
;
}
inline
void
spdlog
::
logger
::
flush
()
{
_flush
();
}
inline
void
spdlog
::
logger
::
flush_on
(
level
::
level_enum
log_level
)
{
_flush_level
.
store
(
log_level
);
}
inline
bool
spdlog
::
logger
::
_should_flush
(
const
details
::
log_msg
&
msg
)
{
auto
flush_level
=
_flush_level
.
load
(
std
::
memory_order_relaxed
);
return
(
msg
.
level
>=
flush_level
)
&&
(
msg
.
level
!=
level
::
off
);
}
inline
spdlog
::
level
::
level_enum
spdlog
::
logger
::
level
()
const
{
return
static_cast
<
spdlog
::
level
::
level_enum
>
(
_level
.
load
(
std
::
memory_order_relaxed
));
...
...
@@ -314,23 +325,13 @@ inline void spdlog::logger::_sink_it(details::log_msg &msg)
}
}
if
(
_should_flush
_on
(
msg
))
if
(
_should_flush
(
msg
))
{
flush
();
}
}
inline
void
spdlog
::
logger
::
_set_pattern
(
const
std
::
string
&
pattern
,
pattern_time_type
pattern_time
)
{
_formatter
=
std
::
make_shared
<
pattern_formatter
>
(
pattern
,
pattern_time
);
}
inline
void
spdlog
::
logger
::
_set_formatter
(
formatter_ptr
msg_formatter
)
{
_formatter
=
std
::
move
(
msg_formatter
);
}
inline
void
spdlog
::
logger
::
flush
()
inline
void
spdlog
::
logger
::
_flush
()
{
for
(
auto
&
sink
:
_sinks
)
{
...
...
@@ -345,19 +346,11 @@ inline void spdlog::logger::_default_err_handler(const std::string &msg)
{
return
;
}
_last_err_time
=
now
;
auto
tm_time
=
details
::
os
::
localtime
(
now
);
char
date_buf
[
100
];
std
::
strftime
(
date_buf
,
sizeof
(
date_buf
),
"%Y-%m-%d %H:%M:%S"
,
&
tm_time
);
details
::
log_msg
err_msg
;
err_msg
.
formatted
.
write
(
"[*** LOG ERROR ***] [{}] [{}] [{}]{}"
,
name
(),
msg
,
date_buf
,
details
::
os
::
default_eol
);
sinks
::
stderr_sink_mt
::
instance
()
->
log
(
err_msg
);
_last_err_time
=
now
;
}
inline
bool
spdlog
::
logger
::
_should_flush_on
(
const
details
::
log_msg
&
msg
)
{
const
auto
flush_level
=
_flush_level
.
load
(
std
::
memory_order_relaxed
);
return
(
msg
.
level
>=
flush_level
)
&&
(
msg
.
level
!=
level
::
off
);
fmt
::
print
(
stderr
,
"[*** LOG ERROR ***] [{}] [{}] {}
\n
"
,
date_buf
,
name
(),
msg
);
}
inline
void
spdlog
::
logger
::
_incr_msg_counter
(
details
::
log_msg
&
msg
)
...
...
include/spdlog/details/registry.h
View file @
6f4cd8d3
...
...
@@ -10,86 +10,41 @@
// If user requests a non existing logger, nullptr will be returned
// This class is thread safe
#include "../async_logger.h"
#include "../common.h"
#include "../details/null_mutex.h"
#include "../logger.h"
#include <chrono>
#include <functional>
#include <memory>
#include <mutex>
#include <string>
#include <unordered_map>
namespace
spdlog
{
namespace
details
{
class
thread_pool
;
template
<
class
Mutex
>
class
registry_t
{
public
:
using
MutexT
=
Mutex
;
registry_t
<
Mutex
>
(
const
registry_t
<
Mutex
>
&
)
=
delete
;
registry_t
<
Mutex
>
&
operator
=
(
const
registry_t
<
Mutex
>
&
)
=
delete
;
void
register_logger
(
std
::
shared_ptr
<
logger
>
logger
)
{
std
::
lock_guard
<
Mutex
>
lock
(
_mutex
);
auto
logger_name
=
logger
->
name
();
throw_if_exists
(
logger_name
);
_loggers
[
logger_name
]
=
logger
;
}
std
::
shared_ptr
<
logger
>
get
(
const
std
::
string
&
logger_name
)
{
std
::
lock_guard
<
Mutex
>
lock
(
_mutex
);
auto
found
=
_loggers
.
find
(
logger_name
);
return
found
==
_loggers
.
end
()
?
nullptr
:
found
->
second
;
}
template
<
class
It
>
std
::
shared_ptr
<
logger
>
create
(
const
std
::
string
&
logger_name
,
const
It
&
sinks_begin
,
const
It
&
sinks_end
)
void
register_logger
(
std
::
shared_ptr
<
logger
>
new_logger
)
{
std
::
lock_guard
<
Mutex
>
lock
(
_mutex
);
auto
logger_name
=
new_logger
->
name
();
throw_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
);
}
else
{
new_logger
=
std
::
make_shared
<
logger
>
(
logger_name
,
sinks_begin
,
sinks_end
);
}
if
(
_formatter
)
{
new_logger
->
set_formatter
(
_formatter
);
}
if
(
_err_handler
)
{
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
;
return
new_logger
;
}
template
<
class
It
>
std
::
shared_ptr
<
async_logger
>
create_async
(
const
std
::
string
&
logger_name
,
size_t
queue_size
,
const
async_overflow_policy
overflow_policy
,
const
std
::
function
<
void
()
>
&
worker_warmup_cb
,
const
std
::
chrono
::
milliseconds
&
flush_interval_ms
,
const
std
::
function
<
void
()
>
&
worker_teardown_cb
,
const
It
&
sinks_begin
,
const
It
&
sinks_end
)
void
register_and_init
(
std
::
shared_ptr
<
logger
>
new_logger
)
{
std
::
lock_guard
<
Mutex
>
lock
(
_mutex
);
auto
logger_name
=
new_logger
->
name
();
throw_if_exists
(
logger_name
);
auto
new_logger
=
std
::
make_shared
<
async_logger
>
(
logger_name
,
sinks_begin
,
sinks_end
,
queue_size
,
overflow_policy
,
worker_warmup_cb
,
flush_interval_ms
,
worker_teardown_cb
);
if
(
_formatter
)
{
...
...
@@ -106,56 +61,28 @@ public:
// Add to registry
_loggers
[
logger_name
]
=
new_logger
;
return
new_logger
;
}
void
apply_all
(
std
::
function
<
void
(
std
::
shared_ptr
<
logger
>
)
>
fun
)
std
::
shared_ptr
<
logger
>
get
(
const
std
::
string
&
logger_name
)
{
std
::
lock_guard
<
Mutex
>
lock
(
_mutex
);
for
(
auto
&
l
:
_loggers
)
{
fun
(
l
.
second
);
}
auto
found
=
_loggers
.
find
(
logger_name
);
return
found
==
_loggers
.
end
()
?
nullptr
:
found
->
second
;
}
void
drop
(
const
std
::
string
&
logger_name
)
void
set_thread_pool
(
std
::
shared_ptr
<
thread_pool
>
tp
)
{
std
::
lock_guard
<
Mutex
>
lock
(
_mutex
);
_
loggers
.
erase
(
logger_name
);
_
tp
=
std
::
move
(
tp
);
}
void
drop_al
l
()
std
::
shared_ptr
<
thread_pool
>
get_thread_poo
l
()
{
std
::
lock_guard
<
Mutex
>
lock
(
_mutex
);
_loggers
.
clear
();
}
std
::
shared_ptr
<
logger
>
create
(
const
std
::
string
&
logger_name
,
sinks_init_list
sinks
)
{
return
create
(
logger_name
,
sinks
.
begin
(),
sinks
.
end
());
}
std
::
shared_ptr
<
logger
>
create
(
const
std
::
string
&
logger_name
,
sink_ptr
sink
)
{
return
create
(
logger_name
,
{
sink
});
}
std
::
shared_ptr
<
async_logger
>
create_async
(
const
std
::
string
&
logger_name
,
size_t
queue_size
,
const
async_overflow_policy
overflow_policy
,
const
std
::
function
<
void
()
>
&
worker_warmup_cb
,
const
std
::
chrono
::
milliseconds
&
flush_interval_ms
,
const
std
::
function
<
void
()
>
&
worker_teardown_cb
,
sinks_init_list
sinks
)
{
return
create_async
(
logger_name
,
queue_size
,
overflow_policy
,
worker_warmup_cb
,
flush_interval_ms
,
worker_teardown_cb
,
sinks
.
begin
(),
sinks
.
end
());
}
std
::
shared_ptr
<
async_logger
>
create_async
(
const
std
::
string
&
logger_name
,
size_t
queue_size
,
const
async_overflow_policy
overflow_policy
,
const
std
::
function
<
void
()
>
&
worker_warmup_cb
,
const
std
::
chrono
::
milliseconds
&
flush_interval_ms
,
const
std
::
function
<
void
()
>
&
worker_teardown_cb
,
sink_ptr
sink
)
{
return
create_async
(
logger_name
,
queue_size
,
overflow_policy
,
worker_warmup_cb
,
flush_interval_ms
,
worker_teardown_cb
,
{
sink
});
return
_tp
;
}
void
formatter
(
formatter_ptr
f
)
void
set_
formatter
(
formatter_ptr
f
)
{
std
::
lock_guard
<
Mutex
>
lock
(
_mutex
);
_formatter
=
f
;
...
...
@@ -204,22 +131,30 @@ public:
_err_handler
=
handler
;
}
void
set_async_mode
(
size_t
q_size
,
const
async_overflow_policy
overflow_policy
,
const
std
::
function
<
void
()
>
&
worker_warmup_cb
,
const
std
::
chrono
::
milliseconds
&
flush_interval_ms
,
const
std
::
function
<
void
()
>
&
worker_teardown_cb
)
void
apply_all
(
std
::
function
<
void
(
std
::
shared_ptr
<
logger
>
)
>
fun
)
{
std
::
lock_guard
<
Mutex
>
lock
(
_mutex
);
_async_mode
=
true
;
_async_q_size
=
q_size
;
_overflow_policy
=
overflow_policy
;
_worker_warmup_cb
=
worker_warmup_cb
;
_flush_interval_ms
=
flush_interval_ms
;
_worker_teardown_cb
=
worker_teardown_cb
;
for
(
auto
&
l
:
_loggers
)
{
fun
(
l
.
second
);
}
}
void
set_sync_mode
(
)
void
drop
(
const
std
::
string
&
logger_name
)
{
std
::
lock_guard
<
Mutex
>
lock
(
_mutex
);
_async_mode
=
false
;
_loggers
.
erase
(
logger_name
);
}
void
drop_all
()
{
std
::
lock_guard
<
Mutex
>
lock
(
_mutex
);
_loggers
.
clear
();
}
Mutex
&
tp_mutex
()
{
return
_tp_mutex
;
}
static
registry_t
<
Mutex
>
&
instance
()
...
...
@@ -240,24 +175,22 @@ private:
}
Mutex
_mutex
;
Mutex
_tp_mutex
;
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
;
async_overflow_policy
_overflow_policy
=
async_overflow_policy
::
block_retry
;
std
::
function
<
void
()
>
_worker_warmup_cb
;
std
::
chrono
::
milliseconds
_flush_interval_ms
{
std
::
chrono
::
milliseconds
::
zero
()};
std
::
function
<
void
()
>
_worker_teardown_cb
;
std
::
shared_ptr
<
thread_pool
>
_tp
;
};
#ifdef SPDLOG_NO_REGISTRY_MUTEX
#include "../details/null_mutex.h"
using
registry
=
registry_t
<
spdlog
::
details
::
null_mutex
>
;
#else
#include <mutex>
using
registry
=
registry_t
<
std
::
mutex
>
;
#endif
}
// namespace details
}
// namespace spdlog
}
// namespace spdlog
\ No newline at end of file
include/spdlog/details/spdlog_impl.h
View file @
6f4cd8d3
This diff is collapsed.
Click to expand it.
include/spdlog/fmt/bundled/format.h
View file @
6f4cd8d3
...
...
@@ -785,7 +785,7 @@ inline typename MakeUnsigned<Int>::Type to_unsigned(Int value)
// to avoid dynamic memory allocation.
enum
{
INLINE_BUFFER_SIZE
=
500
INLINE_BUFFER_SIZE
=
500
// TODO reduce to 250
};
#if FMT_SECURE_SCL
...
...
include/spdlog/logger.h
View file @
6f4cd8d3
//
// Copyright(c) 2015 Gabi Melman.
// Copyright(c) 2015
-2108
Gabi Melman.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
//
...
...
@@ -113,27 +113,23 @@ public:
void
set_pattern
(
const
std
::
string
&
pattern
,
pattern_time_type
pattern_time
=
pattern_time_type
::
local
);
void
set_formatter
(
formatter_ptr
msg_formatter
);
// automatically call flush() if message level >= log_level
void
flush
();
void
flush_on
(
level
::
level_enum
log_level
);
virtual
void
flush
();
const
std
::
vector
<
sink_ptr
>
&
sinks
()
const
;
// error handler
v
irtual
v
oid
set_error_handler
(
log_err_handler
err_handler
);
virtual
log_err_handler
error_handler
();
void
set_error_handler
(
log_err_handler
err_handler
);
log_err_handler
error_handler
();
protected
:
virtual
void
_sink_it
(
details
::
log_msg
&
msg
);
virtual
void
_set_pattern
(
const
std
::
string
&
pattern
,
pattern_time_type
pattern_time
);
virtual
void
_set_formatter
(
formatter_ptr
msg_formatter
);
virtual
void
_flush
();
// default error handler: print the error to stderr with the max rate of 1 message/minute
virtual
void
_default_err_handler
(
const
std
::
string
&
msg
);
bool
_should_flush
(
const
details
::
log_msg
&
msg
);
//
return true if the given message level should trigger a flush
bool
_should_flush_on
(
const
details
::
log_ms
g
&
msg
);
//
default error handler: print the error to stderr with the max rate of 1 message/minute
void
_default_err_handler
(
const
std
::
strin
g
&
msg
);
// increment the message count (only if defined(SPDLOG_ENABLE_MESSAGE_COUNTER))
void
_incr_msg_counter
(
details
::
log_msg
&
msg
);
...
...
include/spdlog/sinks/ansicolor_sink.h
View file @
6f4cd8d3
...
...
@@ -94,7 +94,7 @@ protected:
// after color range
_print_range
(
msg
,
msg
.
color_range_end
,
msg
.
formatted
.
size
());
}
else
else
// no color
{
_print_range
(
msg
,
0
,
msg
.
formatted
.
size
());
}
...
...
include/spdlog/sinks/stdout_sinks.h
View file @
6f4cd8d3
...
...
@@ -23,12 +23,6 @@ class stdout_sink SPDLOG_FINAL : public base_sink<Mutex>
public
:
explicit
stdout_sink
()
=
default
;
static
std
::
shared_ptr
<
MyType
>
instance
()
{
static
std
::
shared_ptr
<
MyType
>
instance
=
std
::
make_shared
<
MyType
>
();
return
instance
;
}
protected
:
void
_sink_it
(
const
details
::
log_msg
&
msg
)
override
{
...
...
@@ -53,12 +47,6 @@ class stderr_sink SPDLOG_FINAL : public base_sink<Mutex>
public
:
explicit
stderr_sink
()
=
default
;
static
std
::
shared_ptr
<
MyType
>
instance
()
{
static
std
::
shared_ptr
<
MyType
>
instance
=
std
::
make_shared
<
MyType
>
();
return
instance
;
}
protected
:
void
_sink_it
(
const
details
::
log_msg
&
msg
)
override
{
...
...
include/spdlog/spdlog.h
View file @
6f4cd8d3
This diff is collapsed.
Click to expand it.
tests/errors.cpp
View file @
6f4cd8d3
...
...
@@ -67,10 +67,11 @@ TEST_CASE("async_error_handler", "[errors]]")
{
prepare_logdir
();
std
::
string
err_msg
(
"log failed with some msg"
);
spdlog
::
set_async_mode
(
128
);
std
::
string
filename
=
"logs/simple_async_log.txt"
;
{
auto
logger
=
spdlog
::
create
<
spdlog
::
sinks
::
simple_file_sink_mt
>
(
"logger"
,
filename
,
true
);
spdlog
::
init_thread_pool
(
128
,
1
);
auto
logger
=
spdlog
::
create_as
<
spdlog
::
sinks
::
simple_file_sink_mt
>
(
"logger"
,
filename
,
true
);
logger
->
set_error_handler
([
=
](
const
std
::
string
&
msg
)
{
std
::
ofstream
ofs
(
"logs/custom_err.txt"
);
if
(
!
ofs
)
...
...
@@ -85,8 +86,8 @@ TEST_CASE("async_error_handler", "[errors]]")
#endif
logger
->
info
(
"Good message #2"
);
spdlog
::
drop
(
"logger"
);
// force logger to drain the queue and shutdown
spdlog
::
set_sync_mode
();
}
spdlog
::
init_thread_pool
(
128
,
1
);
REQUIRE
(
count_lines
(
filename
)
==
2
);
REQUIRE
(
file_contents
(
"logs/custom_err.txt"
)
==
err_msg
);
}
...
...
@@ -96,9 +97,9 @@ TEST_CASE("async_error_handler2", "[errors]]")
{
prepare_logdir
();
std
::
string
err_msg
(
"This is async handler error message"
);
spdlog
::
set_async_mode
(
128
);
{
auto
logger
=
spdlog
::
create
<
failing_sink
>
(
"failed_logger"
);
spdlog
::
init_thread_pool
(
128
,
1
);
auto
logger
=
spdlog
::
create_as
<
failing_sink
>
(
"failed_logger"
);
logger
->
set_error_handler
([
=
](
const
std
::
string
&
msg
)
{
std
::
ofstream
ofs
(
"logs/custom_err2.txt"
);
if
(
!
ofs
)
...
...
@@ -107,8 +108,8 @@ TEST_CASE("async_error_handler2", "[errors]]")
});
logger
->
info
(
"Hello failure"
);
spdlog
::
drop
(
"failed_logger"
);
// force logger to drain the queue and shutdown
spdlog
::
set_sync_mode
();
}
spdlog
::
init_thread_pool
(
128
,
1
);
REQUIRE
(
file_contents
(
"logs/custom_err2.txt"
)
==
err_msg
);
}
tests/includes.h
View file @
6f4cd8d3
...
...
@@ -12,6 +12,7 @@
#define SPDLOG_TRACE_ON
#define SPDLOG_DEBUG_ON
#include "../include/spdlog/async.h"
#include "../include/spdlog/sinks/null_sink.h"
#include "../include/spdlog/sinks/ostream_sink.h"
#include "../include/spdlog/spdlog.h"
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment