Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
S
spdlog
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Libraries
spdlog
Commits
d37bded9
Commit
d37bded9
authored
Dec 07, 2014
by
gabi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
More improvements to the async logger
parent
9feb5fba
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
110 additions
and
127 deletions
+110
-127
include/spdlog/async_logger.h
include/spdlog/async_logger.h
+3
-4
include/spdlog/details/async_log_helper.h
include/spdlog/details/async_log_helper.h
+96
-107
include/spdlog/details/async_logger_impl.h
include/spdlog/details/async_logger_impl.h
+6
-8
include/spdlog/details/registry.h
include/spdlog/details/registry.h
+2
-4
include/spdlog/details/spdlog_impl.h
include/spdlog/details/spdlog_impl.h
+2
-2
include/spdlog/spdlog.h
include/spdlog/spdlog.h
+1
-2
No files found.
include/spdlog/async_logger.h
View file @
d37bded9
...
@@ -46,9 +46,9 @@ class async_logger :public logger
...
@@ -46,9 +46,9 @@ class async_logger :public logger
{
{
public:
public:
template
<
class
It
>
template
<
class
It
>
async_logger
(
const
std
::
string
&
name
,
const
It
&
begin
,
const
It
&
end
,
size_t
queue_size
,
const
log_clock
::
duration
&
shutdown_duration
);
async_logger
(
const
std
::
string
&
name
,
const
It
&
begin
,
const
It
&
end
,
size_t
queue_size
);
async_logger
(
const
std
::
string
&
logger_name
,
sinks_init_list
sinks
,
size_t
queue_size
,
const
log_clock
::
duration
&
shutdown_duration
);
async_logger
(
const
std
::
string
&
logger_name
,
sinks_init_list
sinks
,
size_t
queue_size
);
async_logger
(
const
std
::
string
&
logger_name
,
sink_ptr
single_sink
,
size_t
queue_size
,
const
log_clock
::
duration
&
shutdown_duration
);
async_logger
(
const
std
::
string
&
logger_name
,
sink_ptr
single_sink
,
size_t
queue_size
);
protected:
protected:
...
@@ -58,7 +58,6 @@ protected:
...
@@ -58,7 +58,6 @@ protected:
void
_stop
()
override
;
void
_stop
()
override
;
private:
private:
log_clock
::
duration
_shutdown_duration
;
std
::
unique_ptr
<
details
::
async_log_helper
>
_async_log_helper
;
std
::
unique_ptr
<
details
::
async_log_helper
>
_async_log_helper
;
};
};
}
}
...
...
include/spdlog/details/async_log_helper.h
View file @
d37bded9
...
@@ -115,9 +115,6 @@ public:
...
@@ -115,9 +115,6 @@ public:
//Stop logging and join the back thread
//Stop logging and join the back thread
~
async_log_helper
();
~
async_log_helper
();
void
set_formatter
(
formatter_ptr
);
void
set_formatter
(
formatter_ptr
);
//Wait to remaining items (if any) in the queue to be written and shutdown
void
shutdown
(
const
log_clock
::
duration
&
timeout
);
private:
private:
...
@@ -131,14 +128,16 @@ private:
...
@@ -131,14 +128,16 @@ private:
std
::
shared_ptr
<
spdlog_ex
>
_last_workerthread_ex
;
std
::
shared_ptr
<
spdlog_ex
>
_last_workerthread_ex
;
// throw last worker thread exception or if worker thread is not active
// will throw last worker thread exception or if worker thread no active
void
throw_if_bad_worker
();
void
throw_if_bad_worker
();
// worker thread loop
// worker thread
main
loop
void
worker_loop
();
void
worker_loop
();
//pop next message from the queue and process it
//return true if a message was available (queue was not empty), will set the last_pop to the pop time
bool
process_next_msg
(
clock
::
time_point
&
last_pop
);
// guess how much to sleep if queue is empty/full using last succesful op time as hint
// guess how much to sleep if queue is empty/full using last succesful op time as hint
static
void
sleep_or_yield
(
const
clock
::
time_point
&
last_op_time
);
static
void
sleep_or_yield
(
const
clock
::
time_point
&
last_op_time
);
...
@@ -146,7 +145,6 @@ private:
...
@@ -146,7 +145,6 @@ private:
// clear all remaining messages(if any), stop the _worker_thread and join it
// clear all remaining messages(if any), stop the _worker_thread and join it
void
join_worker
();
void
join_worker
();
};
};
}
}
}
}
...
@@ -155,7 +153,7 @@ private:
...
@@ -155,7 +153,7 @@ private:
// async_sink class implementation
// async_sink class implementation
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
inline
spdlog
::
details
::
async_log_helper
::
async_log_helper
(
formatter_ptr
formatter
,
const
std
::
vector
<
sink_ptr
>&
sinks
,
size_t
queue_size
)
:
inline
spdlog
::
details
::
async_log_helper
::
async_log_helper
(
formatter_ptr
formatter
,
const
std
::
vector
<
sink_ptr
>&
sinks
,
size_t
queue_size
)
:
_active
(
fals
e
),
_active
(
tru
e
),
_formatter
(
formatter
),
_formatter
(
formatter
),
_sinks
(
sinks
),
_sinks
(
sinks
),
_q
(
queue_size
),
_q
(
queue_size
),
...
@@ -172,97 +170,92 @@ inline spdlog::details::async_log_helper::~async_log_helper()
...
@@ -172,97 +170,92 @@ inline spdlog::details::async_log_helper::~async_log_helper()
inline
void
spdlog
::
details
::
async_log_helper
::
log
(
const
details
::
log_msg
&
msg
)
inline
void
spdlog
::
details
::
async_log_helper
::
log
(
const
details
::
log_msg
&
msg
)
{
{
throw_if_bad_worker
();
throw_if_bad_worker
();
async_msg
new_msg
(
msg
);
//Only if queue is full, enter wait loop
if
(
!
_q
.
enqueue
(
std
::
move
(
new_msg
)))
//if (!_q.push(std::unique_ptr < async_msg >(new async_msg(msg))))
//async_msg* as = new async_msg(msg);
//if (!_q.enqueue(std::unique_ptr<async_msg>(new async_msg(msg))))
if
(
!
_q
.
enqueue
(
std
::
move
(
async_msg
(
msg
))))
{
{
auto
last_op_time
=
clock
::
now
();
auto
last_op_time
=
clock
::
now
();
do
do
{
{
sleep_or_yield
(
last_op_time
);
sleep_or_yield
(
last_op_time
);
}
}
while
(
!
_q
.
enqueue
(
std
::
move
(
async_msg
(
msg
)
)));
while
(
!
_q
.
enqueue
(
std
::
move
(
new_msg
)));
}
}
}
}
inline
void
spdlog
::
details
::
async_log_helper
::
worker_loop
()
inline
void
spdlog
::
details
::
async_log_helper
::
worker_loop
()
{
{
log_msg
popped_log_msg
;
clock
::
time_point
last_pop
=
clock
::
now
();
clock
::
time_point
last_pop
=
clock
::
now
();
_active
=
true
;
while
(
_active
)
while
(
_active
)
{
{
q_type
::
item_type
popped_msg
;
//Dont die if there are still messages in the q to process
while
(
process_next_msg
(
last_pop
));
}
}
if
(
_q
.
dequeue
(
popped_msg
))
inline
bool
spdlog
::
details
::
async_log_helper
::
process_next_msg
(
clock
::
time_point
&
last_pop
)
{
async_msg
incoming_async_msg
;
log_msg
incoming_log_msg
;
if
(
_q
.
dequeue
(
incoming_async_msg
))
{
{
last_pop
=
clock
::
now
();
last_pop
=
clock
::
now
();
try
try
{
{
popped_msg
.
fill_log_msg
(
popped
_log_msg
);
incoming_async_msg
.
fill_log_msg
(
incoming
_log_msg
);
_formatter
->
format
(
popped
_log_msg
);
_formatter
->
format
(
incoming
_log_msg
);
for
(
auto
&
s
:
_sinks
)
for
(
auto
&
s
:
_sinks
)
s
->
log
(
popped_log_msg
);
s
->
log
(
incoming_log_msg
);
}
}
catch
(
const
std
::
exception
&
ex
)
catch
(
const
std
::
exception
&
ex
)
{
{
_last_workerthread_ex
=
std
::
make_shared
<
spdlog_ex
>
(
ex
.
what
());
_last_workerthread_ex
=
std
::
make_shared
<
spdlog_ex
>
(
std
::
string
(
"async_logger worker thread exception: "
)
+
ex
.
what
());
}
}
catch
(...)
catch
(...)
{
{
_last_workerthread_ex
=
std
::
make_shared
<
spdlog_ex
>
(
"Unknown
exception"
);
_last_workerthread_ex
=
std
::
make_shared
<
spdlog_ex
>
(
"async_logger worker thread
exception"
);
}
}
return
true
;
}
}
// sleep or yield if queue is empty.
// sleep or yield if queue is empty.
else
else
{
{
sleep_or_yield
(
last_pop
);
sleep_or_yield
(
last_pop
);
}
return
false
;
}
}
}
}
inline
void
spdlog
::
details
::
async_log_helper
::
set_formatter
(
formatter_ptr
msg_formatter
)
inline
void
spdlog
::
details
::
async_log_helper
::
set_formatter
(
formatter_ptr
msg_formatter
)
{
{
_formatter
=
msg_formatter
;
_formatter
=
msg_formatter
;
}
}
inline
void
spdlog
::
details
::
async_log_helper
::
shutdown
(
const
log_clock
::
duration
&
timeout
)
{
/*
if (timeout > std::chrono::milliseconds::zero())
{
auto until = log_clock::now() + timeout;
while (_q.approx_size() > 0 && log_clock::now() < until)
{
std::this_thread::sleep_for(std::chrono::milliseconds(5));
}
}
join_worker();
*/
}
// Sleep
or yield
using the time passed since last message as a hint
// Sleep
,yield or return immediatly
using the time passed since last message as a hint
inline
void
spdlog
::
details
::
async_log_helper
::
sleep_or_yield
(
const
clock
::
time_point
&
last_op_time
)
inline
void
spdlog
::
details
::
async_log_helper
::
sleep_or_yield
(
const
clock
::
time_point
&
last_op_time
)
{
{
using
std
::
chrono
::
milliseconds
;
using
std
::
chrono
::
milliseconds
;
using
std
::
this_thread
::
sleep_for
;
using
namespace
std
::
this_thread
;
using
std
::
this_thread
::
yield
;
clock
::
duration
sleep_duration
;
auto
time_since_op
=
clock
::
now
()
-
last_op_time
;
auto
time_since_op
=
clock
::
now
()
-
last_op_time
;
if
(
time_since_op
>
milliseconds
(
1000
))
sleep_for
(
milliseconds
(
500
));
//spin upto 1 ms
else
if
(
time_since_op
>
milliseconds
(
1
))
if
(
time_since_op
<=
milliseconds
(
1
))
sleep_for
(
time_since_op
/
2
);
return
;
else
yield
();
// yield upto 10ms
if
(
time_since_op
<=
milliseconds
(
10
))
return
yield
();
// sleep for half of duration since last op
if
(
time_since_op
<=
milliseconds
(
100
))
return
sleep_for
(
time_since_op
/
2
);
return
sleep_for
(
milliseconds
(
100
));
}
}
//throw if the worker thread threw an exception or not active
//throw if the worker thread threw an exception or not active
...
@@ -282,17 +275,13 @@ inline void spdlog::details::async_log_helper::throw_if_bad_worker()
...
@@ -282,17 +275,13 @@ inline void spdlog::details::async_log_helper::throw_if_bad_worker()
inline
void
spdlog
::
details
::
async_log_helper
::
join_worker
()
inline
void
spdlog
::
details
::
async_log_helper
::
join_worker
()
{
{
_active
=
false
;
_active
=
false
;
if
(
_worker_thread
.
joinable
())
{
try
try
{
{
_worker_thread
.
join
();
_worker_thread
.
join
();
}
}
catch
(
const
std
::
system_error
&
)
//Dont crash if thread not joinable
catch
(
const
std
::
system_error
&
)
//Dont crash if thread not joinable
{
{}
}
}
}
}
...
...
include/spdlog/details/async_logger_impl.h
View file @
d37bded9
...
@@ -34,18 +34,17 @@
...
@@ -34,18 +34,17 @@
template
<
class
It
>
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
log_clock
::
duration
&
shutdown_duration
)
:
inline
spdlog
::
async_logger
::
async_logger
(
const
std
::
string
&
logger_name
,
const
It
&
begin
,
const
It
&
end
,
size_t
queue_size
)
:
logger
(
logger_name
,
begin
,
end
),
logger
(
logger_name
,
begin
,
end
),
_shutdown_duration
(
shutdown_duration
),
_async_log_helper
(
new
details
::
async_log_helper
(
_formatter
,
_sinks
,
queue_size
))
_async_log_helper
(
new
details
::
async_log_helper
(
_formatter
,
_sinks
,
queue_size
))
{
{
}
}
inline
spdlog
::
async_logger
::
async_logger
(
const
std
::
string
&
logger_name
,
sinks_init_list
sinks
,
size_t
queue_size
,
const
log_clock
::
duration
&
shutdown_duration
)
:
inline
spdlog
::
async_logger
::
async_logger
(
const
std
::
string
&
logger_name
,
sinks_init_list
sinks
,
size_t
queue_size
)
:
async_logger
(
logger_name
,
sinks
.
begin
(),
sinks
.
end
(),
queue_size
,
shutdown_duration
)
{}
async_logger
(
logger_name
,
sinks
.
begin
(),
sinks
.
end
(),
queue_size
)
{}
inline
spdlog
::
async_logger
::
async_logger
(
const
std
::
string
&
logger_name
,
sink_ptr
single_sink
,
size_t
queue_size
,
const
log_clock
::
duration
&
shutdown_duration
)
:
inline
spdlog
::
async_logger
::
async_logger
(
const
std
::
string
&
logger_name
,
sink_ptr
single_sink
,
size_t
queue_size
)
:
async_logger
(
logger_name
,
{
single_sink
},
queue_size
,
shutdown_duration
)
{}
async_logger
(
logger_name
,
{
single_sink
},
queue_size
)
{}
inline
void
spdlog
::
async_logger
::
_set_formatter
(
spdlog
::
formatter_ptr
msg_formatter
)
inline
void
spdlog
::
async_logger
::
_set_formatter
(
spdlog
::
formatter_ptr
msg_formatter
)
...
@@ -65,7 +64,6 @@ inline void spdlog::async_logger::_set_pattern(const std::string& pattern)
...
@@ -65,7 +64,6 @@ inline void spdlog::async_logger::_set_pattern(const std::string& pattern)
inline
void
spdlog
::
async_logger
::
_stop
()
inline
void
spdlog
::
async_logger
::
_stop
()
{
{
set_level
(
level
::
OFF
);
set_level
(
level
::
OFF
);
_async_log_helper
->
shutdown
(
_shutdown_duration
);
}
}
inline
void
spdlog
::
async_logger
::
_log_msg
(
details
::
log_msg
&
msg
)
inline
void
spdlog
::
async_logger
::
_log_msg
(
details
::
log_msg
&
msg
)
...
...
include/spdlog/details/registry.h
View file @
d37bded9
...
@@ -61,7 +61,7 @@ public:
...
@@ -61,7 +61,7 @@ public:
return
found
->
second
;
return
found
->
second
;
std
::
shared_ptr
<
logger
>
new_logger
;
std
::
shared_ptr
<
logger
>
new_logger
;
if
(
_async_mode
)
if
(
_async_mode
)
new_logger
=
std
::
make_shared
<
async_logger
>
(
logger_name
,
sinks_begin
,
sinks_end
,
_async_q_size
,
_async_shutdown_duration
);
new_logger
=
std
::
make_shared
<
async_logger
>
(
logger_name
,
sinks_begin
,
sinks_end
,
_async_q_size
);
else
else
new_logger
=
std
::
make_shared
<
logger
>
(
logger_name
,
sinks_begin
,
sinks_end
);
new_logger
=
std
::
make_shared
<
logger
>
(
logger_name
,
sinks_begin
,
sinks_end
);
...
@@ -114,12 +114,11 @@ public:
...
@@ -114,12 +114,11 @@ public:
l
.
second
->
set_level
(
log_level
);
l
.
second
->
set_level
(
log_level
);
}
}
void
set_async_mode
(
size_t
q_size
,
const
log_clock
::
duration
&
shutdown_duration
)
void
set_async_mode
(
size_t
q_size
)
{
{
std
::
lock_guard
<
std
::
mutex
>
lock
(
_mutex
);
std
::
lock_guard
<
std
::
mutex
>
lock
(
_mutex
);
_async_mode
=
true
;
_async_mode
=
true
;
_async_q_size
=
q_size
;
_async_q_size
=
q_size
;
_async_shutdown_duration
=
shutdown_duration
;
}
}
void
set_sync_mode
()
void
set_sync_mode
()
...
@@ -153,7 +152,6 @@ private:
...
@@ -153,7 +152,6 @@ private:
level
::
level_enum
_level
=
level
::
INFO
;
level
::
level_enum
_level
=
level
::
INFO
;
bool
_async_mode
=
false
;
bool
_async_mode
=
false
;
size_t
_async_q_size
=
0
;
size_t
_async_q_size
=
0
;
log_clock
::
duration
_async_shutdown_duration
;
};
};
}
}
}
}
include/spdlog/details/spdlog_impl.h
View file @
d37bded9
...
@@ -133,9 +133,9 @@ inline void spdlog::set_level(level::level_enum log_level)
...
@@ -133,9 +133,9 @@ inline void spdlog::set_level(level::level_enum log_level)
}
}
inline
void
spdlog
::
set_async_mode
(
size_t
queue_size
,
const
log_clock
::
duration
&
shutdown_duration
)
inline
void
spdlog
::
set_async_mode
(
size_t
queue_size
)
{
{
details
::
registry
::
instance
().
set_async_mode
(
queue_size
,
shutdown_duration
);
details
::
registry
::
instance
().
set_async_mode
(
queue_size
);
}
}
inline
void
spdlog
::
set_sync_mode
()
inline
void
spdlog
::
set_sync_mode
()
...
...
include/spdlog/spdlog.h
View file @
d37bded9
...
@@ -65,9 +65,8 @@ void set_level(level::level_enum log_level);
...
@@ -65,9 +65,8 @@ void set_level(level::level_enum log_level);
//
//
// Turn on async mode and set the queue size for each async_logger
// Turn on async mode and set the queue size for each async_logger
// shutdown_duration indicates max time to wait for the worker thread to log its messages before terminating.
void
set_async_mode
(
size_t
queue_size
,
const
log_clock
::
duration
&
shutdown_duration
=
std
::
chrono
::
seconds
(
5
)
);
void
set_async_mode
(
size_t
queue_size
);
// Turn off async mode
// Turn off async mode
void
set_sync_mode
();
void
set_sync_mode
();
...
...
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