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
Show whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
182 additions
and
255 deletions
+182
-255
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
+38
-105
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 @@
...
@@ -6,10 +6,10 @@
//
//
// bench.cpp : spdlog benchmarks
// bench.cpp : spdlog benchmarks
//
//
#include "spdlog/async_logger.h"
#include "spdlog/async.h"
#include "spdlog/sinks/file_sinks.h"
#include "spdlog/sinks/null_sink.h"
#include "spdlog/sinks/null_sink.h"
#include "spdlog/spdlog.h"
#include "spdlog/spdlog.h"
#include "utils.h"
#include "utils.h"
#include <atomic>
#include <atomic>
#include <cstdlib> // EXIT_FAILURE
#include <cstdlib> // EXIT_FAILURE
...
@@ -71,11 +71,10 @@ int main(int argc, char *argv[])
...
@@ -71,11 +71,10 @@ int main(int argc, char *argv[])
cout
<<
"async logging.. "
<<
threads
<<
" threads sharing same logger, "
<<
format
(
howmany
)
<<
" iterations "
<<
endl
;
cout
<<
"async logging.. "
<<
threads
<<
" threads sharing same logger, "
<<
format
(
howmany
)
<<
" iterations "
<<
endl
;
cout
<<
"*******************************************************************************
\n
"
;
cout
<<
"*******************************************************************************
\n
"
;
spdlog
::
set_async_mode
(
queue_size
);
for
(
int
i
=
0
;
i
<
3
;
++
i
)
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
);
bench_mt
(
howmany
,
as
,
threads
);
spdlog
::
drop
(
"as"
);
spdlog
::
drop
(
"as"
);
}
}
...
...
example/example.cpp
View file @
6f4cd8d3
...
@@ -10,6 +10,7 @@
...
@@ -10,6 +10,7 @@
#define SPDLOG_TRACE_ON
#define SPDLOG_TRACE_ON
#define SPDLOG_DEBUG_ON
#define SPDLOG_DEBUG_ON
#include "spdlog/async.h"
#include "spdlog/spdlog.h"
#include "spdlog/spdlog.h"
#include <iostream>
#include <iostream>
...
@@ -27,9 +28,10 @@ int main(int, char *[])
...
@@ -27,9 +28,10 @@ int main(int, char *[])
try
try
{
{
// Console logger with color
// 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
->
info
(
"Welcome to spdlog!"
);
console
->
error
(
"Some error message with arg
{}..
"
,
1
);
console
->
error
(
"Some error message with arg
: {}
"
,
1
);
// Formatting examples
// Formatting examples
console
->
warn
(
"Easy padding in numbers like {:08d}"
,
12
);
console
->
warn
(
"Easy padding in numbers like {:08d}"
,
12
);
...
@@ -105,13 +107,16 @@ int main(int, char *[])
...
@@ -105,13 +107,16 @@ int main(int, char *[])
void
async_example
()
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
::
basic_logger_mt
<
spdlog
::
create_async
>
(
"async_file_logger"
,
"logs/async_log.txt"
);
auto
async_file
=
spd
::
daily_logger_st
(
"async_file_logger"
,
"logs/async_log.txt"
);
for
(
int
i
=
0
;
i
<
100
;
++
i
)
for
(
int
i
=
0
;
i
<
100
;
++
i
)
{
{
async_file
->
info
(
"Async message #{}"
,
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)
// syslog example (linux/osx/freebsd)
...
...
include/spdlog/async_logger.h
View file @
6f4cd8d3
...
@@ -20,52 +20,39 @@
...
@@ -20,52 +20,39 @@
#include <chrono>
#include <chrono>
#include <functional>
#include <functional>
#include <iostream>
#include <memory>
#include <memory>
#include <string>
#include <string>
namespace
spdlog
{
namespace
spdlog
{
namespace
details
{
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
:
public
:
template
<
class
It
>
template
<
class
It
>
async_logger
(
const
std
::
string
&
logger_name
,
const
It
&
begin
,
const
It
&
end
,
size_t
queue_size
,
async_logger
(
const
std
::
string
&
logger_name
,
const
It
&
begin
,
const
It
&
end
,
std
::
weak_ptr
<
details
::
thread_pool
>
tp
,
const
async_overflow_policy
overflow_policy
=
async_overflow_policy
::
block_retry
,
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
,
size_t
queue_size
,
async_logger
(
const
std
::
string
&
logger_name
,
sinks_init_list
sinks
,
std
::
weak_ptr
<
details
::
thread_pool
>
tp
,
const
async_overflow_policy
overflow_policy
=
async_overflow_policy
::
block_retry
,
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
,
sink_ptr
single_sink
,
size_t
queue_size
,
async_logger
(
const
std
::
string
&
logger_name
,
sink_ptr
single_sink
,
std
::
weak_ptr
<
details
::
thread_pool
>
tp
,
const
async_overflow_policy
overflow_policy
=
async_overflow_policy
::
block_retry
,
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
;
protected
:
protected
:
void
_sink_it
(
details
::
log_msg
&
msg
)
override
;
void
_sink_it
(
details
::
log_msg
&
msg
)
override
;
void
_set_formatter
(
spdlog
::
formatter_ptr
msg_formatter
)
override
;
void
_flush
()
override
;
void
_set_pattern
(
const
std
::
string
&
pattern
,
pattern_time_type
pattern_time
)
override
;
void
_backend_log
(
details
::
log_msg
&
incoming_log_msg
);
void
_backend_flush
();
private
:
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
}
// 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
...
@@ -72,8 +72,7 @@ class async_log_helper
msg_id
(
other
.
msg_id
)
msg_id
(
other
.
msg_id
)
{
{
}
}
dsdfsfs
async_msg
&
operator
=
(
async_msg
&&
other
)
SPDLOG_NOEXCEPT
async_msg
&
operator
=
(
async_msg
&&
other
)
SPDLOG_NOEXCEPT
{
{
logger_name
=
std
::
move
(
other
.
logger_name
);
logger_name
=
std
::
move
(
other
.
logger_name
);
level
=
other
.
level
;
level
=
other
.
level
;
...
...
include/spdlog/details/async_logger_impl.h
View file @
6f4cd8d3
...
@@ -5,82 +5,110 @@
...
@@ -5,82 +5,110 @@
#pragma once
#pragma once
//
Async L
ogger implementation
//
async l
ogger implementation
//
Use an async_sink (queue per logger) to perform the logging in a worker thread
//
uses a thread pool to perform the actual logging
#include "../async_logger.h"
#include "../details/thread_pool.h"
#include "../details/async_log_helper.h"
#include <chrono>
#include <chrono>
#include <functional>
#include <memory>
#include <memory>
#include <string>
#include <string>
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
,
inline
spdlog
::
async_logger
::
async_logger
(
const
std
::
string
&
logger_name
,
const
It
&
begin
,
const
It
&
end
,
const
async_overflow_policy
overflow_policy
,
const
std
::
function
<
void
()
>
&
worker_warmup_cb
,
std
::
weak_ptr
<
details
::
thread_pool
>
tp
,
async_overflow_policy
overflow_policy
)
const
std
::
chrono
::
milliseconds
&
flush_interval_ms
,
const
std
::
function
<
void
()
>
&
worker_teardown_cb
)
:
logger
(
logger_name
,
begin
,
end
)
:
logger
(
logger_name
,
begin
,
end
)
,
_
async_log_helper
(
new
details
::
async_log_helper
(
,
_
thread_pool
(
tp
)
_formatter
,
_sinks
,
queue_size
,
_err_handler
,
overflow_policy
,
worker_warmup_cb
,
flush_interval_ms
,
worker_teardown_cb
)
)
,
_overflow_policy
(
overflow_policy
)
{
{
}
}
inline
spdlog
::
async_logger
::
async_logger
(
const
std
::
string
&
logger_name
,
sinks_init_list
sinks_list
,
size_t
queue_size
,
inline
spdlog
::
async_logger
::
async_logger
(
const
std
::
string
&
logger_name
,
sinks_init_list
sinks_list
,
const
async_overflow_policy
overflow_policy
,
const
std
::
function
<
void
()
>
&
worker_warmup_cb
,
std
::
weak_ptr
<
details
::
thread_pool
>
tp
,
async_overflow_policy
overflow_policy
)
const
std
::
chrono
::
milliseconds
&
flush_interval_ms
,
const
std
::
function
<
void
()
>
&
worker_teardown_cb
)
:
async_logger
(
logger_name
,
sinks_list
.
begin
(),
sinks_list
.
end
(),
tp
,
overflow_policy
)
:
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
,
sink_ptr
single_sink
,
size_t
queue_size
,
inline
spdlog
::
async_logger
::
async_logger
(
const
async_overflow_policy
overflow_policy
,
const
std
::
function
<
void
()
>
&
worker_warmup_cb
,
const
std
::
string
&
logger_name
,
sink_ptr
single_sink
,
std
::
weak_ptr
<
details
::
thread_pool
>
tp
,
async_overflow_policy
overflow_policy
)
const
std
::
chrono
::
milliseconds
&
flush_interval_ms
,
const
std
::
function
<
void
()
>
&
worker_teardown_cb
)
:
async_logger
(
logger_name
,
{
single_sink
},
tp
,
overflow_policy
)
:
async_logger
(
logger_name
,
{
std
::
move
(
single_sink
)},
queue_size
,
overflow_policy
,
worker_warmup_cb
,
flush_interval_ms
,
worker_teardown_cb
)
{
{
}
}
inline
void
spdlog
::
async_logger
::
flush
()
// send the log message to the thread pool
{
inline
void
spdlog
::
async_logger
::
_sink_it
(
details
::
log_msg
&
msg
)
_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
()
{
{
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
;
if
(
auto
pool_ptr
=
_thread_pool
.
lock
())
_async_log_helper
->
set_formatter
(
_formatter
);
{
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
);
try
_async_log_helper
->
set_formatter
(
_formatter
);
{
_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
try
{
{
#if defined(SPDLOG_ENABLE_MESSAGE_COUNTER)
_incr_msg_counter
(
msg
);
for
(
auto
&
sink
:
_sinks
)
#endif
_async_log_helper
->
log
(
msg
);
if
(
_should_flush_on
(
msg
))
{
{
_async_log_helper
->
flush
(
false
);
// do async flush
sink
->
flush
();
}
}
}
}
catch
(
const
std
::
exception
&
ex
)
catch
(
const
std
::
exception
&
ex
)
...
@@ -89,7 +117,6 @@ inline void spdlog::async_logger::_sink_it(details::log_msg &msg)
...
@@ -89,7 +117,6 @@ inline void spdlog::async_logger::_sink_it(details::log_msg &msg)
}
}
catch
(...)
catch
(...)
{
{
_err_handler
(
"Unknown exception in logger "
+
_name
);
_err_handler
(
"Unknown exception in async logger "
+
_name
);
throw
;
}
}
}
}
include/spdlog/details/log_msg.h
View file @
6f4cd8d3
...
@@ -30,8 +30,8 @@ struct log_msg
...
@@ -30,8 +30,8 @@ struct log_msg
}
}
log_msg
(
const
log_msg
&
other
)
=
delete
;
log_msg
(
const
log_msg
&
other
)
=
delete
;
log_msg
&
operator
=
(
log_msg
&&
other
)
=
delete
;
log_msg
(
log_msg
&&
other
)
=
delete
;
log_msg
(
log_msg
&&
other
)
=
delete
;
log_msg
&
operator
=
(
log_msg
&&
other
)
=
delete
;
const
std
::
string
*
logger_name
{
nullptr
};
const
std
::
string
*
logger_name
{
nullptr
};
level
::
level_enum
level
;
level
::
level_enum
level
;
...
@@ -40,7 +40,7 @@ struct log_msg
...
@@ -40,7 +40,7 @@ struct log_msg
fmt
::
MemoryWriter
raw
;
fmt
::
MemoryWriter
raw
;
fmt
::
MemoryWriter
formatted
;
fmt
::
MemoryWriter
formatted
;
size_t
msg_id
{
0
};
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_start
{
0
};
size_t
color_range_end
{
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;
...
@@ -42,12 +42,12 @@ inline spdlog::logger::~logger() = default;
inline
void
spdlog
::
logger
::
set_formatter
(
spdlog
::
formatter_ptr
msg_formatter
)
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
)
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
>
template
<
typename
...
Args
>
...
@@ -282,11 +282,22 @@ inline spdlog::log_err_handler spdlog::logger::error_handler()
...
@@ -282,11 +282,22 @@ inline spdlog::log_err_handler spdlog::logger::error_handler()
return
_err_handler
;
return
_err_handler
;
}
}
inline
void
spdlog
::
logger
::
flush
()
{
_flush
();
}
inline
void
spdlog
::
logger
::
flush_on
(
level
::
level_enum
log_level
)
inline
void
spdlog
::
logger
::
flush_on
(
level
::
level_enum
log_level
)
{
{
_flush_level
.
store
(
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
inline
spdlog
::
level
::
level_enum
spdlog
::
logger
::
level
()
const
{
{
return
static_cast
<
spdlog
::
level
::
level_enum
>
(
_level
.
load
(
std
::
memory_order_relaxed
));
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)
...
@@ -314,23 +325,13 @@ inline void spdlog::logger::_sink_it(details::log_msg &msg)
}
}
}
}
if
(
_should_flush
_on
(
msg
))
if
(
_should_flush
(
msg
))
{
{
flush
();
flush
();
}
}
}
}
inline
void
spdlog
::
logger
::
_set_pattern
(
const
std
::
string
&
pattern
,
pattern_time_type
pattern_time
)
inline
void
spdlog
::
logger
::
_flush
()
{
_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
()
{
{
for
(
auto
&
sink
:
_sinks
)
for
(
auto
&
sink
:
_sinks
)
{
{
...
@@ -345,19 +346,11 @@ inline void spdlog::logger::_default_err_handler(const std::string &msg)
...
@@ -345,19 +346,11 @@ inline void spdlog::logger::_default_err_handler(const std::string &msg)
{
{
return
;
return
;
}
}
_last_err_time
=
now
;
auto
tm_time
=
details
::
os
::
localtime
(
now
);
auto
tm_time
=
details
::
os
::
localtime
(
now
);
char
date_buf
[
100
];
char
date_buf
[
100
];
std
::
strftime
(
date_buf
,
sizeof
(
date_buf
),
"%Y-%m-%d %H:%M:%S"
,
&
tm_time
);
std
::
strftime
(
date_buf
,
sizeof
(
date_buf
),
"%Y-%m-%d %H:%M:%S"
,
&
tm_time
);
details
::
log_msg
err_msg
;
fmt
::
print
(
stderr
,
"[*** LOG ERROR ***] [{}] [{}] {}
\n
"
,
date_buf
,
name
(),
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
);
}
}
inline
void
spdlog
::
logger
::
_incr_msg_counter
(
details
::
log_msg
&
msg
)
inline
void
spdlog
::
logger
::
_incr_msg_counter
(
details
::
log_msg
&
msg
)
...
...
include/spdlog/details/registry.h
View file @
6f4cd8d3
...
@@ -10,86 +10,41 @@
...
@@ -10,86 +10,41 @@
// If user requests a non existing logger, nullptr will be returned
// If user requests a non existing logger, nullptr will be returned
// This class is thread safe
// This class is thread safe
#include "../async_logger.h"
#include "../common.h"
#include "../common.h"
#include "../details/null_mutex.h"
#include "../logger.h"
#include "../logger.h"
#include <chrono>
#include <chrono>
#include <functional>
#include <functional>
#include <memory>
#include <memory>
#include <mutex>
#include <string>
#include <string>
#include <unordered_map>
#include <unordered_map>
namespace
spdlog
{
namespace
spdlog
{
namespace
details
{
namespace
details
{
class
thread_pool
;
template
<
class
Mutex
>
template
<
class
Mutex
>
class
registry_t
class
registry_t
{
{
public
:
public
:
using
MutexT
=
Mutex
;
registry_t
<
Mutex
>
(
const
registry_t
<
Mutex
>
&
)
=
delete
;
registry_t
<
Mutex
>
(
const
registry_t
<
Mutex
>
&
)
=
delete
;
registry_t
<
Mutex
>
&
operator
=
(
const
registry_t
<
Mutex
>
&
)
=
delete
;
registry_t
<
Mutex
>
&
operator
=
(
const
registry_t
<
Mutex
>
&
)
=
delete
;
void
register_logger
(
std
::
shared_ptr
<
logger
>
logger
)
void
register_logger
(
std
::
shared_ptr
<
logger
>
new_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
)
{
{
std
::
lock_guard
<
Mutex
>
lock
(
_mutex
);
std
::
lock_guard
<
Mutex
>
lock
(
_mutex
);
auto
logger_name
=
new_logger
->
name
();
throw_if_exists
(
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
;
_loggers
[
logger_name
]
=
new_logger
;
return
new_logger
;
}
}
template
<
class
It
>
void
register_and_init
(
std
::
shared_ptr
<
logger
>
new_logger
)
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
)
{
{
std
::
lock_guard
<
Mutex
>
lock
(
_mutex
);
std
::
lock_guard
<
Mutex
>
lock
(
_mutex
);
auto
logger_name
=
new_logger
->
name
();
throw_if_exists
(
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
)
if
(
_formatter
)
{
{
...
@@ -106,56 +61,28 @@ public:
...
@@ -106,56 +61,28 @@ public:
// Add to registry
// Add to registry
_loggers
[
logger_name
]
=
new_logger
;
_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
);
std
::
lock_guard
<
Mutex
>
lock
(
_mutex
);
for
(
auto
&
l
:
_loggers
)
auto
found
=
_loggers
.
find
(
logger_name
);
{
return
found
==
_loggers
.
end
()
?
nullptr
:
found
->
second
;
fun
(
l
.
second
);
}
}
}
void
drop
(
const
std
::
string
&
logger_name
)
void
set_thread_pool
(
std
::
shared_ptr
<
thread_pool
>
tp
)
{
{
std
::
lock_guard
<
Mutex
>
lock
(
_mutex
);
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
);
std
::
lock_guard
<
Mutex
>
lock
(
_mutex
);
_loggers
.
clear
();
return
_tp
;
}
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
});
}
}
void
formatter
(
formatter_ptr
f
)
void
set_
formatter
(
formatter_ptr
f
)
{
{
std
::
lock_guard
<
Mutex
>
lock
(
_mutex
);
std
::
lock_guard
<
Mutex
>
lock
(
_mutex
);
_formatter
=
f
;
_formatter
=
f
;
...
@@ -204,22 +131,30 @@ public:
...
@@ -204,22 +131,30 @@ public:
_err_handler
=
handler
;
_err_handler
=
handler
;
}
}
void
set_async_mode
(
size_t
q_size
,
const
async_overflow_policy
overflow_policy
,
const
std
::
function
<
void
()
>
&
worker_warmup_cb
,
void
apply_all
(
std
::
function
<
void
(
std
::
shared_ptr
<
logger
>
)
>
fun
)
const
std
::
chrono
::
milliseconds
&
flush_interval_ms
,
const
std
::
function
<
void
()
>
&
worker_teardown_cb
)
{
{
std
::
lock_guard
<
Mutex
>
lock
(
_mutex
);
std
::
lock_guard
<
Mutex
>
lock
(
_mutex
);
_async_mode
=
true
;
for
(
auto
&
l
:
_loggers
)
_async_q_size
=
q_size
;
{
_overflow_policy
=
overflow_policy
;
fun
(
l
.
second
);
_worker_warmup_cb
=
worker_warmup_cb
;
}
_flush_interval_ms
=
flush_interval_ms
;
_worker_teardown_cb
=
worker_teardown_cb
;
}
}
void
set_sync_mode
(
)
void
drop
(
const
std
::
string
&
logger_name
)
{
{
std
::
lock_guard
<
Mutex
>
lock
(
_mutex
);
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
()
static
registry_t
<
Mutex
>
&
instance
()
...
@@ -240,22 +175,20 @@ private:
...
@@ -240,22 +175,20 @@ private:
}
}
Mutex
_mutex
;
Mutex
_mutex
;
Mutex
_tp_mutex
;
std
::
unordered_map
<
std
::
string
,
std
::
shared_ptr
<
logger
>>
_loggers
;
std
::
unordered_map
<
std
::
string
,
std
::
shared_ptr
<
logger
>>
_loggers
;
formatter_ptr
_formatter
;
formatter_ptr
_formatter
;
level
::
level_enum
_level
=
level
::
info
;
level
::
level_enum
_level
=
level
::
info
;
level
::
level_enum
_flush_level
=
level
::
off
;
level
::
level_enum
_flush_level
=
level
::
off
;
log_err_handler
_err_handler
;
log_err_handler
_err_handler
;
bool
_async_mode
=
false
;
std
::
shared_ptr
<
thread_pool
>
_tp
;
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
;
};
};
#ifdef SPDLOG_NO_REGISTRY_MUTEX
#ifdef SPDLOG_NO_REGISTRY_MUTEX
#include "../details/null_mutex.h"
using
registry
=
registry_t
<
spdlog
::
details
::
null_mutex
>
;
using
registry
=
registry_t
<
spdlog
::
details
::
null_mutex
>
;
#else
#else
#include <mutex>
using
registry
=
registry_t
<
std
::
mutex
>
;
using
registry
=
registry_t
<
std
::
mutex
>
;
#endif
#endif
...
...
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)
...
@@ -785,7 +785,7 @@ inline typename MakeUnsigned<Int>::Type to_unsigned(Int value)
// to avoid dynamic memory allocation.
// to avoid dynamic memory allocation.
enum
enum
{
{
INLINE_BUFFER_SIZE
=
500
INLINE_BUFFER_SIZE
=
500
// TODO reduce to 250
};
};
#if FMT_SECURE_SCL
#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)
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
//
//
...
@@ -113,27 +113,23 @@ public:
...
@@ -113,27 +113,23 @@ public:
void
set_pattern
(
const
std
::
string
&
pattern
,
pattern_time_type
pattern_time
=
pattern_time_type
::
local
);
void
set_pattern
(
const
std
::
string
&
pattern
,
pattern_time_type
pattern_time
=
pattern_time_type
::
local
);
void
set_formatter
(
formatter_ptr
msg_formatter
);
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
);
void
flush_on
(
level
::
level_enum
log_level
);
virtual
void
flush
();
const
std
::
vector
<
sink_ptr
>
&
sinks
()
const
;
const
std
::
vector
<
sink_ptr
>
&
sinks
()
const
;
// error handler
// error handler
v
irtual
v
oid
set_error_handler
(
log_err_handler
err_handler
);
void
set_error_handler
(
log_err_handler
err_handler
);
virtual
log_err_handler
error_handler
();
log_err_handler
error_handler
();
protected
:
protected
:
virtual
void
_sink_it
(
details
::
log_msg
&
msg
);
virtual
void
_sink_it
(
details
::
log_msg
&
msg
);
virtual
void
_set_pattern
(
const
std
::
string
&
pattern
,
pattern_time_type
pattern_time
);
virtual
void
_flush
();
virtual
void
_set_formatter
(
formatter_ptr
msg_formatter
);
// default error handler: print the error to stderr with the max rate of 1 message/minute
bool
_should_flush
(
const
details
::
log_msg
&
msg
);
virtual
void
_default_err_handler
(
const
std
::
string
&
msg
);
//
return true if the given message level should trigger a flush
//
default error handler: print the error to stderr with the max rate of 1 message/minute
bool
_should_flush_on
(
const
details
::
log_ms
g
&
msg
);
void
_default_err_handler
(
const
std
::
strin
g
&
msg
);
// increment the message count (only if defined(SPDLOG_ENABLE_MESSAGE_COUNTER))
// increment the message count (only if defined(SPDLOG_ENABLE_MESSAGE_COUNTER))
void
_incr_msg_counter
(
details
::
log_msg
&
msg
);
void
_incr_msg_counter
(
details
::
log_msg
&
msg
);
...
...
include/spdlog/sinks/ansicolor_sink.h
View file @
6f4cd8d3
...
@@ -94,7 +94,7 @@ protected:
...
@@ -94,7 +94,7 @@ protected:
// after color range
// after color range
_print_range
(
msg
,
msg
.
color_range_end
,
msg
.
formatted
.
size
());
_print_range
(
msg
,
msg
.
color_range_end
,
msg
.
formatted
.
size
());
}
}
else
else
// no color
{
{
_print_range
(
msg
,
0
,
msg
.
formatted
.
size
());
_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>
...
@@ -23,12 +23,6 @@ class stdout_sink SPDLOG_FINAL : public base_sink<Mutex>
public
:
public
:
explicit
stdout_sink
()
=
default
;
explicit
stdout_sink
()
=
default
;
static
std
::
shared_ptr
<
MyType
>
instance
()
{
static
std
::
shared_ptr
<
MyType
>
instance
=
std
::
make_shared
<
MyType
>
();
return
instance
;
}
protected
:
protected
:
void
_sink_it
(
const
details
::
log_msg
&
msg
)
override
void
_sink_it
(
const
details
::
log_msg
&
msg
)
override
{
{
...
@@ -53,12 +47,6 @@ class stderr_sink SPDLOG_FINAL : public base_sink<Mutex>
...
@@ -53,12 +47,6 @@ class stderr_sink SPDLOG_FINAL : public base_sink<Mutex>
public
:
public
:
explicit
stderr_sink
()
=
default
;
explicit
stderr_sink
()
=
default
;
static
std
::
shared_ptr
<
MyType
>
instance
()
{
static
std
::
shared_ptr
<
MyType
>
instance
=
std
::
make_shared
<
MyType
>
();
return
instance
;
}
protected
:
protected
:
void
_sink_it
(
const
details
::
log_msg
&
msg
)
override
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]]")
...
@@ -67,10 +67,11 @@ TEST_CASE("async_error_handler", "[errors]]")
{
{
prepare_logdir
();
prepare_logdir
();
std
::
string
err_msg
(
"log failed with some msg"
);
std
::
string
err_msg
(
"log failed with some msg"
);
spdlog
::
set_async_mode
(
128
);
std
::
string
filename
=
"logs/simple_async_log.txt"
;
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
)
{
logger
->
set_error_handler
([
=
](
const
std
::
string
&
msg
)
{
std
::
ofstream
ofs
(
"logs/custom_err.txt"
);
std
::
ofstream
ofs
(
"logs/custom_err.txt"
);
if
(
!
ofs
)
if
(
!
ofs
)
...
@@ -85,8 +86,8 @@ TEST_CASE("async_error_handler", "[errors]]")
...
@@ -85,8 +86,8 @@ TEST_CASE("async_error_handler", "[errors]]")
#endif
#endif
logger
->
info
(
"Good message #2"
);
logger
->
info
(
"Good message #2"
);
spdlog
::
drop
(
"logger"
);
// force logger to drain the queue and shutdown
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
(
count_lines
(
filename
)
==
2
);
REQUIRE
(
file_contents
(
"logs/custom_err.txt"
)
==
err_msg
);
REQUIRE
(
file_contents
(
"logs/custom_err.txt"
)
==
err_msg
);
}
}
...
@@ -96,9 +97,9 @@ TEST_CASE("async_error_handler2", "[errors]]")
...
@@ -96,9 +97,9 @@ TEST_CASE("async_error_handler2", "[errors]]")
{
{
prepare_logdir
();
prepare_logdir
();
std
::
string
err_msg
(
"This is async handler error message"
);
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
)
{
logger
->
set_error_handler
([
=
](
const
std
::
string
&
msg
)
{
std
::
ofstream
ofs
(
"logs/custom_err2.txt"
);
std
::
ofstream
ofs
(
"logs/custom_err2.txt"
);
if
(
!
ofs
)
if
(
!
ofs
)
...
@@ -107,8 +108,8 @@ TEST_CASE("async_error_handler2", "[errors]]")
...
@@ -107,8 +108,8 @@ TEST_CASE("async_error_handler2", "[errors]]")
});
});
logger
->
info
(
"Hello failure"
);
logger
->
info
(
"Hello failure"
);
spdlog
::
drop
(
"failed_logger"
);
// force logger to drain the queue and shutdown
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
);
REQUIRE
(
file_contents
(
"logs/custom_err2.txt"
)
==
err_msg
);
}
}
tests/includes.h
View file @
6f4cd8d3
...
@@ -12,6 +12,7 @@
...
@@ -12,6 +12,7 @@
#define SPDLOG_TRACE_ON
#define SPDLOG_TRACE_ON
#define SPDLOG_DEBUG_ON
#define SPDLOG_DEBUG_ON
#include "../include/spdlog/async.h"
#include "../include/spdlog/sinks/null_sink.h"
#include "../include/spdlog/sinks/null_sink.h"
#include "../include/spdlog/sinks/ostream_sink.h"
#include "../include/spdlog/sinks/ostream_sink.h"
#include "../include/spdlog/spdlog.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