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
2de924a1
Commit
2de924a1
authored
Apr 26, 2019
by
gabime
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
clang-format
parent
c1c2ff2d
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
684 additions
and
705 deletions
+684
-705
async_logger.h
include/spdlog/async_logger.h
+0
-3
common.h
include/spdlog/common.h
+0
-1
file_helper.h
include/spdlog/details/file_helper.h
+8
-8
log_msg.h
include/spdlog/details/log_msg.h
+2
-2
pattern_formatter.h
include/spdlog/details/pattern_formatter.h
+8
-13
registry.h
include/spdlog/details/registry.h
+24
-24
async_logger.cpp
include/spdlog/impl/async_logger.cpp
+8
-12
file_helper.cpp
include/spdlog/impl/file_helper.cpp
+83
-84
log_msg.cpp
include/spdlog/impl/log_msg.cpp
+5
-7
logger.cpp
include/spdlog/impl/logger.cpp
+5
-5
pattern_formatter.cpp
include/spdlog/impl/pattern_formatter.cpp
+256
-260
registry.cpp
include/spdlog/impl/registry.cpp
+0
-1
sink.cpp
include/spdlog/impl/sink.cpp
+31
-29
logger.h
include/spdlog/logger.h
+247
-250
sink.h
include/spdlog/sinks/sink.h
+3
-3
spdlog.h
include/spdlog/spdlog.h
+2
-1
test_misc.cpp
tests/test_misc.cpp
+2
-2
No files found.
include/spdlog/async_logger.h
View file @
2de924a1
...
...
@@ -19,7 +19,6 @@
// Upon destruction, logs all remaining messages in the queue before
// destructing..
#include "spdlog/logger.h"
namespace
spdlog
{
...
...
@@ -69,5 +68,3 @@ private:
#ifdef SPDLOG_HEADER_ONLY
#include "spdlog/impl/async_logger.cpp"
#endif // SPDLOG_HEADER_ONLY
include/spdlog/common.h
View file @
2de924a1
...
...
@@ -70,7 +70,6 @@
#define SPDLOG_FUNCTION __FUNCTION__
#endif
namespace
spdlog
{
class
formatter
;
...
...
include/spdlog/details/file_helper.h
View file @
2de924a1
...
...
@@ -24,17 +24,17 @@ public:
file_helper
(
const
file_helper
&
)
=
delete
;
file_helper
&
operator
=
(
const
file_helper
&
)
=
delete
;
~
file_helper
();
~
file_helper
();
void
open
(
const
filename_t
&
fname
,
bool
truncate
=
false
);
void
reopen
(
bool
truncate
);
void
flush
();
void
close
();
void
open
(
const
filename_t
&
fname
,
bool
truncate
=
false
);
void
reopen
(
bool
truncate
);
void
flush
();
void
close
();
void
write
(
const
fmt
::
memory_buffer
&
buf
);
size_t
size
()
const
;
size_t
size
()
const
;
const
filename_t
&
filename
()
const
;
static
bool
file_exists
(
const
filename_t
&
fname
);
//
// return file path and its extension:
//
...
...
@@ -57,6 +57,6 @@ private:
}
// namespace details
}
// namespace spdlog
#ifdef
SPDLOG_HEADER_ONLY
#ifdef SPDLOG_HEADER_ONLY
#include "spdlog/impl/file_helper.cpp"
#endif // ! SPDLOG_HEADER_ONLY
include/spdlog/details/log_msg.h
View file @
2de924a1
...
...
@@ -13,7 +13,7 @@ namespace details {
struct
log_msg
{
log_msg
(
source_loc
loc
,
const
std
::
string
*
loggers_name
,
level
::
level_enum
lvl
,
string_view_t
view
);
log_msg
(
const
std
::
string
*
loggers_name
,
level
::
level_enum
lvl
,
string_view_t
view
);
log_msg
(
const
log_msg
&
other
)
=
default
;
...
...
@@ -33,6 +33,6 @@ struct log_msg
}
// namespace details
}
// namespace spdlog
#ifdef
SPDLOG_HEADER_ONLY
#ifdef SPDLOG_HEADER_ONLY
#include "spdlog/impl/log_msg.cpp"
#endif // SPDLOG_HEADER_ONLY
include/spdlog/details/pattern_formatter.h
View file @
2de924a1
...
...
@@ -20,7 +20,6 @@
namespace
spdlog
{
namespace
details
{
// padding information.
struct
padding_info
{
...
...
@@ -61,26 +60,22 @@ protected:
padding_info
padinfo_
;
};
}
}
// namespace details
class
pattern_formatter
final
:
public
formatter
{
public
:
explicit
pattern_formatter
(
std
::
string
pattern
,
pattern_time_type
time_type
=
pattern_time_type
::
local
,
std
::
string
eol
=
spdlog
::
details
::
os
::
default_eol
);
std
::
string
pattern
,
pattern_time_type
time_type
=
pattern_time_type
::
local
,
std
::
string
eol
=
spdlog
::
details
::
os
::
default_eol
);
// use default pattern is not given
explicit
pattern_formatter
(
pattern_time_type
time_type
=
pattern_time_type
::
local
,
std
::
string
eol
=
spdlog
::
details
::
os
::
default_eol
);
explicit
pattern_formatter
(
pattern_time_type
time_type
=
pattern_time_type
::
local
,
std
::
string
eol
=
spdlog
::
details
::
os
::
default_eol
);
pattern_formatter
(
const
pattern_formatter
&
other
)
=
delete
;
pattern_formatter
&
operator
=
(
const
pattern_formatter
&
other
)
=
delete
;
std
::
unique_ptr
<
formatter
>
clone
()
const
override
;
void
format
(
const
details
::
log_msg
&
msg
,
fmt
::
memory_buffer
&
dest
)
override
;
void
format
(
const
details
::
log_msg
&
msg
,
fmt
::
memory_buffer
&
dest
)
override
;
private
:
std
::
string
pattern_
;
...
...
@@ -89,15 +84,15 @@ private:
std
::
tm
cached_tm_
;
std
::
chrono
::
seconds
last_log_secs_
;
std
::
vector
<
std
::
unique_ptr
<
details
::
flag_formatter
>>
formatters_
;
std
::
tm
get_time_
(
const
details
::
log_msg
&
msg
);
std
::
tm
get_time_
(
const
details
::
log_msg
&
msg
);
void
handle_flag_
(
char
flag
,
details
::
padding_info
padding
);
// Extract given pad spec (e.g. %8X)
// Advance the given it pass the end of the padding spec found (if any)
// Return padding.
details
::
padding_info
handle_padspec_
(
std
::
string
::
const_iterator
&
it
,
std
::
string
::
const_iterator
end
);
void
compile_pattern_
(
const
std
::
string
&
pattern
);
};
}
// namespace spdlog
...
...
include/spdlog/details/registry.h
View file @
2de924a1
...
...
@@ -32,59 +32,59 @@ public:
registry
(
const
registry
&
)
=
delete
;
registry
&
operator
=
(
const
registry
&
)
=
delete
;
void
register_logger
(
std
::
shared_ptr
<
logger
>
new_logger
);
void
initialize_logger
(
std
::
shared_ptr
<
logger
>
new_logger
);
std
::
shared_ptr
<
logger
>
get
(
const
std
::
string
&
logger_name
);
void
register_logger
(
std
::
shared_ptr
<
logger
>
new_logger
);
void
initialize_logger
(
std
::
shared_ptr
<
logger
>
new_logger
);
std
::
shared_ptr
<
logger
>
get
(
const
std
::
string
&
logger_name
);
std
::
shared_ptr
<
logger
>
default_logger
();
// Return raw ptr to the default logger.
// To be used directly by the spdlog default api (e.g. spdlog::info)
// This make the default API faster, but cannot be used concurrently with set_default_logger().
// e.g do not call set_default_logger() from one thread while calling spdlog::info() from another.
logger
*
get_default_raw
();
// set default logger.
// default logger is stored in default_logger_ (for faster retrieval) and in the loggers_ map.
void
set_default_logger
(
std
::
shared_ptr
<
logger
>
new_default_logger
);
void
set_tp
(
std
::
shared_ptr
<
thread_pool
>
tp
);
std
::
shared_ptr
<
thread_pool
>
get_tp
();
// Set global formatter. Each sink in each logger will get a clone of this object
void
set_formatter
(
std
::
unique_ptr
<
formatter
>
formatter
);
void
set_formatter
(
std
::
unique_ptr
<
formatter
>
formatter
);
void
set_level
(
level
::
level_enum
log_level
);
void
flush_on
(
level
::
level_enum
log_level
);
void
flush_every
(
std
::
chrono
::
seconds
interval
);
void
set_error_handler
(
void
(
*
handler
)(
const
std
::
string
&
msg
));
void
apply_all
(
const
std
::
function
<
void
(
const
std
::
shared_ptr
<
logger
>
)
>
&
fun
);
void
flush_all
();
void
drop
(
const
std
::
string
&
logger_name
);
void
drop_all
();
void
drop_all
();
// clean all resources and threads started by the registry
void
shutdown
();
void
shutdown
();
std
::
recursive_mutex
&
tp_mutex
();
std
::
recursive_mutex
&
tp_mutex
();
void
set_automatic_registration
(
bool
automatic_regsistration
);
static
registry
&
instance
();
static
registry
&
instance
();
private
:
registry
();
registry
();
~
registry
()
=
default
;
void
throw_if_exists_
(
const
std
::
string
&
logger_name
);
void
register_logger_
(
std
::
shared_ptr
<
logger
>
new_logger
);
void
throw_if_exists_
(
const
std
::
string
&
logger_name
);
void
register_logger_
(
std
::
shared_ptr
<
logger
>
new_logger
);
std
::
mutex
logger_map_mutex_
,
flusher_mutex_
;
std
::
recursive_mutex
tp_mutex_
;
std
::
unordered_map
<
std
::
string
,
std
::
shared_ptr
<
logger
>>
loggers_
;
...
...
include/spdlog/impl/async_logger.cpp
View file @
2de924a1
...
...
@@ -2,7 +2,6 @@
#include "spdlog/async_logger.h"
#endif
// async logger implementation
// uses a thread pool to perform the actual logging
...
...
@@ -15,22 +14,22 @@
template
<
typename
It
>
SPDLOG_INLINE
spdlog
::
async_logger
::
async_logger
(
std
::
string
logger_name
,
It
begin
,
It
end
,
std
::
weak_ptr
<
details
::
thread_pool
>
tp
,
async_overflow_policy
overflow_policy
)
:
logger
(
std
::
move
(
logger_name
),
begin
,
end
)
,
thread_pool_
(
std
::
move
(
tp
))
,
overflow_policy_
(
overflow_policy
)
std
::
string
logger_name
,
It
begin
,
It
end
,
std
::
weak_ptr
<
details
::
thread_pool
>
tp
,
async_overflow_policy
overflow_policy
)
:
logger
(
std
::
move
(
logger_name
),
begin
,
end
)
,
thread_pool_
(
std
::
move
(
tp
))
,
overflow_policy_
(
overflow_policy
)
{
}
SPDLOG_INLINE
spdlog
::
async_logger
::
async_logger
(
std
::
string
logger_name
,
sinks_init_list
sinks_list
,
std
::
weak_ptr
<
details
::
thread_pool
>
tp
,
async_overflow_policy
overflow_policy
)
:
async_logger
(
std
::
move
(
logger_name
),
sinks_list
.
begin
(),
sinks_list
.
end
(),
std
::
move
(
tp
),
overflow_policy
)
std
::
string
logger_name
,
sinks_init_list
sinks_list
,
std
::
weak_ptr
<
details
::
thread_pool
>
tp
,
async_overflow_policy
overflow_policy
)
:
async_logger
(
std
::
move
(
logger_name
),
sinks_list
.
begin
(),
sinks_list
.
end
(),
std
::
move
(
tp
),
overflow_policy
)
{
}
SPDLOG_INLINE
spdlog
::
async_logger
::
async_logger
(
std
::
string
logger_name
,
sink_ptr
single_sink
,
std
::
weak_ptr
<
details
::
thread_pool
>
tp
,
async_overflow_policy
overflow_policy
)
:
async_logger
(
std
::
move
(
logger_name
),
{
std
::
move
(
single_sink
)},
std
::
move
(
tp
),
overflow_policy
)
std
::
string
logger_name
,
sink_ptr
single_sink
,
std
::
weak_ptr
<
details
::
thread_pool
>
tp
,
async_overflow_policy
overflow_policy
)
:
async_logger
(
std
::
move
(
logger_name
),
{
std
::
move
(
single_sink
)},
std
::
move
(
tp
),
overflow_policy
)
{
}
...
...
@@ -118,6 +117,3 @@ SPDLOG_INLINE std::shared_ptr<spdlog::logger> spdlog::async_logger::clone(std::s
cloned
->
set_error_handler
(
this
->
custom_err_handler_
);
return
std
::
move
(
cloned
);
}
include/spdlog/impl/file_helper.cpp
View file @
2de924a1
...
...
@@ -17,116 +17,115 @@
#include <tuple>
namespace
spdlog
{
namespace
details
namespace
details
{
SPDLOG_INLINE
file_helper
::~
file_helper
()
{
SPDLOG_INLINE
file_helper
::~
file_helper
()
{
close
();
}
close
();
}
SPDLOG_INLINE
void
file_helper
::
open
(
const
filename_t
&
fname
,
bool
truncate
)
SPDLOG_INLINE
void
file_helper
::
open
(
const
filename_t
&
fname
,
bool
truncate
)
{
close
();
auto
*
mode
=
truncate
?
SPDLOG_FILENAME_T
(
"wb"
)
:
SPDLOG_FILENAME_T
(
"ab"
);
_filename
=
fname
;
for
(
int
tries
=
0
;
tries
<
open_tries
;
++
tries
)
{
close
();
auto
*
mode
=
truncate
?
SPDLOG_FILENAME_T
(
"wb"
)
:
SPDLOG_FILENAME_T
(
"ab"
);
_filename
=
fname
;
for
(
int
tries
=
0
;
tries
<
open_tries
;
++
tries
)
if
(
!
os
::
fopen_s
(
&
fd_
,
fname
,
mode
))
{
if
(
!
os
::
fopen_s
(
&
fd_
,
fname
,
mode
))
{
return
;
}
details
::
os
::
sleep_for_millis
(
open_interval
);
return
;
}
throw
spdlog_ex
(
"Failed opening file "
+
os
::
filename_to_str
(
_filename
)
+
" for writing"
,
errno
);
details
::
os
::
sleep_for_millis
(
open_interval
);
}
SPDLOG_INLINE
void
file_helper
::
reopen
(
bool
truncate
)
{
if
(
_filename
.
empty
())
{
throw
spdlog_ex
(
"Failed re opening file - was not opened before"
);
}
open
(
_filename
,
truncate
);
}
throw
spdlog_ex
(
"Failed opening file "
+
os
::
filename_to_str
(
_filename
)
+
" for writing"
,
errno
);
}
SPDLOG_INLINE
void
file_helper
::
flush
()
SPDLOG_INLINE
void
file_helper
::
reopen
(
bool
truncate
)
{
if
(
_filename
.
empty
())
{
std
::
fflush
(
fd_
);
throw
spdlog_ex
(
"Failed re opening file - was not opened before"
);
}
open
(
_filename
,
truncate
);
}
SPDLOG_INLINE
void
file_helper
::
close
()
{
if
(
fd_
!=
nullptr
)
{
std
::
fclose
(
fd_
);
fd_
=
nullptr
;
}
}
SPDLOG_INLINE
void
file_helper
::
flush
()
{
std
::
fflush
(
fd_
);
}
SPDLOG_INLINE
void
file_helper
::
write
(
const
fmt
::
memory_buffer
&
buf
)
SPDLOG_INLINE
void
file_helper
::
close
()
{
if
(
fd_
!=
nullptr
)
{
size_t
msg_size
=
buf
.
size
();
auto
data
=
buf
.
data
();
if
(
std
::
fwrite
(
data
,
1
,
msg_size
,
fd_
)
!=
msg_size
)
{
throw
spdlog_ex
(
"Failed writing to file "
+
os
::
filename_to_str
(
_filename
),
errno
);
}
std
::
fclose
(
fd_
);
fd_
=
nullptr
;
}
}
SPDLOG_INLINE
size_t
file_helper
::
size
()
const
SPDLOG_INLINE
void
file_helper
::
write
(
const
fmt
::
memory_buffer
&
buf
)
{
size_t
msg_size
=
buf
.
size
();
auto
data
=
buf
.
data
();
if
(
std
::
fwrite
(
data
,
1
,
msg_size
,
fd_
)
!=
msg_size
)
{
if
(
fd_
==
nullptr
)
{
throw
spdlog_ex
(
"Cannot use size() on closed file "
+
os
::
filename_to_str
(
_filename
));
}
return
os
::
filesize
(
fd_
);
throw
spdlog_ex
(
"Failed writing to file "
+
os
::
filename_to_str
(
_filename
),
errno
);
}
}
SPDLOG_INLINE
const
filename_t
&
file_helper
::
filename
()
const
SPDLOG_INLINE
size_t
file_helper
::
size
()
const
{
if
(
fd_
==
nullptr
)
{
return
_filename
;
throw
spdlog_ex
(
"Cannot use size() on closed file "
+
os
::
filename_to_str
(
_filename
))
;
}
return
os
::
filesize
(
fd_
);
}
SPDLOG_INLINE
bool
file_helper
::
file_exists
(
const
filename_t
&
fname
)
{
return
os
::
file_exists
(
fname
)
;
}
SPDLOG_INLINE
const
filename_t
&
file_helper
::
filename
()
const
{
return
_filename
;
}
//
// return file path and its extension:
//
// "mylog.txt" => ("mylog", ".txt")
// "mylog" => ("mylog", "")
// "mylog." => ("mylog.", "")
// "/dir1/dir2/mylog.txt" => ("/dir1/dir2/mylog", ".txt")
//
// the starting dot in filenames is ignored (hidden files):
//
// ".mylog" => (".mylog". "")
// "my_folder/.mylog" => ("my_folder/.mylog", "")
// "my_folder/.mylog.txt" => ("my_folder/.mylog", ".txt")
SPDLOG_INLINE
std
::
tuple
<
filename_t
,
filename_t
>
file_helper
::
split_by_extension
(
const
filename_t
&
fname
)
{
auto
ext_index
=
fname
.
rfind
(
'.'
);
SPDLOG_INLINE
bool
file_helper
::
file_exists
(
const
filename_t
&
fname
)
{
return
os
::
file_exists
(
fname
);
}
// no valid extension found - return whole path and empty string as
// extension
if
(
ext_index
==
filename_t
::
npos
||
ext_index
==
0
||
ext_index
==
fname
.
size
()
-
1
)
{
return
std
::
make_tuple
(
fname
,
filename_t
());
}
//
// return file path and its extension:
//
// "mylog.txt" => ("mylog", ".txt")
// "mylog" => ("mylog", "")
// "mylog." => ("mylog.", "")
// "/dir1/dir2/mylog.txt" => ("/dir1/dir2/mylog", ".txt")
//
// the starting dot in filenames is ignored (hidden files):
//
// ".mylog" => (".mylog". "")
// "my_folder/.mylog" => ("my_folder/.mylog", "")
// "my_folder/.mylog.txt" => ("my_folder/.mylog", ".txt")
SPDLOG_INLINE
std
::
tuple
<
filename_t
,
filename_t
>
file_helper
::
split_by_extension
(
const
filename_t
&
fname
)
{
auto
ext_index
=
fname
.
rfind
(
'.'
);
// treat casese like "/etc/rc.d/somelogfile or "/abc/.hiddenfile"
auto
folder_index
=
fname
.
rfind
(
details
::
os
::
folder_sep
);
if
(
folder_index
!=
filename_t
::
npos
&&
folder_index
>=
ext_index
-
1
)
{
return
std
::
make_tuple
(
fname
,
filename_t
());
}
// no valid extension found - return whole path and empty string as
// extension
if
(
ext_index
==
filename_t
::
npos
||
ext_index
==
0
||
ext_index
==
fname
.
size
()
-
1
)
{
return
std
::
make_tuple
(
fname
,
filename_t
());
}
// finally - return a valid base and extension tuple
return
std
::
make_tuple
(
fname
.
substr
(
0
,
ext_index
),
fname
.
substr
(
ext_index
));
// treat casese like "/etc/rc.d/somelogfile or "/abc/.hiddenfile"
auto
folder_index
=
fname
.
rfind
(
details
::
os
::
folder_sep
);
if
(
folder_index
!=
filename_t
::
npos
&&
folder_index
>=
ext_index
-
1
)
{
return
std
::
make_tuple
(
fname
,
filename_t
());
}
// finally - return a valid base and extension tuple
return
std
::
make_tuple
(
fname
.
substr
(
0
,
ext_index
),
fname
.
substr
(
ext_index
));
}
}
// namespace details
}
// namespace spdlog
include/spdlog/impl/log_msg.cpp
View file @
2de924a1
#include "spdlog/details/os.h"
#include "spdlog/sinks/sink.h"
#ifndef SPDLOG_HEADER_ONLY
#include "spdlog/details/log_msg.h"
#endif
#ifndef SPDLOG_HEADER_ONLY
#include "spdlog/details/log_msg.h"
#endif
SPDLOG_INLINE
spdlog
::
details
::
log_msg
::
log_msg
(
spdlog
::
source_loc
loc
,
const
std
::
string
*
loggers_name
,
spdlog
::
level
::
level_enum
lvl
,
spdlog
::
string_view_t
view
)
:
logger_name
(
loggers_name
)
...
...
include/spdlog/impl/logger.cpp
View file @
2de924a1
...
...
@@ -160,11 +160,11 @@ SPDLOG_INLINE bool spdlog::logger::should_flush_(const spdlog::details::log_msg
}
SPDLOG_INLINE
void
spdlog
::
logger
::
err_handler_
(
const
std
::
string
&
msg
)
{
if
(
custom_err_handler_
)
{
custom_err_handler_
(
msg
);
}
{
if
(
custom_err_handler_
)
{
custom_err_handler_
(
msg
);
}
else
{
auto
tm_time
=
spdlog
::
details
::
os
::
localtime
();
...
...
include/spdlog/impl/pattern_formatter.cpp
View file @
2de924a1
...
...
@@ -959,308 +959,304 @@ private:
}
// namespace details
SPDLOG_INLINE
pattern_formatter
::
pattern_formatter
(
std
::
string
pattern
,
pattern_time_type
time_type
,
std
::
string
eol
)
:
pattern_
(
std
::
move
(
pattern
))
,
eol_
(
std
::
move
(
eol
))
,
pattern_time_type_
(
time_type
)
,
last_log_secs_
(
0
)
{
std
::
memset
(
&
cached_tm_
,
0
,
sizeof
(
cached_tm_
));
compile_pattern_
(
pattern_
);
}
SPDLOG_INLINE
pattern_formatter
::
pattern_formatter
(
std
::
string
pattern
,
pattern_time_type
time_type
,
std
::
string
eol
)
:
pattern_
(
std
::
move
(
pattern
)
)
,
eol_
(
std
::
move
(
eol
))
,
pattern_time_type_
(
time_type
)
,
last_log_secs_
(
0
)
{
std
::
memset
(
&
cached_tm_
,
0
,
sizeof
(
cached_tm_
));
compile_pattern_
(
pattern_
);
}
// use by default full formatter for if pattern is not given
SPDLOG_INLINE
pattern_formatter
::
pattern_formatter
(
pattern_time_type
time_type
,
std
::
string
eol
)
:
pattern_
(
"%+"
)
,
eol_
(
std
::
move
(
eol
))
,
pattern_time_type_
(
time_type
)
,
last_log_secs_
(
0
)
{
std
::
memset
(
&
cached_tm_
,
0
,
sizeof
(
cached_tm_
));
formatters_
.
push_back
(
details
::
make_unique
<
details
::
full_formatter
>
(
details
::
padding_info
{})
);
}
// use by default full formatter for if pattern is not given
SPDLOG_INLINE
pattern_formatter
::
pattern_formatter
(
pattern_time_type
time_type
,
std
::
string
eol
)
:
pattern_
(
"%+"
)
,
eol_
(
std
::
move
(
eol
))
,
pattern_time_type_
(
time_type
)
,
last_log_secs_
(
0
)
{
std
::
memset
(
&
cached_tm_
,
0
,
sizeof
(
cached_tm_
));
formatters_
.
push_back
(
details
::
make_unique
<
details
::
full_formatter
>
(
details
::
padding_info
{}));
}
SPDLOG_INLINE
std
::
unique_ptr
<
formatter
>
pattern_formatter
::
clone
()
const
{
return
details
::
make_unique
<
pattern_formatter
>
(
pattern_
,
pattern_time_type_
,
eol_
);
}
SPDLOG_INLINE
std
::
unique_ptr
<
formatter
>
pattern_formatter
::
clone
()
const
SPDLOG_INLINE
void
pattern_formatter
::
format
(
const
details
::
log_msg
&
msg
,
fmt
::
memory_buffer
&
dest
)
{
#ifndef SPDLOG_NO_DATETIME
auto
secs
=
std
::
chrono
::
duration_cast
<
std
::
chrono
::
seconds
>
(
msg
.
time
.
time_since_epoch
());
if
(
secs
!=
last_log_secs_
)
{
return
details
::
make_unique
<
pattern_formatter
>
(
pattern_
,
pattern_time_type_
,
eol_
);
cached_tm_
=
get_time_
(
msg
);
last_log_secs_
=
secs
;
}
SPDLOG_INLINE
void
pattern_formatter
::
format
(
const
details
::
log_msg
&
msg
,
fmt
::
memory_buffer
&
dest
)
{
#ifndef SPDLOG_NO_DATETIME
auto
secs
=
std
::
chrono
::
duration_cast
<
std
::
chrono
::
seconds
>
(
msg
.
time
.
time_since_epoch
());
if
(
secs
!=
last_log_secs_
)
{
cached_tm_
=
get_time_
(
msg
);
last_log_secs_
=
secs
;
}
#endif
for
(
auto
&
f
:
formatters_
)
{
f
->
format
(
msg
,
cached_tm_
,
dest
);
}
// write eol
details
::
fmt_helper
::
append_string_view
(
eol_
,
dest
);
for
(
auto
&
f
:
formatters_
)
{
f
->
format
(
msg
,
cached_tm_
,
dest
);
}
// write eol
details
::
fmt_helper
::
append_string_view
(
eol_
,
dest
);
}
SPDLOG_INLINE
std
::
tm
pattern_formatter
::
get_time_
(
const
details
::
log_msg
&
msg
)
SPDLOG_INLINE
std
::
tm
pattern_formatter
::
get_time_
(
const
details
::
log_msg
&
msg
)
{
if
(
pattern_time_type_
==
pattern_time_type
::
local
)
{
if
(
pattern_time_type_
==
pattern_time_type
::
local
)
{
return
details
::
os
::
localtime
(
log_clock
::
to_time_t
(
msg
.
time
));
}
return
details
::
os
::
gmtime
(
log_clock
::
to_time_t
(
msg
.
time
));
return
details
::
os
::
localtime
(
log_clock
::
to_time_t
(
msg
.
time
));
}
return
details
::
os
::
gmtime
(
log_clock
::
to_time_t
(
msg
.
time
));
}
SPDLOG_INLINE
void
pattern_formatter
::
handle_flag_
(
char
flag
,
details
::
padding_info
padding
)
SPDLOG_INLINE
void
pattern_formatter
::
handle_flag_
(
char
flag
,
details
::
padding_info
padding
)
{
switch
(
flag
)
{
switch
(
flag
)
{
case
(
'+'
):
// default formatter
formatters_
.
push_back
(
details
::
make_unique
<
details
::
full_formatter
>
(
padding
));
break
;
case
(
'+'
):
// default formatter
formatters_
.
push_back
(
details
::
make_unique
<
details
::
full_formatter
>
(
padding
));
break
;
case
'n'
:
// logger name
formatters_
.
push_back
(
details
::
make_unique
<
details
::
name_formatter
>
(
padding
));
break
;
case
'n'
:
// logger name
formatters_
.
push_back
(
details
::
make_unique
<
details
::
name_formatter
>
(
padding
));
break
;
case
'l'
:
// level
formatters_
.
push_back
(
details
::
make_unique
<
details
::
level_formatter
>
(
padding
));
break
;
case
'l'
:
// level
formatters_
.
push_back
(
details
::
make_unique
<
details
::
level_formatter
>
(
padding
));
break
;
case
'L'
:
// short level
formatters_
.
push_back
(
details
::
make_unique
<
details
::
short_level_formatter
>
(
padding
));
break
;
case
'L'
:
// short level
formatters_
.
push_back
(
details
::
make_unique
<
details
::
short_level_formatter
>
(
padding
));
break
;
case
(
't'
):
// thread id
formatters_
.
push_back
(
details
::
make_unique
<
details
::
t_formatter
>
(
padding
));
break
;
case
(
't'
):
// thread id
formatters_
.
push_back
(
details
::
make_unique
<
details
::
t_formatter
>
(
padding
));
break
;
case
(
'v'
):
// the message text
formatters_
.
push_back
(
details
::
make_unique
<
details
::
v_formatter
>
(
padding
));
break
;
case
(
'v'
):
// the message text
formatters_
.
push_back
(
details
::
make_unique
<
details
::
v_formatter
>
(
padding
));
break
;
case
(
'a'
):
// weekday
formatters_
.
push_back
(
details
::
make_unique
<
details
::
a_formatter
>
(
padding
));
break
;
case
(
'a'
):
// weekday
formatters_
.
push_back
(
details
::
make_unique
<
details
::
a_formatter
>
(
padding
));
break
;
case
(
'A'
):
// short weekday
formatters_
.
push_back
(
details
::
make_unique
<
details
::
A_formatter
>
(
padding
));
break
;
case
(
'A'
):
// short weekday
formatters_
.
push_back
(
details
::
make_unique
<
details
::
A_formatter
>
(
padding
));
break
;
case
(
'b'
):
case
(
'h'
):
// month
formatters_
.
push_back
(
details
::
make_unique
<
details
::
b_formatter
>
(
padding
));
break
;
case
(
'b'
):
case
(
'h'
):
// month
formatters_
.
push_back
(
details
::
make_unique
<
details
::
b_formatter
>
(
padding
));
break
;
case
(
'B'
):
// short month
formatters_
.
push_back
(
details
::
make_unique
<
details
::
B_formatter
>
(
padding
));
break
;
case
(
'B'
):
// short month
formatters_
.
push_back
(
details
::
make_unique
<
details
::
B_formatter
>
(
padding
));
break
;
case
(
'c'
):
// datetime
formatters_
.
push_back
(
details
::
make_unique
<
details
::
c_formatter
>
(
padding
));
break
;
case
(
'c'
):
// datetime
formatters_
.
push_back
(
details
::
make_unique
<
details
::
c_formatter
>
(
padding
));
break
;
case
(
'C'
):
// year 2 digits
formatters_
.
push_back
(
details
::
make_unique
<
details
::
C_formatter
>
(
padding
));
break
;
case
(
'C'
):
// year 2 digits
formatters_
.
push_back
(
details
::
make_unique
<
details
::
C_formatter
>
(
padding
));
break
;
case
(
'Y'
):
// year 4 digits
formatters_
.
push_back
(
details
::
make_unique
<
details
::
Y_formatter
>
(
padding
));
break
;
case
(
'Y'
):
// year 4 digits
formatters_
.
push_back
(
details
::
make_unique
<
details
::
Y_formatter
>
(
padding
));
break
;
case
(
'D'
):
case
(
'x'
):
// datetime MM/DD/YY
formatters_
.
push_back
(
details
::
make_unique
<
details
::
D_formatter
>
(
padding
));
break
;
case
(
'm'
):
// month 1-12
formatters_
.
push_back
(
details
::
make_unique
<
details
::
m_formatter
>
(
padding
));
break
;
case
(
'd'
):
// day of month 1-31
formatters_
.
push_back
(
details
::
make_unique
<
details
::
d_formatter
>
(
padding
));
break
;
case
(
'H'
):
// hours 24
formatters_
.
push_back
(
details
::
make_unique
<
details
::
H_formatter
>
(
padding
));
break
;
case
(
'I'
):
// hours 12
formatters_
.
push_back
(
details
::
make_unique
<
details
::
I_formatter
>
(
padding
));
break
;
case
(
'M'
):
// minutes
formatters_
.
push_back
(
details
::
make_unique
<
details
::
M_formatter
>
(
padding
));
break
;
case
(
'S'
):
// seconds
formatters_
.
push_back
(
details
::
make_unique
<
details
::
S_formatter
>
(
padding
));
break
;
case
(
'e'
):
// milliseconds
formatters_
.
push_back
(
details
::
make_unique
<
details
::
e_formatter
>
(
padding
));
break
;
case
(
'f'
):
// microseconds
formatters_
.
push_back
(
details
::
make_unique
<
details
::
f_formatter
>
(
padding
));
break
;
case
(
'F'
):
// nanoseconds
formatters_
.
push_back
(
details
::
make_unique
<
details
::
F_formatter
>
(
padding
));
break
;
case
(
'E'
):
// seconds since epoch
formatters_
.
push_back
(
details
::
make_unique
<
details
::
E_formatter
>
(
padding
));
break
;
case
(
'p'
):
// am/pm
formatters_
.
push_back
(
details
::
make_unique
<
details
::
p_formatter
>
(
padding
));
break
;
case
(
'r'
):
// 12 hour clock 02:55:02 pm
formatters_
.
push_back
(
details
::
make_unique
<
details
::
r_formatter
>
(
padding
));
break
;
case
(
'R'
):
// 24-hour HH:MM time
formatters_
.
push_back
(
details
::
make_unique
<
details
::
R_formatter
>
(
padding
));
break
;
case
(
'T'
):
case
(
'X'
):
// ISO 8601 time format (HH:MM:SS)
formatters_
.
push_back
(
details
::
make_unique
<
details
::
T_formatter
>
(
padding
));
break
;
case
(
'z'
):
// timezone
formatters_
.
push_back
(
details
::
make_unique
<
details
::
z_formatter
>
(
padding
));
break
;
case
(
'P'
):
// pid
formatters_
.
push_back
(
details
::
make_unique
<
details
::
pid_formatter
>
(
padding
));
break
;
case
(
'^'
):
// color range start
formatters_
.
push_back
(
details
::
make_unique
<
details
::
color_start_formatter
>
(
padding
));
break
;
case
(
'$'
):
// color range end
formatters_
.
push_back
(
details
::
make_unique
<
details
::
color_stop_formatter
>
(
padding
));
break
;
case
(
'@'
):
// source location (filename:filenumber)
formatters_
.
push_back
(
details
::
make_unique
<
details
::
source_location_formatter
>
(
padding
));
break
;
case
(
's'
):
// source filename
formatters_
.
push_back
(
details
::
make_unique
<
details
::
source_filename_formatter
>
(
padding
));
break
;
case
(
'#'
):
// source line number
formatters_
.
push_back
(
details
::
make_unique
<
details
::
source_linenum_formatter
>
(
padding
));
break
;
case
(
'!'
):
// source funcname
formatters_
.
push_back
(
details
::
make_unique
<
details
::
source_funcname_formatter
>
(
padding
));
break
;
case
(
'%'
):
// % char
formatters_
.
push_back
(
details
::
make_unique
<
details
::
ch_formatter
>
(
'%'
));
break
;
default
:
// Unknown flag appears as is
auto
unknown_flag
=
details
::
make_unique
<
details
::
aggregate_formatter
>
();
unknown_flag
->
add_ch
(
'%'
);
unknown_flag
->
add_ch
(
flag
);
formatters_
.
push_back
((
std
::
move
(
unknown_flag
)));
break
;
}
case
(
'D'
):
case
(
'x'
):
// datetime MM/DD/YY
formatters_
.
push_back
(
details
::
make_unique
<
details
::
D_formatter
>
(
padding
));
break
;
case
(
'm'
):
// month 1-12
formatters_
.
push_back
(
details
::
make_unique
<
details
::
m_formatter
>
(
padding
));
break
;
case
(
'd'
):
// day of month 1-31
formatters_
.
push_back
(
details
::
make_unique
<
details
::
d_formatter
>
(
padding
));
break
;
case
(
'H'
):
// hours 24
formatters_
.
push_back
(
details
::
make_unique
<
details
::
H_formatter
>
(
padding
));
break
;
case
(
'I'
):
// hours 12
formatters_
.
push_back
(
details
::
make_unique
<
details
::
I_formatter
>
(
padding
));
break
;
case
(
'M'
):
// minutes
formatters_
.
push_back
(
details
::
make_unique
<
details
::
M_formatter
>
(
padding
));
break
;
case
(
'S'
):
// seconds
formatters_
.
push_back
(
details
::
make_unique
<
details
::
S_formatter
>
(
padding
));
break
;
case
(
'e'
):
// milliseconds
formatters_
.
push_back
(
details
::
make_unique
<
details
::
e_formatter
>
(
padding
));
break
;
case
(
'f'
):
// microseconds
formatters_
.
push_back
(
details
::
make_unique
<
details
::
f_formatter
>
(
padding
));
break
;
case
(
'F'
):
// nanoseconds
formatters_
.
push_back
(
details
::
make_unique
<
details
::
F_formatter
>
(
padding
));
break
;
case
(
'E'
):
// seconds since epoch
formatters_
.
push_back
(
details
::
make_unique
<
details
::
E_formatter
>
(
padding
));
break
;
case
(
'p'
):
// am/pm
formatters_
.
push_back
(
details
::
make_unique
<
details
::
p_formatter
>
(
padding
));
break
;
case
(
'r'
):
// 12 hour clock 02:55:02 pm
formatters_
.
push_back
(
details
::
make_unique
<
details
::
r_formatter
>
(
padding
));
break
;
case
(
'R'
):
// 24-hour HH:MM time
formatters_
.
push_back
(
details
::
make_unique
<
details
::
R_formatter
>
(
padding
));
break
;
case
(
'T'
):
case
(
'X'
):
// ISO 8601 time format (HH:MM:SS)
formatters_
.
push_back
(
details
::
make_unique
<
details
::
T_formatter
>
(
padding
));
break
;
case
(
'z'
):
// timezone
formatters_
.
push_back
(
details
::
make_unique
<
details
::
z_formatter
>
(
padding
));
break
;
case
(
'P'
):
// pid
formatters_
.
push_back
(
details
::
make_unique
<
details
::
pid_formatter
>
(
padding
));
break
;
case
(
'^'
):
// color range start
formatters_
.
push_back
(
details
::
make_unique
<
details
::
color_start_formatter
>
(
padding
));
break
;
case
(
'$'
):
// color range end
formatters_
.
push_back
(
details
::
make_unique
<
details
::
color_stop_formatter
>
(
padding
));
break
;
case
(
'@'
):
// source location (filename:filenumber)
formatters_
.
push_back
(
details
::
make_unique
<
details
::
source_location_formatter
>
(
padding
));
break
;
case
(
's'
):
// source filename
formatters_
.
push_back
(
details
::
make_unique
<
details
::
source_filename_formatter
>
(
padding
));
break
;
case
(
'#'
):
// source line number
formatters_
.
push_back
(
details
::
make_unique
<
details
::
source_linenum_formatter
>
(
padding
));
break
;
case
(
'!'
):
// source funcname
formatters_
.
push_back
(
details
::
make_unique
<
details
::
source_funcname_formatter
>
(
padding
));
break
;
case
(
'%'
):
// % char
formatters_
.
push_back
(
details
::
make_unique
<
details
::
ch_formatter
>
(
'%'
));
break
;
default
:
// Unknown flag appears as is
auto
unknown_flag
=
details
::
make_unique
<
details
::
aggregate_formatter
>
();
unknown_flag
->
add_ch
(
'%'
);
unknown_flag
->
add_ch
(
flag
);
formatters_
.
push_back
((
std
::
move
(
unknown_flag
)));
break
;
}
}
// Extract given pad spec (e.g. %8X)
// Advance the given it pass the end of the padding spec found (if any)
// Return padding.
SPDLOG_INLINE
details
::
padding_info
pattern_formatter
::
handle_padspec_
(
std
::
string
::
const_iterator
&
it
,
std
::
string
::
const_iterator
end
)
// Extract given pad spec (e.g. %8X)
// Advance the given it pass the end of the padding spec found (if any)
// Return padding.
SPDLOG_INLINE
details
::
padding_info
pattern_formatter
::
handle_padspec_
(
std
::
string
::
const_iterator
&
it
,
std
::
string
::
const_iterator
end
)
{
using
details
::
padding_info
;
using
details
::
scoped_pad
;
const
size_t
max_width
=
128
;
if
(
it
==
end
)
{
using
details
::
padding_info
;
using
details
::
scoped_pad
;
const
size_t
max_width
=
128
;
if
(
it
==
end
)
{
return
padding_info
{};
}
return
padding_info
{};
}
padding_info
::
pad_side
side
;
switch
(
*
it
)
{
case
'-'
:
side
=
padding_info
::
right
;
++
it
;
break
;
case
'='
:
side
=
padding_info
::
center
;
++
it
;
break
;
default
:
side
=
details
::
padding_info
::
left
;
break
;
}
padding_info
::
pad_side
side
;
switch
(
*
it
)
{
case
'-'
:
side
=
padding_info
::
right
;
++
it
;
break
;
case
'='
:
side
=
padding_info
::
center
;
++
it
;
break
;
default
:
side
=
details
::
padding_info
::
left
;
break
;
}
if
(
it
==
end
||
!
std
::
isdigit
(
static_cast
<
unsigned
char
>
(
*
it
)))
{
return
padding_info
{
0
,
side
};
}
if
(
it
==
end
||
!
std
::
isdigit
(
static_cast
<
unsigned
char
>
(
*
it
)))
{
return
padding_info
{
0
,
side
};
}
auto
width
=
static_cast
<
size_t
>
(
*
it
-
'0'
);
for
(
++
it
;
it
!=
end
&&
std
::
isdigit
(
static_cast
<
unsigned
char
>
(
*
it
));
++
it
)
{
auto
digit
=
static_cast
<
size_t
>
(
*
it
-
'0'
);
width
=
width
*
10
+
digit
;
}
return
details
::
padding_info
{
std
::
min
<
size_t
>
(
width
,
max_width
),
side
};
auto
width
=
static_cast
<
size_t
>
(
*
it
-
'0'
);
for
(
++
it
;
it
!=
end
&&
std
::
isdigit
(
static_cast
<
unsigned
char
>
(
*
it
));
++
it
)
{
auto
digit
=
static_cast
<
size_t
>
(
*
it
-
'0'
);
width
=
width
*
10
+
digit
;
}
return
details
::
padding_info
{
std
::
min
<
size_t
>
(
width
,
max_width
),
side
};
}
SPDLOG_INLINE
void
pattern_formatter
::
compile_pattern_
(
const
std
::
string
&
pattern
)
SPDLOG_INLINE
void
pattern_formatter
::
compile_pattern_
(
const
std
::
string
&
pattern
)
{
auto
end
=
pattern
.
end
();
std
::
unique_ptr
<
details
::
aggregate_formatter
>
user_chars
;
formatters_
.
clear
();
for
(
auto
it
=
pattern
.
begin
();
it
!=
end
;
++
it
)
{
auto
end
=
pattern
.
end
();
std
::
unique_ptr
<
details
::
aggregate_formatter
>
user_chars
;
formatters_
.
clear
();
for
(
auto
it
=
pattern
.
begin
();
it
!=
end
;
++
it
)
if
(
*
it
==
'%'
)
{
if
(
*
it
==
'%'
)
if
(
user_chars
)
// append user chars found so far
{
formatters_
.
push_back
(
std
::
move
(
user_chars
));
}
auto
padding
=
handle_padspec_
(
++
it
,
end
);
if
(
it
!=
end
)
{
if
(
user_chars
)
// append user chars found so far
{
formatters_
.
push_back
(
std
::
move
(
user_chars
));
}
auto
padding
=
handle_padspec_
(
++
it
,
end
);
if
(
it
!=
end
)
{
handle_flag_
(
*
it
,
padding
);
}
else
{
break
;
}
handle_flag_
(
*
it
,
padding
);
}
else
// chars not following the % sign should be displayed as is
else
{
if
(
!
user_chars
)
{
user_chars
=
details
::
make_unique
<
details
::
aggregate_formatter
>
();
}
user_chars
->
add_ch
(
*
it
);
break
;
}
}
if
(
user_chars
)
// append raw chars found so far
else
// chars not following the % sign should be displayed as is
{
formatters_
.
push_back
(
std
::
move
(
user_chars
));
if
(
!
user_chars
)
{
user_chars
=
details
::
make_unique
<
details
::
aggregate_formatter
>
();
}
user_chars
->
add_ch
(
*
it
);
}
}
if
(
user_chars
)
// append raw chars found so far
{
formatters_
.
push_back
(
std
::
move
(
user_chars
));
}
}
}
// namespace spdlog
include/spdlog/impl/registry.cpp
View file @
2de924a1
...
...
@@ -6,7 +6,6 @@
#include "spdlog/details/registry.h"
#endif
#include "spdlog/common.h"
#include "spdlog/details/periodic_worker.h"
#include "spdlog/logger.h"
...
...
include/spdlog/impl/sink.cpp
View file @
2de924a1
#include "spdlog/common.h"
#include "spdlog/details/pattern_formatter.h"
#ifndef SPDLOG_HEADER_ONLY
#include "spdlog/sinks/sink.h"
#endif
SPDLOG_INLINE
spdlog
::
sinks
::
sink
::
sink
()
:
formatter_
{
details
::
make_unique
<
spdlog
::
pattern_formatter
>
()}
{}
SPDLOG_INLINE
spdlog
::
sinks
::
sink
::
sink
(
std
::
unique_ptr
<
spdlog
::
formatter
>
formatter
)
:
formatter_
{
std
::
move
(
formatter
)}
{}
SPDLOG_INLINE
bool
spdlog
::
sinks
::
sink
::
should_log
(
spdlog
::
level
::
level_enum
msg_level
)
const
{
return
msg_level
>=
level_
.
load
(
std
::
memory_order_relaxed
);
}
SPDLOG_INLINE
void
spdlog
::
sinks
::
sink
::
set_level
(
level
::
level_enum
log_level
)
{
level_
.
store
(
log_level
);
}
SPDLOG_INLINE
spdlog
::
level
::
level_enum
spdlog
::
sinks
::
sink
::
level
()
const
{
return
static_cast
<
spdlog
::
level
::
level_enum
>
(
level_
.
load
(
std
::
memory_order_relaxed
));
}
#include "spdlog/common.h"
#include "spdlog/details/pattern_formatter.h"
#ifndef SPDLOG_HEADER_ONLY
#include "spdlog/sinks/sink.h"
#endif
SPDLOG_INLINE
spdlog
::
sinks
::
sink
::
sink
()
:
formatter_
{
details
::
make_unique
<
spdlog
::
pattern_formatter
>
()}
{
}
SPDLOG_INLINE
spdlog
::
sinks
::
sink
::
sink
(
std
::
unique_ptr
<
spdlog
::
formatter
>
formatter
)
:
formatter_
{
std
::
move
(
formatter
)}
{
}
SPDLOG_INLINE
bool
spdlog
::
sinks
::
sink
::
should_log
(
spdlog
::
level
::
level_enum
msg_level
)
const
{
return
msg_level
>=
level_
.
load
(
std
::
memory_order_relaxed
);
}
SPDLOG_INLINE
void
spdlog
::
sinks
::
sink
::
set_level
(
level
::
level_enum
log_level
)
{
level_
.
store
(
log_level
);
}
SPDLOG_INLINE
spdlog
::
level
::
level_enum
spdlog
::
sinks
::
sink
::
level
()
const
{
return
static_cast
<
spdlog
::
level
::
level_enum
>
(
level_
.
load
(
std
::
memory_order_relaxed
));
}
include/spdlog/logger.h
View file @
2de924a1
...
...
@@ -33,313 +33,310 @@ namespace spdlog {
class
logger
{
public
:
template
<
typename
It
>
logger
(
std
::
string
name
,
It
begin
,
It
end
)
:
name_
(
std
::
move
(
name
))
,
sinks_
(
begin
,
end
)
template
<
typename
It
>
logger
(
std
::
string
name
,
It
begin
,
It
end
)
:
name_
(
std
::
move
(
name
))
,
sinks_
(
begin
,
end
)
{
}
logger
(
std
::
string
name
,
sink_ptr
single_sink
)
:
logger
(
std
::
move
(
name
),
{
std
::
move
(
single_sink
)})
{
}
logger
(
std
::
string
name
,
sinks_init_list
sinks
)
:
logger
(
std
::
move
(
name
),
sinks
.
begin
(),
sinks
.
end
())
{
}
virtual
~
logger
()
=
default
;
logger
(
const
logger
&
)
=
delete
;
logger
&
operator
=
(
const
logger
&
)
=
delete
;
template
<
typename
...
Args
>
void
log
(
source_loc
loc
,
level
::
level_enum
lvl
,
const
char
*
fmt
,
const
Args
&
...
args
)
{
if
(
!
should_log
(
lvl
))
{
return
;
}
logger
(
std
::
string
name
,
sink_ptr
single_sink
)
:
logger
(
std
::
move
(
name
),
{
std
::
move
(
single_sink
)})
try
{
fmt
::
memory_buffer
buf
;
fmt
::
format_to
(
buf
,
fmt
,
args
...);
details
::
log_msg
log_msg
(
loc
,
&
name_
,
lvl
,
string_view_t
(
buf
.
data
(),
buf
.
size
()));
sink_it_
(
log_msg
);
}
logger
(
std
::
string
name
,
sinks_init_list
sinks
)
:
logger
(
std
::
move
(
name
),
sinks
.
begin
(),
sinks
.
end
())
catch
(
const
std
::
exception
&
ex
)
{
err_handler_
(
ex
.
what
());
}
virtual
~
logger
()
=
default
;
logger
(
const
logger
&
)
=
delete
;
logger
&
operator
=
(
const
logger
&
)
=
delete
;
template
<
typename
...
Args
>
void
log
(
source_loc
loc
,
level
::
level_enum
lvl
,
const
char
*
fmt
,
const
Args
&
...
args
)
{
if
(
!
should_log
(
lvl
))
{
return
;
}
try
{
fmt
::
memory_buffer
buf
;
fmt
::
format_to
(
buf
,
fmt
,
args
...);
details
::
log_msg
log_msg
(
loc
,
&
name_
,
lvl
,
string_view_t
(
buf
.
data
(),
buf
.
size
()));
sink_it_
(
log_msg
);
}
catch
(
const
std
::
exception
&
ex
)
{
err_handler_
(
ex
.
what
());
}
catch
(...)
{
err_handler_
(
"Unknown exception in logger"
);
}
}
template
<
typename
...
Args
>
void
log
(
level
::
level_enum
lvl
,
const
char
*
fmt
,
const
Args
&
...
args
)
{
log
(
source_loc
{},
lvl
,
fmt
,
args
...);
}
void
log
(
source_loc
loc
,
level
::
level_enum
lvl
,
const
char
*
msg
);
void
log
(
level
::
level_enum
lvl
,
const
char
*
msg
);
template
<
typename
...
Args
>
void
trace
(
const
char
*
fmt
,
const
Args
&
...
args
)
{
log
(
level
::
trace
,
fmt
,
args
...);
}
template
<
typename
...
Args
>
void
debug
(
const
char
*
fmt
,
const
Args
&
...
args
)
{
log
(
level
::
debug
,
fmt
,
args
...);
}
template
<
typename
...
Args
>
void
info
(
const
char
*
fmt
,
const
Args
&
...
args
)
{
log
(
level
::
info
,
fmt
,
args
...);
}
template
<
typename
...
Args
>
void
warn
(
const
char
*
fmt
,
const
Args
&
...
args
)
{
log
(
level
::
warn
,
fmt
,
args
...);
}
template
<
typename
...
Args
>
void
error
(
const
char
*
fmt
,
const
Args
&
...
args
)
{
log
(
level
::
err
,
fmt
,
args
...);
}
template
<
typename
...
Args
>
void
critical
(
const
char
*
fmt
,
const
Args
&
...
args
)
catch
(...)
{
log
(
level
::
critical
,
fmt
,
args
...
);
err_handler_
(
"Unknown exception in logger"
);
}
template
<
typename
T
>
void
log
(
level
::
level_enum
lvl
,
const
T
&
msg
)
}
template
<
typename
...
Args
>
void
log
(
level
::
level_enum
lvl
,
const
char
*
fmt
,
const
Args
&
...
args
)
{
log
(
source_loc
{},
lvl
,
fmt
,
args
...);
}
void
log
(
source_loc
loc
,
level
::
level_enum
lvl
,
const
char
*
msg
);
void
log
(
level
::
level_enum
lvl
,
const
char
*
msg
);
template
<
typename
...
Args
>
void
trace
(
const
char
*
fmt
,
const
Args
&
...
args
)
{
log
(
level
::
trace
,
fmt
,
args
...);
}
template
<
typename
...
Args
>
void
debug
(
const
char
*
fmt
,
const
Args
&
...
args
)
{
log
(
level
::
debug
,
fmt
,
args
...);
}
template
<
typename
...
Args
>
void
info
(
const
char
*
fmt
,
const
Args
&
...
args
)
{
log
(
level
::
info
,
fmt
,
args
...);
}
template
<
typename
...
Args
>
void
warn
(
const
char
*
fmt
,
const
Args
&
...
args
)
{
log
(
level
::
warn
,
fmt
,
args
...);
}
template
<
typename
...
Args
>
void
error
(
const
char
*
fmt
,
const
Args
&
...
args
)
{
log
(
level
::
err
,
fmt
,
args
...);
}
template
<
typename
...
Args
>
void
critical
(
const
char
*
fmt
,
const
Args
&
...
args
)
{
log
(
level
::
critical
,
fmt
,
args
...);
}
template
<
typename
T
>
void
log
(
level
::
level_enum
lvl
,
const
T
&
msg
)
{
log
(
source_loc
{},
lvl
,
msg
);
}
// T can be statically converted to string_view
template
<
class
T
,
typename
std
::
enable_if
<
std
::
is_convertible
<
T
,
spdlog
::
string_view_t
>::
value
,
T
>::
type
*
=
nullptr
>
void
log
(
source_loc
loc
,
level
::
level_enum
lvl
,
const
T
&
msg
)
{
if
(
!
should_log
(
lvl
))
{
log
(
source_loc
{},
lvl
,
msg
)
;
return
;
}
// T can be statically converted to string_view
template
<
class
T
,
typename
std
::
enable_if
<
std
::
is_convertible
<
T
,
spdlog
::
string_view_t
>::
value
,
T
>::
type
*
=
nullptr
>
void
log
(
source_loc
loc
,
level
::
level_enum
lvl
,
const
T
&
msg
)
try
{
if
(
!
should_log
(
lvl
))
{
return
;
}
try
{
details
::
log_msg
log_msg
(
loc
,
&
name_
,
lvl
,
msg
);
sink_it_
(
log_msg
);
}
catch
(
const
std
::
exception
&
ex
)
{
err_handler_
(
ex
.
what
());
}
catch
(...)
{
err_handler_
(
"Unknown exception in logger"
);
}
details
::
log_msg
log_msg
(
loc
,
&
name_
,
lvl
,
msg
);
sink_it_
(
log_msg
);
}
// T cannot be statically converted to string_view
template
<
class
T
,
typename
std
::
enable_if
<!
std
::
is_convertible
<
T
,
spdlog
::
string_view_t
>::
value
,
T
>::
type
*
=
nullptr
>
void
log
(
source_loc
loc
,
level
::
level_enum
lvl
,
const
T
&
msg
)
catch
(
const
std
::
exception
&
ex
)
{
if
(
!
should_log
(
lvl
))
{
return
;
}
try
{
fmt
::
memory_buffer
buf
;
fmt
::
format_to
(
buf
,
"{}"
,
msg
);
details
::
log_msg
log_msg
(
loc
,
&
name_
,
lvl
,
string_view_t
(
buf
.
data
(),
buf
.
size
()));
sink_it_
(
log_msg
);
}
catch
(
const
std
::
exception
&
ex
)
{
err_handler_
(
ex
.
what
());
}
catch
(...)
{
err_handler_
(
"Unknown exception in logger"
);
}
err_handler_
(
ex
.
what
());
}
template
<
typename
T
>
void
trace
(
const
T
&
msg
)
catch
(...)
{
log
(
level
::
trace
,
msg
);
err_handler_
(
"Unknown exception in logger"
);
}
}
template
<
typename
T
>
void
debug
(
const
T
&
msg
)
// T cannot be statically converted to string_view
template
<
class
T
,
typename
std
::
enable_if
<!
std
::
is_convertible
<
T
,
spdlog
::
string_view_t
>::
value
,
T
>::
type
*
=
nullptr
>
void
log
(
source_loc
loc
,
level
::
level_enum
lvl
,
const
T
&
msg
)
{
if
(
!
should_log
(
lvl
))
{
log
(
level
::
debug
,
msg
)
;
return
;
}
template
<
typename
T
>
void
info
(
const
T
&
msg
)
try
{
log
(
level
::
info
,
msg
);
fmt
::
memory_buffer
buf
;
fmt
::
format_to
(
buf
,
"{}"
,
msg
);
details
::
log_msg
log_msg
(
loc
,
&
name_
,
lvl
,
string_view_t
(
buf
.
data
(),
buf
.
size
()));
sink_it_
(
log_msg
);
}
template
<
typename
T
>
void
warn
(
const
T
&
msg
)
catch
(
const
std
::
exception
&
ex
)
{
log
(
level
::
warn
,
msg
);
err_handler_
(
ex
.
what
()
);
}
template
<
typename
T
>
void
error
(
const
T
&
msg
)
{
log
(
level
::
err
,
msg
);
}
template
<
typename
T
>
void
critical
(
const
T
&
msg
)
catch
(...)
{
log
(
level
::
critical
,
msg
);
err_handler_
(
"Unknown exception in logger"
);
}
}
template
<
typename
T
>
void
trace
(
const
T
&
msg
)
{
log
(
level
::
trace
,
msg
);
}
template
<
typename
T
>
void
debug
(
const
T
&
msg
)
{
log
(
level
::
debug
,
msg
);
}
template
<
typename
T
>
void
info
(
const
T
&
msg
)
{
log
(
level
::
info
,
msg
);
}
template
<
typename
T
>
void
warn
(
const
T
&
msg
)
{
log
(
level
::
warn
,
msg
);
}
template
<
typename
T
>
void
error
(
const
T
&
msg
)
{
log
(
level
::
err
,
msg
);
}
template
<
typename
T
>
void
critical
(
const
T
&
msg
)
{
log
(
level
::
critical
,
msg
);
}
#ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT
#ifndef _WIN32
#error SPDLOG_WCHAR_TO_UTF8_SUPPORT only supported on windows
#else
template
<
typename
...
Args
>
void
log
(
source_loc
source
,
level
::
level_enum
lvl
,
const
wchar_t
*
fmt
,
const
Args
&
...
args
)
template
<
typename
...
Args
>
void
log
(
source_loc
source
,
level
::
level_enum
lvl
,
const
wchar_t
*
fmt
,
const
Args
&
...
args
)
{
if
(
!
should_log
(
lvl
))
{
if
(
!
should_log
(
lvl
))
{
return
;
}
try
{
// format to wmemory_buffer and convert to utf8
fmt
::
wmemory_buffer
wbuf
;
fmt
::
format_to
(
wbuf
,
fmt
,
args
...);
fmt
::
memory_buffer
buf
;
details
::
os
::
wbuf_to_utf8buf
(
wbuf
,
buf
);
details
::
log_msg
log_msg
(
source
,
&
name_
,
lvl
,
string_view_t
(
buf
.
data
(),
buf
.
size
()));
sink_it_
(
log_msg
);
}
catch
(
const
std
::
exception
&
ex
)
{
err_handler_
(
ex
.
what
());
}
catch
(...)
{
err_handler_
(
"Unknown exception in logger"
);
}
return
;
}
template
<
typename
...
Args
>
void
log
(
level
::
level_enum
lvl
,
const
wchar_t
*
fmt
,
const
Args
&
...
args
)
try
{
log
(
source_loc
{},
lvl
,
fmt
,
args
...);
// format to wmemory_buffer and convert to utf8
fmt
::
wmemory_buffer
wbuf
;
fmt
::
format_to
(
wbuf
,
fmt
,
args
...);
fmt
::
memory_buffer
buf
;
details
::
os
::
wbuf_to_utf8buf
(
wbuf
,
buf
);
details
::
log_msg
log_msg
(
source
,
&
name_
,
lvl
,
string_view_t
(
buf
.
data
(),
buf
.
size
()));
sink_it_
(
log_msg
);
}
template
<
typename
...
Args
>
void
trace
(
const
wchar_t
*
fmt
,
const
Args
&
...
args
)
catch
(
const
std
::
exception
&
ex
)
{
log
(
level
::
trace
,
fmt
,
args
...
);
err_handler_
(
ex
.
what
()
);
}
template
<
typename
...
Args
>
void
debug
(
const
wchar_t
*
fmt
,
const
Args
&
...
args
)
{
log
(
level
::
debug
,
fmt
,
args
...);
}
template
<
typename
...
Args
>
void
info
(
const
wchar_t
*
fmt
,
const
Args
&
...
args
)
{
log
(
level
::
info
,
fmt
,
args
...);
}
template
<
typename
...
Args
>
void
warn
(
const
wchar_t
*
fmt
,
const
Args
&
...
args
)
{
log
(
level
::
warn
,
fmt
,
args
...);
}
template
<
typename
...
Args
>
void
error
(
const
wchar_t
*
fmt
,
const
Args
&
...
args
)
{
log
(
level
::
err
,
fmt
,
args
...);
}
template
<
typename
...
Args
>
void
critical
(
const
wchar_t
*
fmt
,
const
Args
&
...
args
)
catch
(...)
{
log
(
level
::
critical
,
fmt
,
args
...
);
err_handler_
(
"Unknown exception in logger"
);
}
}
template
<
typename
...
Args
>
void
log
(
level
::
level_enum
lvl
,
const
wchar_t
*
fmt
,
const
Args
&
...
args
)
{
log
(
source_loc
{},
lvl
,
fmt
,
args
...);
}
template
<
typename
...
Args
>
void
trace
(
const
wchar_t
*
fmt
,
const
Args
&
...
args
)
{
log
(
level
::
trace
,
fmt
,
args
...);
}
template
<
typename
...
Args
>
void
debug
(
const
wchar_t
*
fmt
,
const
Args
&
...
args
)
{
log
(
level
::
debug
,
fmt
,
args
...);
}
template
<
typename
...
Args
>
void
info
(
const
wchar_t
*
fmt
,
const
Args
&
...
args
)
{
log
(
level
::
info
,
fmt
,
args
...);
}
template
<
typename
...
Args
>
void
warn
(
const
wchar_t
*
fmt
,
const
Args
&
...
args
)
{
log
(
level
::
warn
,
fmt
,
args
...);
}
template
<
typename
...
Args
>
void
error
(
const
wchar_t
*
fmt
,
const
Args
&
...
args
)
{
log
(
level
::
err
,
fmt
,
args
...);
}
template
<
typename
...
Args
>
void
critical
(
const
wchar_t
*
fmt
,
const
Args
&
...
args
)
{
log
(
level
::
critical
,
fmt
,
args
...);
}
#endif // _WIN32
#endif // SPDLOG_WCHAR_TO_UTF8_SUPPORT
#endif // SPDLOG_WCHAR_TO_UTF8_SUPPORT
bool
should_log
(
level
::
level_enum
msg_level
)
const
;
bool
should_log
(
level
::
level_enum
msg_level
)
const
;
void
set_level
(
level
::
level_enum
log_level
);
void
set_level
(
level
::
level_enum
log_level
);
static
level
::
level_enum
default_level
();
static
level
::
level_enum
default_level
();
level
::
level_enum
level
()
const
;
level
::
level_enum
level
()
const
;
const
std
::
string
&
name
()
const
;
const
std
::
string
&
name
()
const
;
// set formatting for the sinks in this logger.
// each sink will get a seperate instance of the formatter object.
void
set_formatter
(
std
::
unique_ptr
<
formatter
>
f
);
// set formatting for the sinks in this logger.
// each sink will get a seperate instance of the formatter object.
void
set_formatter
(
std
::
unique_ptr
<
formatter
>
f
);
void
set_pattern
(
std
::
string
pattern
,
pattern_time_type
time_type
=
pattern_time_type
::
local
);
void
set_pattern
(
std
::
string
pattern
,
pattern_time_type
time_type
=
pattern_time_type
::
local
);
// flush functions
void
flush
();
void
flush_on
(
level
::
level_enum
log_level
);
level
::
level_enum
flush_level
()
const
;
// flush functions
void
flush
();
void
flush_on
(
level
::
level_enum
log_level
);
level
::
level_enum
flush_level
()
const
;
// sinks
const
std
::
vector
<
sink_ptr
>
&
sinks
()
const
;
// sinks
const
std
::
vector
<
sink_ptr
>
&
sinks
()
const
;
std
::
vector
<
sink_ptr
>
&
sinks
();
std
::
vector
<
sink_ptr
>
&
sinks
();
// error handler
void
set_error_handler
(
err_handler
);
// create new logger with same sinks and configuration.
virtual
std
::
shared_ptr
<
logger
>
clone
(
std
::
string
logger_name
);
// error handler
void
set_error_handler
(
err_handler
);
protected
:
virtual
void
sink_it_
(
details
::
log_msg
&
msg
);
// create new logger with same sinks and configuration.
virtual
std
::
shared_ptr
<
logger
>
clone
(
std
::
string
logger_name
);
virtual
void
flush_
();
bool
should_flush_
(
const
details
::
log_msg
&
msg
);
protected
:
virtual
void
sink_it_
(
details
::
log_msg
&
msg
);
// default error handler.
// print the error to stderr with the max rate of 1 message/minute.
void
err_handler_
(
const
std
::
string
&
msg
);
const
std
::
string
name_
;
std
::
vector
<
sink_ptr
>
sinks_
;
spdlog
::
level_t
level_
{
spdlog
::
logger
::
default_level
()};
spdlog
::
level_t
flush_level_
{
level
::
off
};
err_handler
custom_err_handler_
{
nullptr
};
virtual
void
flush_
();
bool
should_flush_
(
const
details
::
log_msg
&
msg
);
// default error handler.
// print the error to stderr with the max rate of 1 message/minute.
void
err_handler_
(
const
std
::
string
&
msg
);
const
std
::
string
name_
;
std
::
vector
<
sink_ptr
>
sinks_
;
spdlog
::
level_t
level_
{
spdlog
::
logger
::
default_level
()};
spdlog
::
level_t
flush_level_
{
level
::
off
};
err_handler
custom_err_handler_
{
nullptr
};
};
}
// namespace spdlog
...
...
include/spdlog/sinks/sink.h
View file @
2de924a1
...
...
@@ -17,7 +17,7 @@ class sink
public
:
sink
();
explicit
sink
(
std
::
unique_ptr
<
spdlog
::
formatter
>
formatter
);
explicit
sink
(
std
::
unique_ptr
<
spdlog
::
formatter
>
formatter
);
virtual
~
sink
()
=
default
;
virtual
void
log
(
const
details
::
log_msg
&
msg
)
=
0
;
virtual
void
flush
()
=
0
;
...
...
@@ -25,9 +25,9 @@ public:
virtual
void
set_formatter
(
std
::
unique_ptr
<
spdlog
::
formatter
>
sink_formatter
)
=
0
;
bool
should_log
(
level
::
level_enum
msg_level
)
const
;
void
set_level
(
level
::
level_enum
log_level
);
level
::
level_enum
level
()
const
;
protected
:
...
...
include/spdlog/spdlog.h
View file @
2de924a1
...
...
@@ -328,7 +328,8 @@ inline void critical(const wchar_t *fmt, const Args &... args)
//
#define SPDLOG_LOGGER_CALL(logger, level, ...) \
do { \
do \
{ \
if (logger->should_log(level)) \
logger->log(spdlog::source_loc{SPDLOG_FILE_BASENAME(__FILE__), __LINE__, SPDLOG_FUNCTION}, level, __VA_ARGS__); \
} while (0)
...
...
tests/test_misc.cpp
View file @
2de924a1
...
...
@@ -107,7 +107,7 @@ TEST_CASE("clone-logger", "[clone]")
cloned
->
info
(
"Some message 2"
);
auto
test_sink
=
std
::
static_pointer_cast
<
sinks
::
test_sink_mt
>
(
cloned
->
sinks
()[
0
]);
spdlog
::
drop_all
();
}
...
...
@@ -128,7 +128,7 @@ TEST_CASE("clone async", "[clone]")
spdlog
::
details
::
os
::
sleep_for_millis
(
10
);
auto
test_sink
=
std
::
static_pointer_cast
<
sinks
::
test_sink_mt
>
(
cloned
->
sinks
()[
0
]);
auto
test_sink
=
std
::
static_pointer_cast
<
sinks
::
test_sink_mt
>
(
cloned
->
sinks
()[
0
]);
spdlog
::
drop_all
();
}
...
...
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