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