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
Show whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
556 additions
and
638 deletions
+556
-638
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
+200
-277
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
+174
-106
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,22 +175,20 @@ 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
...
...
include/spdlog/details/spdlog_impl.h
View file @
6f4cd8d3
////
//// Copyright(c) 2015 Gabi Melman.
//// Distributed under the MIT License (http://opensource.org/licenses/MIT)
////
//
// Copyright(c) 2015 Gabi Melman.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
//
#pragma once
//
// Global registry functions
//
#include "../details/registry.h"
#include "../sinks/file_sinks.h"
#include "../sinks/stdout_sinks.h"
#include "../spdlog.h"
#ifdef SPDLOG_ENABLE_SYSLOG
#include "../sinks/syslog_sink.h"
#endif
#if defined _WIN32 && !defined(__cplusplus_winrt)
#include "../sinks/wincolor_sink.h"
#else
#include "../sinks/ansicolor_sink.h"
#endif
#ifdef __ANDROID__
#include "../sinks/android_sink.h"
#endif
#include <chrono>
#include <functional>
#include <memory>
#include <string>
inline
void
spdlog
::
register_logger
(
std
::
shared_ptr
<
logger
>
logger
)
{
return
details
::
registry
::
instance
().
register_logger
(
std
::
move
(
logger
));
}
inline
std
::
shared_ptr
<
spdlog
::
logger
>
spdlog
::
get
(
const
std
::
string
&
name
)
{
return
details
::
registry
::
instance
().
get
(
name
);
}
inline
void
spdlog
::
drop
(
const
std
::
string
&
name
)
{
details
::
registry
::
instance
().
drop
(
name
);
}
// Create multi/single threaded simple file logger
inline
std
::
shared_ptr
<
spdlog
::
logger
>
spdlog
::
basic_logger_mt
(
const
std
::
string
&
logger_name
,
const
filename_t
&
filename
,
bool
truncate
)
{
return
create
<
spdlog
::
sinks
::
simple_file_sink_mt
>
(
logger_name
,
filename
,
truncate
);
}
inline
std
::
shared_ptr
<
spdlog
::
logger
>
spdlog
::
basic_logger_st
(
const
std
::
string
&
logger_name
,
const
filename_t
&
filename
,
bool
truncate
)
{
return
create
<
spdlog
::
sinks
::
simple_file_sink_st
>
(
logger_name
,
filename
,
truncate
);
}
// Create multi/single threaded rotating file logger
inline
std
::
shared_ptr
<
spdlog
::
logger
>
spdlog
::
rotating_logger_mt
(
const
std
::
string
&
logger_name
,
const
filename_t
&
filename
,
size_t
max_file_size
,
size_t
max_files
)
{
return
create
<
spdlog
::
sinks
::
rotating_file_sink_mt
>
(
logger_name
,
filename
,
max_file_size
,
max_files
);
}
inline
std
::
shared_ptr
<
spdlog
::
logger
>
spdlog
::
rotating_logger_st
(
const
std
::
string
&
logger_name
,
const
filename_t
&
filename
,
size_t
max_file_size
,
size_t
max_files
)
{
return
create
<
spdlog
::
sinks
::
rotating_file_sink_st
>
(
logger_name
,
filename
,
max_file_size
,
max_files
);
}
// Create file logger which creates new file at midnight):
inline
std
::
shared_ptr
<
spdlog
::
logger
>
spdlog
::
daily_logger_mt
(
const
std
::
string
&
logger_name
,
const
filename_t
&
filename
,
int
hour
,
int
minute
)
{
return
create
<
spdlog
::
sinks
::
daily_file_sink_mt
>
(
logger_name
,
filename
,
hour
,
minute
);
}
inline
std
::
shared_ptr
<
spdlog
::
logger
>
spdlog
::
daily_logger_st
(
const
std
::
string
&
logger_name
,
const
filename_t
&
filename
,
int
hour
,
int
minute
)
{
return
create
<
spdlog
::
sinks
::
daily_file_sink_st
>
(
logger_name
,
filename
,
hour
,
minute
);
}
//
// stdout/stderr loggers
//
inline
std
::
shared_ptr
<
spdlog
::
logger
>
spdlog
::
stdout_logger_mt
(
const
std
::
string
&
logger_name
)
{
return
spdlog
::
details
::
registry
::
instance
().
create
(
logger_name
,
spdlog
::
sinks
::
stdout_sink_mt
::
instance
());
}
inline
std
::
shared_ptr
<
spdlog
::
logger
>
spdlog
::
stdout_logger_st
(
const
std
::
string
&
logger_name
)
{
return
spdlog
::
details
::
registry
::
instance
().
create
(
logger_name
,
spdlog
::
sinks
::
stdout_sink_st
::
instance
());
}
inline
std
::
shared_ptr
<
spdlog
::
logger
>
spdlog
::
stderr_logger_mt
(
const
std
::
string
&
logger_name
)
{
return
spdlog
::
details
::
registry
::
instance
().
create
(
logger_name
,
spdlog
::
sinks
::
stderr_sink_mt
::
instance
());
}
inline
std
::
shared_ptr
<
spdlog
::
logger
>
spdlog
::
stderr_logger_st
(
const
std
::
string
&
logger_name
)
{
return
spdlog
::
details
::
registry
::
instance
().
create
(
logger_name
,
spdlog
::
sinks
::
stderr_sink_st
::
instance
());
}
//
// stdout/stderr color loggers
//
#if defined _WIN32 && !defined(__cplusplus_winrt)
inline
std
::
shared_ptr
<
spdlog
::
logger
>
spdlog
::
stdout_color_mt
(
const
std
::
string
&
logger_name
)
{
auto
sink
=
std
::
make_shared
<
spdlog
::
sinks
::
wincolor_stdout_sink_mt
>
();
return
spdlog
::
details
::
registry
::
instance
().
create
(
logger_name
,
sink
);
}
inline
std
::
shared_ptr
<
spdlog
::
logger
>
spdlog
::
stdout_color_st
(
const
std
::
string
&
logger_name
)
{
auto
sink
=
std
::
make_shared
<
spdlog
::
sinks
::
wincolor_stdout_sink_st
>
();
return
spdlog
::
details
::
registry
::
instance
().
create
(
logger_name
,
sink
);
}
inline
std
::
shared_ptr
<
spdlog
::
logger
>
spdlog
::
stderr_color_mt
(
const
std
::
string
&
logger_name
)
{
auto
sink
=
std
::
make_shared
<
spdlog
::
sinks
::
wincolor_stderr_sink_mt
>
();
return
spdlog
::
details
::
registry
::
instance
().
create
(
logger_name
,
sink
);
}
inline
std
::
shared_ptr
<
spdlog
::
logger
>
spdlog
::
stderr_color_st
(
const
std
::
string
&
logger_name
)
{
auto
sink
=
std
::
make_shared
<
spdlog
::
sinks
::
wincolor_stderr_sink_st
>
();
return
spdlog
::
details
::
registry
::
instance
().
create
(
logger_name
,
sink
);
}
#else // ansi terminal colors
inline
std
::
shared_ptr
<
spdlog
::
logger
>
spdlog
::
stdout_color_mt
(
const
std
::
string
&
logger_name
)
{
auto
sink
=
std
::
make_shared
<
spdlog
::
sinks
::
ansicolor_stdout_sink_mt
>
();
return
spdlog
::
details
::
registry
::
instance
().
create
(
logger_name
,
sink
);
}
inline
std
::
shared_ptr
<
spdlog
::
logger
>
spdlog
::
stdout_color_st
(
const
std
::
string
&
logger_name
)
{
auto
sink
=
std
::
make_shared
<
spdlog
::
sinks
::
ansicolor_stdout_sink_st
>
();
return
spdlog
::
details
::
registry
::
instance
().
create
(
logger_name
,
sink
);
}
inline
std
::
shared_ptr
<
spdlog
::
logger
>
spdlog
::
stderr_color_mt
(
const
std
::
string
&
logger_name
)
{
auto
sink
=
std
::
make_shared
<
spdlog
::
sinks
::
ansicolor_stderr_sink_mt
>
();
return
spdlog
::
details
::
registry
::
instance
().
create
(
logger_name
,
sink
);
}
inline
std
::
shared_ptr
<
spdlog
::
logger
>
spdlog
::
stderr_color_st
(
const
std
::
string
&
logger_name
)
{
auto
sink
=
std
::
make_shared
<
spdlog
::
sinks
::
ansicolor_stderr_sink_st
>
();
return
spdlog
::
details
::
registry
::
instance
().
create
(
logger_name
,
sink
);
}
#endif
#ifdef SPDLOG_ENABLE_SYSLOG
// Create syslog logger
inline
std
::
shared_ptr
<
spdlog
::
logger
>
spdlog
::
syslog_logger
(
const
std
::
string
&
logger_name
,
const
std
::
string
&
syslog_ident
,
int
syslog_option
,
int
syslog_facility
)
{
return
create
<
spdlog
::
sinks
::
syslog_sink
>
(
logger_name
,
syslog_ident
,
syslog_option
,
syslog_facility
);
}
#endif
#ifdef __ANDROID__
inline
std
::
shared_ptr
<
spdlog
::
logger
>
spdlog
::
android_logger
(
const
std
::
string
&
logger_name
,
const
std
::
string
&
tag
)
{
return
create
<
spdlog
::
sinks
::
android_sink
>
(
logger_name
,
tag
);
}
#endif
// Create and register a logger a single sink
inline
std
::
shared_ptr
<
spdlog
::
logger
>
spdlog
::
create
(
const
std
::
string
&
logger_name
,
const
spdlog
::
sink_ptr
&
sink
)
{
return
details
::
registry
::
instance
().
create
(
logger_name
,
sink
);
}
// Create logger with multiple sinks
inline
std
::
shared_ptr
<
spdlog
::
logger
>
spdlog
::
create
(
const
std
::
string
&
logger_name
,
spdlog
::
sinks_init_list
sinks
)
{
return
details
::
registry
::
instance
().
create
(
logger_name
,
sinks
);
}
template
<
typename
Sink
,
typename
...
Args
>
inline
std
::
shared_ptr
<
spdlog
::
logger
>
spdlog
::
create
(
const
std
::
string
&
logger_name
,
Args
...
args
)
{
sink_ptr
sink
=
std
::
make_shared
<
Sink
>
(
args
...);
return
details
::
registry
::
instance
().
create
(
logger_name
,
{
sink
});
}
template
<
class
It
>
inline
std
::
shared_ptr
<
spdlog
::
logger
>
spdlog
::
create
(
const
std
::
string
&
logger_name
,
const
It
&
sinks_begin
,
const
It
&
sinks_end
)
{
return
details
::
registry
::
instance
().
create
(
logger_name
,
sinks_begin
,
sinks_end
);
}
// Create and register an async logger with a single sink
inline
std
::
shared_ptr
<
spdlog
::
logger
>
spdlog
::
create_async
(
const
std
::
string
&
logger_name
,
const
sink_ptr
&
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
)
{
return
details
::
registry
::
instance
().
create_async
(
logger_name
,
queue_size
,
overflow_policy
,
worker_warmup_cb
,
flush_interval_ms
,
worker_teardown_cb
,
sink
);
}
// Create and register an async logger with multiple sinks
inline
std
::
shared_ptr
<
spdlog
::
logger
>
spdlog
::
create_async
(
const
std
::
string
&
logger_name
,
sinks_init_list
sinks
,
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
)
{
return
details
::
registry
::
instance
().
create_async
(
logger_name
,
queue_size
,
overflow_policy
,
worker_warmup_cb
,
flush_interval_ms
,
worker_teardown_cb
,
sinks
);
}
template
<
class
It
>
inline
std
::
shared_ptr
<
spdlog
::
logger
>
spdlog
::
create_async
(
const
std
::
string
&
logger_name
,
const
It
&
sinks_begin
,
const
It
&
sinks_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
)
{
return
details
::
registry
::
instance
().
create_async
(
logger_name
,
queue_size
,
overflow_policy
,
worker_warmup_cb
,
flush_interval_ms
,
worker_teardown_cb
,
sinks_begin
,
sinks_end
);
}
inline
void
spdlog
::
set_formatter
(
spdlog
::
formatter_ptr
f
)
{
details
::
registry
::
instance
().
formatter
(
std
::
move
(
f
));
}
inline
void
spdlog
::
set_pattern
(
const
std
::
string
&
format_string
)
{
return
details
::
registry
::
instance
().
set_pattern
(
format_string
);
}
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
(
std
::
move
(
handler
));
}
inline
void
spdlog
::
set_async_mode
(
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
)
{
details
::
registry
::
instance
().
set_async_mode
(
queue_size
,
overflow_policy
,
worker_warmup_cb
,
flush_interval_ms
,
worker_teardown_cb
);
}
inline
void
spdlog
::
set_sync_mode
()
{
details
::
registry
::
instance
().
set_sync_mode
();
}
inline
void
spdlog
::
apply_all
(
std
::
function
<
void
(
std
::
shared_ptr
<
logger
>
)
>
fun
)
{
details
::
registry
::
instance
().
apply_all
(
std
::
move
(
fun
));
}
inline
void
spdlog
::
drop_all
()
{
details
::
registry
::
instance
().
drop_all
();
}
//#pragma once
//
////
//// Global registry functions
////
//#include "../details/registry.h"
//#include "../sinks/file_sinks.h"
//#include "../sinks/stdout_sinks.h"
//#include "../spdlog.h"
//#ifdef SPDLOG_ENABLE_SYSLOG
//#include "../sinks/syslog_sink.h"
//#endif
//
//#if defined _WIN32 && !defined(__cplusplus_winrt)
//#include "../sinks/wincolor_sink.h"
//#else
//#include "../sinks/ansicolor_sink.h"
//#endif
//
//#ifdef __ANDROID__
//#include "../sinks/android_sink.h"
//#endif
//
//#include <chrono>
//#include <functional>
//#include <memory>
//#include <string>
//
// inline void spdlog::register_logger(std::shared_ptr<logger> logger)
//{
// return details::registry::instance().register_logger(std::move(logger));
//}
//
//
// inline void spdlog::drop(const std::string &name)
//{
// details::registry::instance().drop(name);
//}
//
//// Create multi/single threaded simple file logger
// inline std::shared_ptr<spdlog::logger> spdlog::basic_logger_mt(const std::string &logger_name, const filename_t &filename, bool truncate)
//{
// return create_and_register<sinks::simple_file_sink_mt>(logger_name, filename, truncate);
//}
//
// inline std::shared_ptr<spdlog::logger> spdlog::basic_logger_st(const std::string &logger_name, const filename_t &filename, bool truncate)
//{
// return create_and_register<sinks::simple_file_sink_st>(logger_name, filename, truncate);
//}
//
//// Create multi/single threaded rotating file logger
// inline std::shared_ptr<spdlog::logger> spdlog::rotating_logger_mt(
// const std::string &logger_name, const filename_t &filename, size_t max_file_size, size_t max_files)
//{
// return create_and_register<sinks::rotating_file_sink_mt>(logger_name, filename, max_file_size, max_files);
//}
//
// inline std::shared_ptr<spdlog::logger> spdlog::rotating_logger_st(
// const std::string &logger_name, const filename_t &filename, size_t max_file_size, size_t max_files)
//{
// return create_and_register<sinks::rotating_file_sink_st>(logger_name, filename, max_file_size, max_files);
//}
//
//// Create file logger which creates new file at midnight):
// inline std::shared_ptr<spdlog::logger> spdlog::daily_logger_mt(
// const std::string &logger_name, const filename_t &filename, int hour, int minute)
//{
// return create_and_register<sinks::daily_file_sink_mt>(logger_name, filename, hour, minute);
//}
//
// inline std::shared_ptr<spdlog::logger> spdlog::daily_logger_st(
// const std::string &logger_name, const filename_t &filename, int hour, int minute)
//{
// return create_and_register<sinks::daily_file_sink_st>(logger_name, filename, hour, minute);
//}
//
////
//// stdout/stderr loggers
////
// inline std::shared_ptr<spdlog::logger> spdlog::stdout_logger_mt(const std::string &logger_name)
//{
//
// auto new_logger = std::make_shared<logger>(logger_name, sinks::stdout_sink_mt::instance());
// details::registry::instance().register_and_init(new_logger);
// return new_logger;
// //return details::registry::instance().create(logger_name, sinks::stdout_sink_mt::instance());
//}
//
// inline std::shared_ptr<spdlog::logger> spdlog::stdout_logger_st(const std::string &logger_name)
//{
// auto new_logger = std::make_shared<logger>(logger_name, sinks::stdout_sink_st::instance());
// details::registry::instance().register_and_init(new_logger);
// return new_logger;
//}
//
// inline std::shared_ptr<spdlog::logger> spdlog::stderr_logger_mt(const std::string &logger_name)
//{
// auto new_logger = std::make_shared<logger>(logger_name, sinks::stderr_sink_mt::instance());
// details::registry::instance().register_and_init(new_logger);
// return new_logger;
//}
//
// inline std::shared_ptr<spdlog::logger> spdlog::stderr_logger_st(const std::string &logger_name)
//{
// auto new_logger = std::make_shared<logger>(logger_name, sinks::stderr_sink_st::instance());
// details::registry::instance().register_and_init(new_logger);
// return new_logger;
//}
//
////
//// stdout/stderr color loggers
////
//#if defined _WIN32 && !defined(__cplusplus_winrt)
//
// inline std::shared_ptr<spdlog::logger> spdlog::stdout_color_mt(const std::string &logger_name)
//{
// return create_and_register<sinks::wincolor_stdout_sink_mt>(logger_name);
//}
//
// inline std::shared_ptr<spdlog::logger> spdlog::stdout_color_st(const std::string &logger_name)
//{
// return create_and_register<sinks::wincolor_stdout_sink_st>(logger_name);
//}
//
// inline std::shared_ptr<spdlog::logger> spdlog::stderr_color_mt(const std::string &logger_name)
//{
// return create_and_register<sinks::wincolor_stderr_sink_mt>(logger_name);
//}
//
// inline std::shared_ptr<spdlog::logger> spdlog::stderr_color_st(const std::string &logger_name)
//{
//
// return create_and_register<sinks::wincolor_stderr_sink_st>(logger_name);
//}
//
//#else // ansi terminal colors
//
//
// inline std::shared_ptr<spdlog::logger> spdlog::stdout_color_mt(const std::string &logger_name)
//{
// return create_and_register<sinks::ansicolor_stdout_sink_mt>(logger_name);
//}
//
// inline std::shared_ptr<spdlog::logger> spdlog::stdout_color_st(const std::string &logger_name)
//{
// return create_and_register<sinks::ansicolor_stdout_sink_st>(logger_name);
//}
//
// inline std::shared_ptr<spdlog::logger> spdlog::stderr_color_mt(const std::string &logger_name)
//{
// return create_and_register<sinks::ansicolor_stderr_sink_mt>(logger_name);
//}
//
// inline std::shared_ptr<spdlog::logger> spdlog::stderr_color_st(const std::string &logger_name)
//{
// return create_and_register<sinks::ansicolor_stderr_sink_st>(logger_name);
//}
//#endif
//
//#ifdef SPDLOG_ENABLE_SYSLOG
//// Create syslog logger
// inline std::shared_ptr<spdlog::logger> spdlog::syslog_logger(
// const std::string &logger_name, const std::string &syslog_ident, int syslog_option, int syslog_facility) {
// return create_and_register<sinks::syslog_sink>(logger_name, syslog_ident, syslog_option, syslog_facility);
//}
//#endif
//
//#ifdef __ANDROID__
// inline std::shared_ptr<spdlog::logger> spdlog::android_logger(const std::string &logger_name, const std::string &tag)
//{
// return create_and_register<sinks::android_sink>(logger_name, tag);
//}
//#endif
//
//
//
//
// inline void spdlog::flush_on(level::level_enum log_level)
//{
// details::registry::instance().flush_on(log_level);
//}
//
// inline void spdlog::set_error_handler(log_err_handler handler)
//{
// details::registry::instance().set_error_handler(std::move(handler));
//}
//
// inline void spdlog::apply_all(std::function<void(std::shared_ptr<logger>)> fun)
//{
// details::registry::instance().apply_all(std::move(fun));
//}
//
// inline void spdlog::drop_all()
//{
// details::registry::instance().drop_all();
//}
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
//
// Copyright(c) 2015 Gabi Melman.
// Copyright(c) 2015
-2018
Gabi Melman.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
//
// spdlog main header file.
...
...
@@ -7,9 +7,23 @@
#pragma once
#include "details/registry.h"
#include "sinks/file_sinks.h"
#include "sinks/stdout_sinks.h"
#include "common.h"
#include "logger.h"
#if defined _WIN32
#include "sinks/wincolor_sink.h"
#else
#include "sinks/ansicolor_sink.h"
#endif
#ifdef __ANDROID__
#include "sinks/android_sink.h"
#endif
#include <chrono>
#include <functional>
#include <memory>
...
...
@@ -17,157 +31,213 @@
namespace
spdlog
{
// Default logger factory- creates synchronous loggers
struct
default_factory
{
template
<
typename
Sink
,
typename
...
SinkArgs
>
static
std
::
shared_ptr
<
spdlog
::
logger
>
create
(
const
std
::
string
&
logger_name
,
SinkArgs
&&
...
args
)
{
auto
sink
=
std
::
make_shared
<
Sink
>
(
std
::
forward
<
SinkArgs
>
(
args
)...);
auto
new_logger
=
std
::
make_shared
<
logger
>
(
logger_name
,
std
::
move
(
sink
));
details
::
registry
::
instance
().
register_and_init
(
new_logger
);
return
new_logger
;
}
};
// Create and register a logger with a templated sink type
// The logger's level, formatter and flush level will be set according the global settings.
// Example:
// spdlog::create<daily_file_sink_st>("logger_name", "dailylog_filename", 11, 59);
template
<
typename
Sink
,
typename
...
SinkArgs
>
inline
std
::
shared_ptr
<
spdlog
::
logger
>
create
(
const
std
::
string
&
logger_name
,
SinkArgs
&&
...
sink_args
)
{
return
default_factory
::
create
<
Sink
>
(
logger_name
,
std
::
forward
<
SinkArgs
>
(
sink_args
)...);
}
//
// Return an existing logger or nullptr if a logger with such name doesn't exist.
// example: spdlog::get("my_logger")->info("hello {}", "world");
//
std
::
shared_ptr
<
logger
>
get
(
const
std
::
string
&
name
);
inline
std
::
shared_ptr
<
logger
>
get
(
const
std
::
string
&
name
)
{
return
details
::
registry
::
instance
().
get
(
name
);
}
//
// Set global formatting
// example: spdlog::set_pattern("%Y-%m-%d %H:%M:%S.%e %l : %v");
//
void
set_pattern
(
const
std
::
string
&
format_string
);
void
set_formatter
(
formatter_ptr
f
);
inline
void
set_pattern
(
const
std
::
string
&
format_string
)
{
details
::
registry
::
instance
().
set_pattern
(
format_string
);
}
inline
void
set_formatter
(
formatter_ptr
f
)
{
details
::
registry
::
instance
().
set_formatter
(
std
::
move
(
f
));
}
//
// Set global logging level
//
void
set_level
(
level
::
level_enum
log_level
);
inline
void
set_level
(
level
::
level_enum
log_level
)
{
details
::
registry
::
instance
().
set_level
(
log_level
);
}
//
// Set global flush level
//
void
flush_on
(
level
::
level_enum
log_level
);
inline
void
flush_on
(
level
::
level_enum
log_level
)
{
details
::
registry
::
instance
().
flush_on
(
log_level
);
}
//
// Set global error handler
//
void
set_error_handler
(
log_err_handler
handler
);
inline
void
set_error_handler
(
log_err_handler
handler
)
{
details
::
registry
::
instance
().
set_error_handler
(
std
::
move
(
handler
));
}
//
// Turn on async mode (off by default) and set the queue size for each async_logger.
// effective only for loggers created after this call.
// queue_size: size of queue (must be power of 2):
// Each logger will pre-allocate a dedicated queue with queue_size entries upon construction.
//
// async_overflow_policy (optional, block_retry by default):
// async_overflow_policy::block_retry - if queue is full, block until queue has room for the new log entry.
// async_overflow_policy::discard_log_msg - never block and discard any new messages when queue overflows.
//
// worker_warmup_cb (optional):
// callback function that will be called in worker thread upon start (can be used to init stuff like thread affinity)
//
// worker_teardown_cb (optional):
// callback function that will be called in worker thread upon exit
//
void
set_async_mode
(
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
);
// Register the given logger with the given name
inline
void
register_logger
(
std
::
shared_ptr
<
logger
>
logger
)
{
details
::
registry
::
instance
().
register_logger
(
std
::
move
(
logger
));
}
// Apply a user defined function on all registered loggers
// Example:
// spdlog::apply_all([&](std::shared_ptr<spdlog::logger> l) {l->flush();});
inline
void
apply_all
(
std
::
function
<
void
(
std
::
shared_ptr
<
logger
>
)
>
fun
)
{
details
::
registry
::
instance
().
apply_all
(
std
::
move
(
fun
));
}
// Drop the reference to the given logger
inline
void
drop
(
const
std
::
string
&
name
)
{
details
::
registry
::
instance
().
drop
(
name
);
}
// Turn off async mode
void
set_sync_mode
();
// Drop all references from the registry
inline
void
drop_all
()
{
details
::
registry
::
instance
().
drop_all
();
}
//
// Create and register multi/single threaded basic file logger.
// Basic logger simply writes to given file without any limitations or rotations.
//
std
::
shared_ptr
<
logger
>
basic_logger_mt
(
const
std
::
string
&
logger_name
,
const
filename_t
&
filename
,
bool
truncate
=
false
);
std
::
shared_ptr
<
logger
>
basic_logger_st
(
const
std
::
string
&
logger_name
,
const
filename_t
&
filename
,
bool
truncate
=
false
);
template
<
typename
Factory
=
default_factory
>
inline
std
::
shared_ptr
<
logger
>
basic_logger_mt
(
const
std
::
string
&
logger_name
,
const
filename_t
&
filename
,
bool
truncate
=
false
)
{
return
Factory
::
template
create
<
sinks
::
simple_file_sink_mt
>
(
logger_name
,
filename
,
truncate
);
}
template
<
typename
Factory
=
default_factory
>
inline
std
::
shared_ptr
<
logger
>
basic_logger_st
(
const
std
::
string
&
logger_name
,
const
filename_t
&
filename
,
bool
truncate
=
false
)
{
return
Factory
::
template
create
<
sinks
::
simple_file_sink_st
>
(
logger_name
,
filename
,
truncate
);
}
//
// Create and register multi/single threaded rotating file logger
//
std
::
shared_ptr
<
logger
>
rotating_logger_mt
(
const
std
::
string
&
logger_name
,
const
filename_t
&
filename
,
size_t
max_file_size
,
size_t
max_files
);
std
::
shared_ptr
<
logger
>
rotating_logger_st
(
const
std
::
string
&
logger_name
,
const
filename_t
&
filename
,
size_t
max_file_size
,
size_t
max_files
);
template
<
typename
Factory
=
default_factory
>
inline
std
::
shared_ptr
<
logger
>
rotating_logger_mt
(
const
std
::
string
&
logger_name
,
const
filename_t
&
filename
,
size_t
max_file_size
,
size_t
max_files
)
{
return
Factory
::
template
create
<
sinks
::
rotating_file_sink_mt
>
(
logger_name
,
filename
,
max_file_size
,
max_files
);
}
template
<
typename
Factory
=
default_factory
>
inline
std
::
shared_ptr
<
logger
>
rotating_logger_st
(
const
std
::
string
&
logger_name
,
const
filename_t
&
filename
,
size_t
max_file_size
,
size_t
max_files
)
{
return
Factory
::
template
create
<
sinks
::
rotating_file_sink_st
>
(
logger_name
,
filename
,
max_file_size
,
max_files
);
}
//
// Create file logger which creates new file on the given time (default in midnight):
//
std
::
shared_ptr
<
logger
>
daily_logger_mt
(
const
std
::
string
&
logger_name
,
const
filename_t
&
filename
,
int
hour
=
0
,
int
minute
=
0
);
std
::
shared_ptr
<
logger
>
daily_logger_st
(
const
std
::
string
&
logger_name
,
const
filename_t
&
filename
,
int
hour
=
0
,
int
minute
=
0
);
template
<
typename
Factory
=
default_factory
>
inline
std
::
shared_ptr
<
logger
>
daily_logger_mt
(
const
std
::
string
&
logger_name
,
const
filename_t
&
filename
,
int
hour
=
0
,
int
minute
=
0
)
{
return
Factory
::
template
create
<
sinks
::
daily_file_sink_mt
>
(
logger_name
,
filename
,
hour
,
minute
);
}
template
<
typename
Factory
=
default_factory
>
inline
std
::
shared_ptr
<
logger
>
daily_logger_st
(
const
std
::
string
&
logger_name
,
const
filename_t
&
filename
,
int
hour
=
0
,
int
minute
=
0
)
{
return
Factory
::
template
create
<
sinks
::
daily_file_sink_st
>
(
logger_name
,
filename
,
hour
,
minute
);
}
///////////////////////////////////////////////////////////////////////////////
// stdout and stderr loggers
//
// Create and register stdout/stderr loggers
// multi threaded and colored:
// spdlog::console<stdout_color_mt>("name")
// spdlog::console<stderr_color_mt>("name")
//
std
::
shared_ptr
<
logger
>
stdout_logger_mt
(
const
std
::
string
&
logger_name
);
std
::
shared_ptr
<
logger
>
stdout_logger_st
(
const
std
::
string
&
logger_name
);
std
::
shared_ptr
<
logger
>
stderr_logger_mt
(
const
std
::
string
&
logger_name
);
std
::
shared_ptr
<
logger
>
stderr_logger_st
(
const
std
::
string
&
logger_name
);
// single threaded and colored:
// spdlog::console<stdout_color_st>("name")
// spdlog::console<stderr_color_st>("name")
//
// Create and register colored stdout/stderr loggers
// multi threaded, no color:
// spdlog::console<stdout_mt>("name")
// spdlog::console<stderr_mt>("name")
//
std
::
shared_ptr
<
logger
>
stdout_color_mt
(
const
std
::
string
&
logger_name
);
std
::
shared_ptr
<
logger
>
stdout_color_st
(
const
std
::
string
&
logger_name
);
std
::
shared_ptr
<
logger
>
stderr_color_mt
(
const
std
::
string
&
logger_name
);
std
::
shared_ptr
<
logger
>
stderr_color_st
(
const
std
::
string
&
logger_name
);
// single threaded, no color:
// spdlog::console<stdout_st>("name")
// spdlog::console<stderr_st>("name")
///////////////////////////////////////////////////////////////////////////////
#if defined _WIN32 // window color console
using
stdout_color_mt
=
sinks
::
wincolor_stdout_sink_mt
;
using
stdout_color_st
=
sinks
::
wincolor_stdout_sink_st
;
using
stderr_color_mt
=
sinks
::
wincolor_stderr_sink_mt
;
using
stderr_color_st
=
sinks
::
wincolor_stderr_sink_st
;
#else // ansi color console
using
stdout_color_mt
=
sinks
::
ansicolor_stdout_sink_mt
;
using
stdout_color_st
=
sinks
::
ansicolor_stdout_sink_st
;
using
stderr_color_mt
=
sinks
::
ansicolor_stderr_sink_mt
;
using
stderr_color_st
=
sinks
::
ansicolor_stderr_sink_st
;
#endif
// no color console
using
stdout_mt
=
sinks
::
stdout_sink_mt
;
using
stdout_st
=
sinks
::
stdout_sink_st
;
using
stderr_mt
=
sinks
::
stderr_sink_mt
;
using
stderr_st
=
sinks
::
stderr_sink_st
;
template
<
typename
Sink
,
typename
Factory
=
default_factory
>
inline
std
::
shared_ptr
<
logger
>
console
(
const
std
::
string
&
logger_name
)
{
return
Factory
::
template
create
<
Sink
>
(
logger_name
);
}
//
// Create and register a syslog logger
//
#ifdef SPDLOG_ENABLE_SYSLOG
std
::
shared_ptr
<
logger
>
syslog_logger
(
const
std
::
string
&
logger_name
,
const
std
::
string
&
ident
=
""
,
int
syslog_option
=
0
,
int
syslog_facilty
=
(
1
<<
3
));
// Create and register a syslog logger
template
<
typename
Factory
=
default_factory
>
inline
std
::
shared_ptr
<
logger
>
syslog_logger
(
const
std
::
string
&
logger_name
,
const
std
::
string
&
ident
=
""
,
int
syslog_option
=
0
,
int
syslog_facilty
=
(
1
<<
3
))
{
return
return
Factory
::
template
create
<
sinks
::
syslog_sink
>
(
logger_name
,
syslog_ident
,
syslog_option
,
syslog_facility
);
}
#endif
#if defined(__ANDROID__)
std
::
shared_ptr
<
logger
>
android_logger
(
const
std
::
string
&
logger_name
,
const
std
::
string
&
tag
=
"spdlog"
);
// Create and register android syslog logger
template
<
typename
Factory
=
default_factory
>
inline
std
::
shared_ptr
<
logger
>
android_logger
(
const
std
::
string
&
logger_name
,
const
std
::
string
&
tag
=
"spdlog"
)
{
return
return
Factory
::
template
create
<
sinks
::
android_sink
>
(
logger_name
,
tag
);
}
#endif
// Create and register a logger with a single sink
std
::
shared_ptr
<
logger
>
create
(
const
std
::
string
&
logger_name
,
const
sink_ptr
&
sink
);
// Create and register a logger with multiple sinks
std
::
shared_ptr
<
logger
>
create
(
const
std
::
string
&
logger_name
,
sinks_init_list
sinks
);
template
<
class
It
>
std
::
shared_ptr
<
logger
>
create
(
const
std
::
string
&
logger_name
,
const
It
&
sinks_begin
,
const
It
&
sinks_end
);
// Create and register a logger with templated sink type
// Example:
// spdlog::create<daily_file_sink_st>("mylog", "dailylog_filename");
template
<
typename
Sink
,
typename
...
Args
>
std
::
shared_ptr
<
spdlog
::
logger
>
create
(
const
std
::
string
&
logger_name
,
Args
...
args
);
// Create and register an async logger with a single sink
std
::
shared_ptr
<
logger
>
create_async
(
const
std
::
string
&
logger_name
,
const
sink_ptr
&
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
);
// Create and register an async logger with multiple sinks
std
::
shared_ptr
<
logger
>
create_async
(
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
);
template
<
class
It
>
std
::
shared_ptr
<
logger
>
create_async
(
const
std
::
string
&
logger_name
,
const
It
&
sinks_begin
,
const
It
&
sinks_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
);
// Register the given logger with the given name
void
register_logger
(
std
::
shared_ptr
<
logger
>
logger
);
// Apply a user defined function on all registered loggers
// Example:
// spdlog::apply_all([&](std::shared_ptr<spdlog::logger> l) {l->flush();});
void
apply_all
(
std
::
function
<
void
(
std
::
shared_ptr
<
logger
>
)
>
fun
);
// Drop the reference to the given logger
void
drop
(
const
std
::
string
&
name
);
// Drop all references from the registry
void
drop_all
();
///////////////////////////////////////////////////////////////////////////////
//
// Trace & Debug can be switched on/off at compile time for zero cost debug statements.
...
...
@@ -200,5 +270,3 @@ void drop_all();
#endif
}
// namespace spdlog
#include "details/spdlog_impl.h"
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