Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
S
spdlog
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Libraries
spdlog
Commits
d163b8c4
Commit
d163b8c4
authored
Dec 21, 2014
by
gabime
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
astyle
parent
58308df3
Changes
38
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
38 changed files
with
3211 additions
and
3211 deletions
+3211
-3211
astyle.sh
astyle.sh
+1
-1
bench/boost-bench-mt.cpp
bench/boost-bench-mt.cpp
+38
-38
bench/boost-bench.cpp
bench/boost-bench.cpp
+19
-19
bench/easylogging-bench-mt.cpp
bench/easylogging-bench-mt.cpp
+33
-33
bench/easylogging-bench.cpp
bench/easylogging-bench.cpp
+7
-7
bench/g2log-async.cpp
bench/g2log-async.cpp
+34
-34
bench/glog-bench-mt.cpp
bench/glog-bench-mt.cpp
+33
-33
bench/glog-bench.cpp
bench/glog-bench.cpp
+7
-7
bench/spdlog-async.cpp
bench/spdlog-async.cpp
+38
-38
bench/spdlog-bench-mt.cpp
bench/spdlog-bench-mt.cpp
+26
-26
bench/spdlog-bench.cpp
bench/spdlog-bench.cpp
+8
-8
example/bench.cpp
example/bench.cpp
+93
-93
example/example.cpp
example/example.cpp
+49
-49
example/utils.h
example/utils.h
+10
-10
include/spdlog/async_logger.h
include/spdlog/async_logger.h
+9
-9
include/spdlog/common.h
include/spdlog/common.h
+9
-8
include/spdlog/details/async_log_helper.h
include/spdlog/details/async_log_helper.h
+139
-139
include/spdlog/details/async_logger_impl.h
include/spdlog/details/async_logger_impl.h
+10
-10
include/spdlog/details/file_helper.h
include/spdlog/details/file_helper.h
+78
-78
include/spdlog/details/format.h
include/spdlog/details/format.h
+1560
-1560
include/spdlog/details/line_logger.h
include/spdlog/details/line_logger.h
+63
-63
include/spdlog/details/log_msg.h
include/spdlog/details/log_msg.h
+49
-50
include/spdlog/details/logger_impl.h
include/spdlog/details/logger_impl.h
+46
-46
include/spdlog/details/mpmc_bounded_q.h
include/spdlog/details/mpmc_bounded_q.h
+93
-93
include/spdlog/details/null_mutex.h
include/spdlog/details/null_mutex.h
+6
-6
include/spdlog/details/os.h
include/spdlog/details/os.h
+38
-38
include/spdlog/details/pattern_formatter_impl.h
include/spdlog/details/pattern_formatter_impl.h
+333
-333
include/spdlog/details/registry.h
include/spdlog/details/registry.h
+106
-106
include/spdlog/details/spdlog_impl.h
include/spdlog/details/spdlog_impl.h
+21
-21
include/spdlog/formatter.h
include/spdlog/formatter.h
+10
-10
include/spdlog/logger.h
include/spdlog/logger.h
+60
-60
include/spdlog/sinks/base_sink.h
include/spdlog/sinks/base_sink.h
+11
-11
include/spdlog/sinks/file_sinks.h
include/spdlog/sinks/file_sinks.h
+124
-124
include/spdlog/sinks/null_sink.h
include/spdlog/sinks/null_sink.h
+2
-2
include/spdlog/sinks/ostream_sink.h
include/spdlog/sinks/ostream_sink.h
+9
-9
include/spdlog/sinks/sink.h
include/spdlog/sinks/sink.h
+2
-2
include/spdlog/sinks/stdout_sinks.h
include/spdlog/sinks/stdout_sinks.h
+2
-2
include/spdlog/sinks/syslog_sink.h
include/spdlog/sinks/syslog_sink.h
+35
-35
No files found.
astyle.sh
View file @
d163b8c4
#!/bin/bash
find
.
-name
"*
\.
h"
-o
-name
"*
\.
cpp"
|xargs dos2unix
find
.
-name
"*
\.
h"
-o
-name
"*
\.
cpp"
|xargs astyle
-n
-
A1
find
.
-name
"*
\.
h"
-o
-name
"*
\.
cpp"
|xargs astyle
-n
-
c
-t4
-A1
bench/boost-bench-mt.cpp
View file @
d163b8c4
...
...
@@ -18,17 +18,17 @@ namespace keywords = boost::log::keywords;
void
init
()
{
logging
::
add_file_log
(
keywords
::
file_name
=
"logs/boost-sample_%N.log"
,
/*< file name pattern >*/
keywords
::
auto_flush
=
false
,
keywords
::
format
=
"[%TimeStamp%]: %Message%"
);
logging
::
core
::
get
()
->
set_filter
(
logging
::
trivial
::
severity
>=
logging
::
trivial
::
info
);
logging
::
add_file_log
(
keywords
::
file_name
=
"logs/boost-sample_%N.log"
,
/*< file name pattern >*/
keywords
::
auto_flush
=
false
,
keywords
::
format
=
"[%TimeStamp%]: %Message%"
);
logging
::
core
::
get
()
->
set_filter
(
logging
::
trivial
::
severity
>=
logging
::
trivial
::
info
);
}
...
...
@@ -37,43 +37,43 @@ using namespace std;
int
main
(
int
argc
,
char
*
argv
[])
{
int
thread_count
=
10
;
if
(
argc
>
1
)
thread_count
=
atoi
(
argv
[
1
]);
int
thread_count
=
10
;
if
(
argc
>
1
)
thread_count
=
atoi
(
argv
[
1
]);
int
howmany
=
1000000
;
int
howmany
=
1000000
;
init
();
logging
::
add_common_attributes
();
init
();
logging
::
add_common_attributes
();
using
namespace
logging
::
trivial
;
using
namespace
logging
::
trivial
;
src
::
severity_logger_mt
<
severity_level
>
lg
;
src
::
severity_logger_mt
<
severity_level
>
lg
;
std
::
atomic
<
int
>
msg_counter
{
0
};
vector
<
thread
>
threads
;
std
::
atomic
<
int
>
msg_counter
{
0
};
vector
<
thread
>
threads
;
for
(
int
t
=
0
;
t
<
thread_count
;
++
t
)
{
threads
.
push_back
(
std
::
thread
([
&
]()
{
while
(
true
)
{
int
counter
=
++
msg_counter
;
if
(
counter
>
howmany
)
break
;
BOOST_LOG_SEV
(
lg
,
info
)
<<
"boost message #"
<<
counter
<<
": This is some text for your pleasure"
;
}
}));
}
for
(
int
t
=
0
;
t
<
thread_count
;
++
t
)
{
threads
.
push_back
(
std
::
thread
([
&
]()
{
while
(
true
)
{
int
counter
=
++
msg_counter
;
if
(
counter
>
howmany
)
break
;
BOOST_LOG_SEV
(
lg
,
info
)
<<
"boost message #"
<<
counter
<<
": This is some text for your pleasure"
;
}
}));
}
for
(
auto
&
t
:
threads
)
{
t
.
join
();
};
for
(
auto
&
t
:
threads
)
{
t
.
join
();
};
return
0
;
return
0
;
}
bench/boost-bench.cpp
View file @
d163b8c4
...
...
@@ -15,30 +15,30 @@ namespace keywords = boost::log::keywords;
void
init
()
{
logging
::
add_file_log
(
keywords
::
file_name
=
"logs/boost-sample_%N.log"
,
/*< file name pattern >*/
keywords
::
auto_flush
=
false
,
keywords
::
format
=
"[%TimeStamp%]: %Message%"
);
logging
::
core
::
get
()
->
set_filter
(
logging
::
trivial
::
severity
>=
logging
::
trivial
::
info
);
logging
::
add_file_log
(
keywords
::
file_name
=
"logs/boost-sample_%N.log"
,
/*< file name pattern >*/
keywords
::
auto_flush
=
false
,
keywords
::
format
=
"[%TimeStamp%]: %Message%"
);
logging
::
core
::
get
()
->
set_filter
(
logging
::
trivial
::
severity
>=
logging
::
trivial
::
info
);
}
int
main
(
int
argc
,
char
*
[])
{
int
howmany
=
1000000
;
init
();
logging
::
add_common_attributes
();
int
howmany
=
1000000
;
init
();
logging
::
add_common_attributes
();
using
namespace
logging
::
trivial
;
src
::
severity_logger_mt
<
severity_level
>
lg
;
for
(
int
i
=
0
;
i
<
howmany
;
++
i
)
BOOST_LOG_SEV
(
lg
,
info
)
<<
"boost message #"
<<
i
<<
": This is some text for your pleasure"
;
using
namespace
logging
::
trivial
;
src
::
severity_logger_mt
<
severity_level
>
lg
;
for
(
int
i
=
0
;
i
<
howmany
;
++
i
)
BOOST_LOG_SEV
(
lg
,
info
)
<<
"boost message #"
<<
i
<<
": This is some text for your pleasure"
;
return
0
;
return
0
;
}
bench/easylogging-bench-mt.cpp
View file @
d163b8c4
...
...
@@ -11,37 +11,37 @@ using namespace std;
int
main
(
int
argc
,
char
*
argv
[])
{
int
thread_count
=
10
;
if
(
argc
>
1
)
thread_count
=
atoi
(
argv
[
1
]);
int
howmany
=
1000000
;
// Load configuration from file
el
::
Configurations
conf
(
"easyl.conf"
);
el
::
Loggers
::
reconfigureLogger
(
"default"
,
conf
);
std
::
atomic
<
int
>
msg_counter
{
0
};
vector
<
thread
>
threads
;
for
(
int
t
=
0
;
t
<
thread_count
;
++
t
)
{
threads
.
push_back
(
std
::
thread
([
&
]()
{
while
(
true
)
{
int
counter
=
++
msg_counter
;
if
(
counter
>
howmany
)
break
;
LOG
(
INFO
)
<<
"easylog message #"
<<
counter
<<
": This is some text for your pleasure"
;
}
}));
}
for
(
auto
&
t
:
threads
)
{
t
.
join
();
};
return
0
;
int
thread_count
=
10
;
if
(
argc
>
1
)
thread_count
=
atoi
(
argv
[
1
]);
int
howmany
=
1000000
;
// Load configuration from file
el
::
Configurations
conf
(
"easyl.conf"
);
el
::
Loggers
::
reconfigureLogger
(
"default"
,
conf
);
std
::
atomic
<
int
>
msg_counter
{
0
};
vector
<
thread
>
threads
;
for
(
int
t
=
0
;
t
<
thread_count
;
++
t
)
{
threads
.
push_back
(
std
::
thread
([
&
]()
{
while
(
true
)
{
int
counter
=
++
msg_counter
;
if
(
counter
>
howmany
)
break
;
LOG
(
INFO
)
<<
"easylog message #"
<<
counter
<<
": This is some text for your pleasure"
;
}
}));
}
for
(
auto
&
t
:
threads
)
{
t
.
join
();
};
return
0
;
}
bench/easylogging-bench.cpp
View file @
d163b8c4
...
...
@@ -5,12 +5,12 @@ _INITIALIZE_EASYLOGGINGPP
int
main
(
int
,
char
*
[])
{
int
howmany
=
1000000
;
// Load configuration from file
el
::
Configurations
conf
(
"easyl.conf"
);
el
::
Loggers
::
reconfigureLogger
(
"default"
,
conf
);
for
(
int
i
=
0
;
i
<
howmany
;
++
i
)
LOG
(
INFO
)
<<
"easylog message #"
<<
i
<<
": This is some text for your pleasure"
;
return
0
;
el
::
Configurations
conf
(
"easyl.conf"
);
el
::
Loggers
::
reconfigureLogger
(
"default"
,
conf
);
for
(
int
i
=
0
;
i
<
howmany
;
++
i
)
LOG
(
INFO
)
<<
"easylog message #"
<<
i
<<
": This is some text for your pleasure"
;
return
0
;
}
bench/g2log-async.cpp
View file @
d163b8c4
...
...
@@ -14,44 +14,44 @@ int main(int argc, char* argv[])
{
using
namespace
std
::
chrono
;
using
clock
=
steady_clock
;
int
thread_count
=
10
;
if
(
argc
>
1
)
thread_count
=
atoi
(
argv
[
1
]);
int
howmany
=
1000000
;
int
thread_count
=
10
;
g2LogWorker
g2log
(
argv
[
0
],
"logs"
);
g2
::
initializeLogging
(
&
g2log
);
if
(
argc
>
1
)
thread_count
=
atoi
(
argv
[
1
]);
int
howmany
=
1000000
;
g2LogWorker
g2log
(
argv
[
0
],
"logs"
);
g2
::
initializeLogging
(
&
g2log
);
std
::
atomic
<
int
>
msg_counter
{
0
};
vector
<
thread
>
threads
;
std
::
atomic
<
int
>
msg_counter
{
0
};
vector
<
thread
>
threads
;
auto
start
=
clock
::
now
();
for
(
int
t
=
0
;
t
<
thread_count
;
++
t
)
{
threads
.
push_back
(
std
::
thread
([
&
]()
{
while
(
true
)
{
int
counter
=
++
msg_counter
;
if
(
counter
>
howmany
)
break
;
LOG
(
INFO
)
<<
"g2log message #"
<<
counter
<<
": This is some text for your pleasure"
;
}
}));
}
for
(
auto
&
t
:
threads
)
{
t
.
join
();
};
for
(
int
t
=
0
;
t
<
thread_count
;
++
t
)
{
threads
.
push_back
(
std
::
thread
([
&
]()
{
while
(
true
)
{
int
counter
=
++
msg_counter
;
if
(
counter
>
howmany
)
break
;
LOG
(
INFO
)
<<
"g2log message #"
<<
counter
<<
": This is some text for your pleasure"
;
}
}));
}
for
(
auto
&
t
:
threads
)
{
t
.
join
();
};
duration
<
float
>
delta
=
clock
::
now
()
-
start
;
float
deltaf
=
delta
.
count
();
auto
rate
=
howmany
/
deltaf
;
cout
<<
"Total: "
<<
howmany
<<
std
::
endl
;
cout
<<
"Threads: "
<<
thread_count
<<
std
::
endl
;
std
::
cout
<<
"Delta = "
<<
deltaf
<<
" seconds"
<<
std
::
endl
;
std
::
cout
<<
"Rate = "
<<
rate
<<
"/sec"
<<
std
::
endl
;
auto
rate
=
howmany
/
deltaf
;
cout
<<
"Total: "
<<
howmany
<<
std
::
endl
;
cout
<<
"Threads: "
<<
thread_count
<<
std
::
endl
;
std
::
cout
<<
"Delta = "
<<
deltaf
<<
" seconds"
<<
std
::
endl
;
std
::
cout
<<
"Rate = "
<<
rate
<<
"/sec"
<<
std
::
endl
;
}
bench/glog-bench-mt.cpp
View file @
d163b8c4
...
...
@@ -9,37 +9,37 @@ using namespace std;
int
main
(
int
argc
,
char
*
argv
[])
{
int
thread_count
=
10
;
if
(
argc
>
1
)
thread_count
=
atoi
(
argv
[
1
]);
int
howmany
=
1000000
;
FLAGS_logtostderr
=
0
;
FLAGS_log_dir
=
"logs"
;
google
::
InitGoogleLogging
(
argv
[
0
]);
std
::
atomic
<
int
>
msg_counter
{
0
};
vector
<
thread
>
threads
;
for
(
int
t
=
0
;
t
<
thread_count
;
++
t
)
{
threads
.
push_back
(
std
::
thread
([
&
]()
{
while
(
true
)
{
int
counter
=
++
msg_counter
;
if
(
counter
>
howmany
)
break
;
LOG
(
INFO
)
<<
"glog message #"
<<
counter
<<
": This is some text for your pleasure"
;
}
}));
}
for
(
auto
&
t
:
threads
)
{
t
.
join
();
};
return
0
;
int
thread_count
=
10
;
if
(
argc
>
1
)
thread_count
=
atoi
(
argv
[
1
]);
int
howmany
=
1000000
;
FLAGS_logtostderr
=
0
;
FLAGS_log_dir
=
"logs"
;
google
::
InitGoogleLogging
(
argv
[
0
]);
std
::
atomic
<
int
>
msg_counter
{
0
};
vector
<
thread
>
threads
;
for
(
int
t
=
0
;
t
<
thread_count
;
++
t
)
{
threads
.
push_back
(
std
::
thread
([
&
]()
{
while
(
true
)
{
int
counter
=
++
msg_counter
;
if
(
counter
>
howmany
)
break
;
LOG
(
INFO
)
<<
"glog message #"
<<
counter
<<
": This is some text for your pleasure"
;
}
}));
}
for
(
auto
&
t
:
threads
)
{
t
.
join
();
};
return
0
;
}
bench/glog-bench.cpp
View file @
d163b8c4
...
...
@@ -4,14 +4,14 @@
int
main
(
int
,
char
*
argv
[])
{
int
howmany
=
1000000
;
int
howmany
=
1000000
;
FLAGS_logtostderr
=
0
;
FLAGS_log_dir
=
"logs"
;
google
::
InitGoogleLogging
(
argv
[
0
]);
for
(
int
i
=
0
;
i
<
howmany
;
++
i
)
LOG
(
INFO
)
<<
"glog message # "
<<
i
<<
": This is some text for your pleasure"
;
FLAGS_logtostderr
=
0
;
FLAGS_log_dir
=
"logs"
;
google
::
InitGoogleLogging
(
argv
[
0
]);
for
(
int
i
=
0
;
i
<
howmany
;
++
i
)
LOG
(
INFO
)
<<
"glog message # "
<<
i
<<
": This is some text for your pleasure"
;
return
0
;
return
0
;
}
bench/spdlog-async.cpp
View file @
d163b8c4
...
...
@@ -11,48 +11,48 @@ using namespace std;
int
main
(
int
argc
,
char
*
argv
[])
{
using
namespace
std
::
chrono
;
using
clock
=
steady_clock
;
namespace
spd
=
spdlog
;
int
thread_count
=
10
;
if
(
argc
>
1
)
thread_count
=
atoi
(
argv
[
1
]);
int
howmany
=
1000000
;
spd
::
set_async_mode
(
1048576
);
auto
logger
=
spdlog
::
create
<
spd
::
sinks
::
simple_file_sink_mt
>
(
"file_logger"
,
"logs/spd-bench-async.txt"
,
false
);
logger
->
set_pattern
(
"[%Y-%b-%d %T.%e]: %v"
);
std
::
atomic
<
int
>
msg_counter
{
0
};
vector
<
thread
>
threads
;
int
thread_count
=
10
;
if
(
argc
>
1
)
thread_count
=
atoi
(
argv
[
1
]);
int
howmany
=
1000000
;
spd
::
set_async_mode
(
1048576
);
auto
logger
=
spdlog
::
create
<
spd
::
sinks
::
simple_file_sink_mt
>
(
"file_logger"
,
"logs/spd-bench-async.txt"
,
false
);
logger
->
set_pattern
(
"[%Y-%b-%d %T.%e]: %v"
);
std
::
atomic
<
int
>
msg_counter
{
0
};
vector
<
thread
>
threads
;
auto
start
=
clock
::
now
();
for
(
int
t
=
0
;
t
<
thread_count
;
++
t
)
{
threads
.
push_back
(
std
::
thread
([
&
]()
{
while
(
true
)
{
int
counter
=
++
msg_counter
;
if
(
counter
>
howmany
)
break
;
logger
->
info
()
<<
"spdlog message #"
<<
counter
<<
": This is some text for your pleasure"
;
}
}));
}
for
(
auto
&
t
:
threads
)
{
t
.
join
();
};
for
(
int
t
=
0
;
t
<
thread_count
;
++
t
)
{
threads
.
push_back
(
std
::
thread
([
&
]()
{
while
(
true
)
{
int
counter
=
++
msg_counter
;
if
(
counter
>
howmany
)
break
;
logger
->
info
()
<<
"spdlog message #"
<<
counter
<<
": This is some text for your pleasure"
;
}
}));
}
for
(
auto
&
t
:
threads
)
{
t
.
join
();
};
duration
<
float
>
delta
=
clock
::
now
()
-
start
;
float
deltaf
=
delta
.
count
();
auto
rate
=
howmany
/
deltaf
;
cout
<<
"Total: "
<<
howmany
<<
std
::
endl
;
cout
<<
"Threads: "
<<
thread_count
<<
std
::
endl
;
std
::
cout
<<
"Delta = "
<<
deltaf
<<
" seconds"
<<
std
::
endl
;
std
::
cout
<<
"Rate = "
<<
rate
<<
"/sec"
<<
std
::
endl
;
auto
rate
=
howmany
/
deltaf
;
cout
<<
"Total: "
<<
howmany
<<
std
::
endl
;
cout
<<
"Threads: "
<<
thread_count
<<
std
::
endl
;
std
::
cout
<<
"Delta = "
<<
deltaf
<<
" seconds"
<<
std
::
endl
;
std
::
cout
<<
"Rate = "
<<
rate
<<
"/sec"
<<
std
::
endl
;
}
bench/spdlog-bench-mt.cpp
View file @
d163b8c4
...
...
@@ -10,41 +10,41 @@ using namespace std;
int
main
(
int
argc
,
char
*
argv
[])
{
int
thread_count
=
10
;
if
(
argc
>
1
)
thread_count
=
atoi
(
argv
[
1
]);
int
thread_count
=
10
;
if
(
argc
>
1
)
thread_count
=
atoi
(
argv
[
1
]);
int
howmany
=
1000000
;
int
howmany
=
1000000
;
namespace
spd
=
spdlog
;
namespace
spd
=
spdlog
;
auto
logger
=
spdlog
::
create
<
spd
::
sinks
::
simple_file_sink_mt
>
(
"file_logger"
,
"logs/spd-bench-mt.txt"
,
false
);
auto
logger
=
spdlog
::
create
<
spd
::
sinks
::
simple_file_sink_mt
>
(
"file_logger"
,
"logs/spd-bench-mt.txt"
,
false
);
logger
->
set_pattern
(
"[%Y-%b-%d %T.%e]: %v"
);
logger
->
set_pattern
(
"[%Y-%b-%d %T.%e]: %v"
);
std
::
atomic
<
int
>
msg_counter
{
0
};
vector
<
thread
>
threads
;
std
::
atomic
<
int
>
msg_counter
{
0
};
vector
<
thread
>
threads
;
for
(
int
t
=
0
;
t
<
thread_count
;
++
t
)
{
threads
.
push_back
(
std
::
thread
([
&
]()
{
while
(
true
)
{
int
counter
=
++
msg_counter
;
if
(
counter
>
howmany
)
break
;
logger
->
info
()
<<
"spdlog message #"
<<
counter
<<
": This is some text for your pleasure"
;
}
}));
}
for
(
int
t
=
0
;
t
<
thread_count
;
++
t
)
{
threads
.
push_back
(
std
::
thread
([
&
]()
{
while
(
true
)
{
int
counter
=
++
msg_counter
;
if
(
counter
>
howmany
)
break
;
logger
->
info
()
<<
"spdlog message #"
<<
counter
<<
": This is some text for your pleasure"
;
}
}));
}
for
(
auto
&
t
:
threads
)
{
t
.
join
();
};
for
(
auto
&
t
:
threads
)
{
t
.
join
();
};
return
0
;
return
0
;
}
bench/spdlog-bench.cpp
View file @
d163b8c4
...
...
@@ -4,13 +4,13 @@
int
main
(
int
,
char
*
[])
{
int
howmany
=
1000000
;
namespace
spd
=
spdlog
;
///Create a file rotating logger with 5mb size max and 3 rotated files
auto
logger
=
spdlog
::
create
<
spd
::
sinks
::
simple_file_sink_st
>
(
"file_logger"
,
"logs/spd-bench-st.txt"
,
false
);
int
howmany
=
1000000
;
namespace
spd
=
spdlog
;
///Create a file rotating logger with 5mb size max and 3 rotated files
auto
logger
=
spdlog
::
create
<
spd
::
sinks
::
simple_file_sink_st
>
(
"file_logger"
,
"logs/spd-bench-st.txt"
,
false
);
logger
->
set_pattern
(
"[%Y-%b-%d %T.%e]: %v"
);
for
(
int
i
=
0
;
i
<
howmany
;
++
i
)
logger
->
info
()
<<
"spdlog message #"
<<
i
<<
": This is some text for your pleasure"
;
return
0
;
logger
->
set_pattern
(
"[%Y-%b-%d %T.%e]: %v"
);
for
(
int
i
=
0
;
i
<
howmany
;
++
i
)
logger
->
info
()
<<
"spdlog message #"
<<
i
<<
": This is some text for your pleasure"
;
return
0
;
}
example/bench.cpp
View file @
d163b8c4
...
...
@@ -50,110 +50,110 @@ void bench_mt(int howmany, std::shared_ptr<spdlog::logger> log, int thread_count
int
main
(
int
argc
,
char
*
argv
[])
{
int
howmany
=
1048576
;
int
threads
=
10
;
bool
auto_flush
=
false
;
int
file_size
=
30
*
1024
*
1024
;
int
rotating_files
=
5
;
try
{
if
(
argc
>
1
)
howmany
=
atoi
(
argv
[
1
]);
if
(
argc
>
2
)
threads
=
atoi
(
argv
[
2
]);
cout
<<
"*******************************************************************************
\n
"
;
cout
<<
"Single thread, "
<<
format
(
howmany
)
<<
" iterations, auto flush="
<<
auto_flush
<<
endl
;
cout
<<
"*******************************************************************************
\n
"
;
auto
rotating_st
=
spdlog
::
rotating_logger_st
(
"rotating_st"
,
"logs/rotating_st"
,
file_size
,
rotating_files
,
auto_flush
);
bench
(
howmany
,
rotating_st
);
auto
daily_st
=
spdlog
::
daily_logger_st
(
"daily_st"
,
"logs/daily_st"
,
auto_flush
);
bench
(
howmany
,
daily_st
);
bench
(
howmany
,
spdlog
::
create
<
null_sink_st
>
(
"null_st"
));
cout
<<
"
\n
*******************************************************************************
\n
"
;
cout
<<
threads
<<
" threads sharing same logger, "
<<
format
(
howmany
)
<<
" iterations, auto_flush="
<<
auto_flush
<<
endl
;
cout
<<
"*******************************************************************************
\n
"
;
auto
rotating_mt
=
spdlog
::
rotating_logger_mt
(
"rotating_mt"
,
"logs/rotating_mt"
,
file_size
,
rotating_files
,
auto_flush
);
bench_mt
(
howmany
,
rotating_mt
,
threads
);
auto
daily_mt
=
spdlog
::
daily_logger_mt
(
"daily_mt"
,
"logs/daily_mt"
,
auto_flush
);
bench_mt
(
howmany
,
daily_mt
,
threads
);
bench
(
howmany
,
spdlog
::
create
<
null_sink_st
>
(
"null_mt"
));
cout
<<
"
\n
*******************************************************************************
\n
"
;
cout
<<
"async logging.. "
<<
threads
<<
" threads sharing same logger, "
<<
format
(
howmany
)
<<
" iterations, auto_flush="
<<
auto_flush
<<
endl
;
cout
<<
"*******************************************************************************
\n
"
;
spdlog
::
set_async_mode
(
howmany
);
for
(
int
i
=
0
;
i
<
3
;
++
i
)
{
auto
as
=
spdlog
::
daily_logger_st
(
"as"
,
"logs/daily_async"
,
auto_flush
);
bench_mt
(
howmany
,
as
,
threads
);
spdlog
::
drop
(
"as"
);
}
}
catch
(
std
::
exception
&
ex
)
{
std
::
cerr
<<
"Error: "
<<
ex
.
what
()
<<
std
::
endl
;
perror
(
"Last error"
);
}
return
0
;
int
howmany
=
1048576
;
int
threads
=
10
;
bool
auto_flush
=
false
;
int
file_size
=
30
*
1024
*
1024
;
int
rotating_files
=
5
;
try
{
if
(
argc
>
1
)
howmany
=
atoi
(
argv
[
1
]);
if
(
argc
>
2
)
threads
=
atoi
(
argv
[
2
]);
cout
<<
"*******************************************************************************
\n
"
;
cout
<<
"Single thread, "
<<
format
(
howmany
)
<<
" iterations, auto flush="
<<
auto_flush
<<
endl
;
cout
<<
"*******************************************************************************
\n
"
;
auto
rotating_st
=
spdlog
::
rotating_logger_st
(
"rotating_st"
,
"logs/rotating_st"
,
file_size
,
rotating_files
,
auto_flush
);
bench
(
howmany
,
rotating_st
);
auto
daily_st
=
spdlog
::
daily_logger_st
(
"daily_st"
,
"logs/daily_st"
,
auto_flush
);
bench
(
howmany
,
daily_st
);
bench
(
howmany
,
spdlog
::
create
<
null_sink_st
>
(
"null_st"
));
cout
<<
"
\n
*******************************************************************************
\n
"
;
cout
<<
threads
<<
" threads sharing same logger, "
<<
format
(
howmany
)
<<
" iterations, auto_flush="
<<
auto_flush
<<
endl
;
cout
<<
"*******************************************************************************
\n
"
;
auto
rotating_mt
=
spdlog
::
rotating_logger_mt
(
"rotating_mt"
,
"logs/rotating_mt"
,
file_size
,
rotating_files
,
auto_flush
);
bench_mt
(
howmany
,
rotating_mt
,
threads
);
auto
daily_mt
=
spdlog
::
daily_logger_mt
(
"daily_mt"
,
"logs/daily_mt"
,
auto_flush
);
bench_mt
(
howmany
,
daily_mt
,
threads
);
bench
(
howmany
,
spdlog
::
create
<
null_sink_st
>
(
"null_mt"
));
cout
<<
"
\n
*******************************************************************************
\n
"
;
cout
<<
"async logging.. "
<<
threads
<<
" threads sharing same logger, "
<<
format
(
howmany
)
<<
" iterations, auto_flush="
<<
auto_flush
<<
endl
;
cout
<<
"*******************************************************************************
\n
"
;
spdlog
::
set_async_mode
(
howmany
);
for
(
int
i
=
0
;
i
<
3
;
++
i
)
{
auto
as
=
spdlog
::
daily_logger_st
(
"as"
,
"logs/daily_async"
,
auto_flush
);
bench_mt
(
howmany
,
as
,
threads
);
spdlog
::
drop
(
"as"
);
}
}
catch
(
std
::
exception
&
ex
)
{
std
::
cerr
<<
"Error: "
<<
ex
.
what
()
<<
std
::
endl
;
perror
(
"Last error"
);
}
return
0
;
}
void
bench
(
int
howmany
,
std
::
shared_ptr
<
spdlog
::
logger
>
log
)
{
cout
<<
log
->
name
()
<<
"...
\t\t
"
<<
flush
;
auto
start
=
system_clock
::
now
();
for
(
auto
i
=
0
;
i
<
howmany
;
++
i
)
{
log
->
info
(
"Hello logger: msg number {}"
,
i
);
}
cout
<<
log
->
name
()
<<
"...
\t\t
"
<<
flush
;
auto
start
=
system_clock
::
now
();
for
(
auto
i
=
0
;
i
<
howmany
;
++
i
)
{
log
->
info
(
"Hello logger: msg number {}"
,
i
);
}
auto
delta
=
system_clock
::
now
()
-
start
;
auto
delta_d
=
duration_cast
<
duration
<
double
>>
(
delta
).
count
();
cout
<<
format
(
int
(
howmany
/
delta_d
))
<<
"/sec"
<<
endl
;
auto
delta
=
system_clock
::
now
()
-
start
;
auto
delta_d
=
duration_cast
<
duration
<
double
>>
(
delta
).
count
();
cout
<<
format
(
int
(
howmany
/
delta_d
))
<<
"/sec"
<<
endl
;
}
void
bench_mt
(
int
howmany
,
std
::
shared_ptr
<
spdlog
::
logger
>
log
,
int
thread_count
)
{
cout
<<
log
->
name
()
<<
"...
\t\t
"
<<
flush
;
std
::
atomic
<
int
>
msg_counter
{
0
};
vector
<
thread
>
threads
;
auto
start
=
system_clock
::
now
();
for
(
int
t
=
0
;
t
<
thread_count
;
++
t
)
{
threads
.
push_back
(
std
::
thread
([
&
]()
{
for
(;;)
{
int
counter
=
++
msg_counter
;
if
(
counter
>
howmany
)
break
;
log
->
info
(
"Hello logger: msg number {}"
,
counter
);
}
}));
}
for
(
auto
&
t
:
threads
)
{
t
.
join
();
};
auto
delta
=
system_clock
::
now
()
-
start
;
auto
delta_d
=
duration_cast
<
duration
<
double
>>
(
delta
).
count
();
cout
<<
format
(
int
(
howmany
/
delta_d
))
<<
"/sec"
<<
endl
;
cout
<<
log
->
name
()
<<
"...
\t\t
"
<<
flush
;
std
::
atomic
<
int
>
msg_counter
{
0
};
vector
<
thread
>
threads
;
auto
start
=
system_clock
::
now
();
for
(
int
t
=
0
;
t
<
thread_count
;
++
t
)
{
threads
.
push_back
(
std
::
thread
([
&
]()
{
for
(;;)
{
int
counter
=
++
msg_counter
;
if
(
counter
>
howmany
)
break
;
log
->
info
(
"Hello logger: msg number {}"
,
counter
);
}
}));
}
for
(
auto
&
t
:
threads
)
{
t
.
join
();
};
auto
delta
=
system_clock
::
now
()
-
start
;
auto
delta_d
=
duration_cast
<
duration
<
double
>>
(
delta
).
count
();
cout
<<
format
(
int
(
howmany
/
delta_d
))
<<
"/sec"
<<
endl
;
}
example/example.cpp
View file @
d163b8c4
...
...
@@ -30,61 +30,61 @@
int
main
(
int
,
char
*
[])
{
namespace
spd
=
spdlog
;
try
{
// Set log level to all loggers to debug and above
spd
::
set_level
(
spd
::
level
::
debug
);
namespace
spd
=
spdlog
;
try
{
// Set log level to all loggers to debug and above
spd
::
set_level
(
spd
::
level
::
debug
);
// Create console, multithreaded logger
auto
console
=
spd
::
stdout_logger_mt
(
"console"
);
console
->
info
(
"Welcome to spdlog!"
)
;
console
->
info
(
"An info message example {}.."
,
1
);
console
->
info
()
<<
"Streams are supported too "
<<
1
;
// Create console, multithreaded logger
auto
console
=
spd
::
stdout_logger_mt
(
"console"
);
console
->
info
(
"Welcome to spdlog!"
)
;
console
->
info
(
"An info message example {}.."
,
1
);
console
->
info
()
<<
"Streams are supported too "
<<
1
;
console
->
info
(
"Easy padding in numbers like {:08d}"
,
12
);
console
->
info
(
"Support for int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}"
,
42
);
console
->
info
(
"Support for floats {:03.2f}"
,
1.23456
);
console
->
info
(
"Positional args are {1} {0}.."
,
"too"
,
"supported"
);
console
->
info
(
"Easy padding in numbers like {:08d}"
,
12
);
console
->
info
(
"Support for int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}"
,
42
);
console
->
info
(
"Support for floats {:03.2f}"
,
1.23456
);
console
->
info
(
"Positional args are {1} {0}.."
,
"too"
,
"supported"
);
console
->
info
(
"{:<30}"
,
"left aligned"
);
console
->
info
(
"{:>30}"
,
"right aligned"
);
console
->
info
(
"{:^30}"
,
"centered"
);
// Create a file rotating logger with 5mb size max and 3 rotated files
auto
file_logger
=
spd
::
rotating_logger_mt
(
"file_logger"
,
"logs/mylogfile"
,
1048576
*
5
,
3
);
file_logger
->
set_level
(
spd
::
level
::
info
);
for
(
int
i
=
0
;
i
<
10
;
++
i
)
file_logger
->
info
(
"{} * {} equals {:>10}"
,
i
,
i
,
i
*
i
);
console
->
info
(
"{:<30}"
,
"left aligned"
);
console
->
info
(
"{:>30}"
,
"right aligned"
);
console
->
info
(
"{:^30}"
,
"centered"
);
// Customize msg format for all messages
spd
::
set_pattern
(
"*** [%H:%M:%S %z] [thread %t] %v ***"
);
file_logger
->
info
(
"This is another message with custom format"
);
// Create a file rotating logger with 5mb size max and 3 rotated files
auto
file_logger
=
spd
::
rotating_logger_mt
(
"file_logger"
,
"logs/mylogfile"
,
1048576
*
5
,
3
);
file_logger
->
set_level
(
spd
::
level
::
info
);
for
(
int
i
=
0
;
i
<
10
;
++
i
)
file_logger
->
info
(
"{} * {} equals {:>10}"
,
i
,
i
,
i
*
i
);
spd
::
get
(
"console"
)
->
info
(
"loggers can be retrieved from a global registry using the spdlog::get(logger_name) function"
);
// Customize msg format for all messages
spd
::
set_pattern
(
"*** [%H:%M:%S %z] [thread %t] %v ***"
);
file_logger
->
info
(
"This is another message with custom format"
);
SPDLOG_TRACE
(
console
,
"Enabled only #ifdef SPDLOG_TRACE_ON..{} ,{}"
,
1
,
3.23
);
SPDLOG_DEBUG
(
console
,
"Enabled only #ifdef SPDLOG_DEBUG_ON.. {} ,{}"
,
1
,
3.23
);
spd
::
get
(
"console"
)
->
info
(
"loggers can be retrieved from a global registry using the spdlog::get(logger_name) function"
);
//
// Asynchronous logging is very fast..
// Just call spdlog::set_async_mode(q_size) and all created loggers from now on will be asynchronous..
//
size_t
q_size
=
1048576
;
//queue size must be power of 2
spdlog
::
set_async_mode
(
q_size
);
auto
async_file
=
spd
::
daily_logger_st
(
"async_file_logger"
,
"logs/async_log.txt"
);
async_file
->
info
()
<<
"This is async log.."
<<
"Should be very fast!"
;
// syslog example. linux only..
#ifdef __linux__
std
::
string
ident
=
"spdlog-example"
;
auto
syslog_logger
=
spd
::
syslog_logger
(
"syslog"
,
ident
,
LOG_PID
);
syslog_logger
->
warn
(
"This is warning that will end up in syslog. This is Linux only!"
);
#endif
SPDLOG_TRACE
(
console
,
"Enabled only #ifdef SPDLOG_TRACE_ON..{} ,{}"
,
1
,
3.23
);
SPDLOG_DEBUG
(
console
,
"Enabled only #ifdef SPDLOG_DEBUG_ON.. {} ,{}"
,
1
,
3.23
);
}
catch
(
const
spd
::
spdlog_ex
&
ex
)
{
std
::
cout
<<
"Log failed: "
<<
ex
.
what
()
<<
std
::
endl
;
}
//
// Asynchronous logging is very fast..
// Just call spdlog::set_async_mode(q_size) and all created loggers from now on will be asynchronous..
//
size_t
q_size
=
1048576
;
//queue size must be power of 2
spdlog
::
set_async_mode
(
q_size
);
auto
async_file
=
spd
::
daily_logger_st
(
"async_file_logger"
,
"logs/async_log.txt"
);
async_file
->
info
()
<<
"This is async log.."
<<
"Should be very fast!"
;
// syslog example. linux only..
#ifdef __linux__
std
::
string
ident
=
"spdlog-example"
;
auto
syslog_logger
=
spd
::
syslog_logger
(
"syslog"
,
ident
,
LOG_PID
);
syslog_logger
->
warn
(
"This is warning that will end up in syslog. This is Linux only!"
);
#endif
}
catch
(
const
spd
::
spdlog_ex
&
ex
)
{
std
::
cout
<<
"Log failed: "
<<
ex
.
what
()
<<
std
::
endl
;
}
}
example/utils.h
View file @
d163b8c4
...
...
@@ -34,21 +34,21 @@ namespace utils
template
<
typename
T
>
inline
std
::
string
format
(
const
T
&
value
)
{
static
std
::
locale
loc
(
""
);
std
::
stringstream
ss
;
ss
.
imbue
(
loc
);
ss
<<
value
;
return
ss
.
str
();
static
std
::
locale
loc
(
""
);
std
::
stringstream
ss
;
ss
.
imbue
(
loc
);
ss
<<
value
;
return
ss
.
str
();
}
template
<
>
inline
std
::
string
format
(
const
double
&
value
)
{
static
std
::
locale
loc
(
""
);
std
::
stringstream
ss
;
ss
.
imbue
(
loc
);
ss
<<
std
::
fixed
<<
std
::
setprecision
(
1
)
<<
value
;
return
ss
.
str
();
static
std
::
locale
loc
(
""
);
std
::
stringstream
ss
;
ss
.
imbue
(
loc
);
ss
<<
std
::
fixed
<<
std
::
setprecision
(
1
)
<<
value
;
return
ss
.
str
();
}
}
include/spdlog/async_logger.h
View file @
d163b8c4
...
...
@@ -50,20 +50,20 @@ class async_log_helper;
class
async_logger
:
public
logger
{
public:
template
<
class
It
>
async_logger
(
const
std
::
string
&
name
,
const
It
&
begin
,
const
It
&
end
,
size_t
queue_size
);
async_logger
(
const
std
::
string
&
logger_name
,
sinks_init_list
sinks
,
size_t
queue_size
);
async_logger
(
const
std
::
string
&
logger_name
,
sink_ptr
single_sink
,
size_t
queue_size
);
template
<
class
It
>
async_logger
(
const
std
::
string
&
name
,
const
It
&
begin
,
const
It
&
end
,
size_t
queue_size
);
async_logger
(
const
std
::
string
&
logger_name
,
sinks_init_list
sinks
,
size_t
queue_size
);
async_logger
(
const
std
::
string
&
logger_name
,
sink_ptr
single_sink
,
size_t
queue_size
);
protected:
void
_log_msg
(
details
::
log_msg
&
msg
)
override
;
void
_set_formatter
(
spdlog
::
formatter_ptr
msg_formatter
)
override
;
void
_set_pattern
(
const
std
::
string
&
pattern
)
override
;
void
_stop
()
override
;
void
_log_msg
(
details
::
log_msg
&
msg
)
override
;
void
_set_formatter
(
spdlog
::
formatter_ptr
msg_formatter
)
override
;
void
_set_pattern
(
const
std
::
string
&
pattern
)
override
;
void
_stop
()
override
;
private:
std
::
unique_ptr
<
details
::
async_log_helper
>
_async_log_helper
;
std
::
unique_ptr
<
details
::
async_log_helper
>
_async_log_helper
;
};
}
...
...
include/spdlog/common.h
View file @
d163b8c4
...
...
@@ -39,7 +39,8 @@ namespace spdlog
class
formatter
;
namespace
sinks
{
namespace
sinks
{
class
sink
;
}
...
...
@@ -70,7 +71,7 @@ static const char* level_names[] { "trace", "debug", "info", "notice", "warning"
inline
const
char
*
to_str
(
spdlog
::
level
::
level_enum
l
)
{
return
level_names
[
l
];
return
level_names
[
l
];
}
}
//level
...
...
@@ -80,13 +81,13 @@ inline const char* to_str(spdlog::level::level_enum l)
class
spdlog_ex
:
public
std
::
exception
{
public:
spdlog_ex
(
const
std
::
string
&
msg
)
:
_msg
(
msg
)
{}
const
char
*
what
()
const
SPDLOG_NOEXCEPT
override
{
return
_msg
.
c_str
();
}
spdlog_ex
(
const
std
::
string
&
msg
)
:
_msg
(
msg
)
{}
const
char
*
what
()
const
SPDLOG_NOEXCEPT
override
{
return
_msg
.
c_str
();
}
private:
std
::
string
_msg
;
std
::
string
_msg
;
};
...
...
include/spdlog/details/async_log_helper.h
View file @
d163b8c4
...
...
@@ -52,93 +52,93 @@ namespace details
class
async_log_helper
{
// Async msg to move to/from the queue
// Movable only. should never be copied
struct
async_msg
{
std
::
string
logger_name
;
level
::
level_enum
level
;
log_clock
::
time_point
time
;
std
::
string
txt
;
async_msg
()
=
default
;
~
async_msg
()
=
default
;
async_msg
(
const
async_msg
&
)
=
delete
;
async_msg
&
operator
=
(
async_msg
&
other
)
=
delete
;
async_msg
(
const
details
::
log_msg
&
m
)
:
logger_name
(
m
.
logger_name
),
level
(
m
.
level
),
time
(
m
.
time
),
txt
(
m
.
raw
.
data
(),
m
.
raw
.
size
())
{}
async_msg
(
async_msg
&&
other
)
:
logger_name
(
std
::
move
(
other
.
logger_name
)),
level
(
std
::
move
(
other
.
level
)),
time
(
std
::
move
(
other
.
time
)),
txt
(
std
::
move
(
other
.
txt
))
{}
async_msg
&
operator
=
(
async_msg
&&
other
)
{
logger_name
=
std
::
move
(
other
.
logger_name
);
level
=
other
.
level
;
time
=
std
::
move
(
other
.
time
);
txt
=
std
::
move
(
other
.
txt
);
return
*
this
;
}
void
fill_log_msg
(
log_msg
&
msg
)
{
msg
.
clear
();
msg
.
logger_name
=
logger_name
;
msg
.
level
=
level
;
msg
.
time
=
time
;
msg
.
raw
<<
txt
;
}
};
// Async msg to move to/from the queue
// Movable only. should never be copied
struct
async_msg
{
std
::
string
logger_name
;
level
::
level_enum
level
;
log_clock
::
time_point
time
;
std
::
string
txt
;
async_msg
()
=
default
;
~
async_msg
()
=
default
;
async_msg
(
const
async_msg
&
)
=
delete
;
async_msg
&
operator
=
(
async_msg
&
other
)
=
delete
;
async_msg
(
const
details
::
log_msg
&
m
)
:
logger_name
(
m
.
logger_name
),
level
(
m
.
level
),
time
(
m
.
time
),
txt
(
m
.
raw
.
data
(),
m
.
raw
.
size
())
{}
async_msg
(
async_msg
&&
other
)
:
logger_name
(
std
::
move
(
other
.
logger_name
)),
level
(
std
::
move
(
other
.
level
)),
time
(
std
::
move
(
other
.
time
)),
txt
(
std
::
move
(
other
.
txt
))
{}
async_msg
&
operator
=
(
async_msg
&&
other
)
{
logger_name
=
std
::
move
(
other
.
logger_name
);
level
=
other
.
level
;
time
=
std
::
move
(
other
.
time
);
txt
=
std
::
move
(
other
.
txt
);
return
*
this
;
}
void
fill_log_msg
(
log_msg
&
msg
)
{
msg
.
clear
();
msg
.
logger_name
=
logger_name
;
msg
.
level
=
level
;
msg
.
time
=
time
;
msg
.
raw
<<
txt
;
}
};
public:
using
item_type
=
async_msg
;
using
q_type
=
details
::
mpmc_bounded_queue
<
item_type
>
;
using
item_type
=
async_msg
;
using
q_type
=
details
::
mpmc_bounded_queue
<
item_type
>
;
using
clock
=
std
::
chrono
::
steady_clock
;
using
clock
=
std
::
chrono
::
steady_clock
;
async_log_helper
(
formatter_ptr
formatter
,
const
std
::
vector
<
sink_ptr
>&
sinks
,
size_t
queue_size
);
void
log
(
const
details
::
log_msg
&
msg
);
async_log_helper
(
formatter_ptr
formatter
,
const
std
::
vector
<
sink_ptr
>&
sinks
,
size_t
queue_size
);
void
log
(
const
details
::
log_msg
&
msg
);
//Stop logging and join the back thread
~
async_log_helper
();
void
set_formatter
(
formatter_ptr
);
//Stop logging and join the back thread
~
async_log_helper
();
void
set_formatter
(
formatter_ptr
);
private:
formatter_ptr
_formatter
;
std
::
vector
<
std
::
shared_ptr
<
sinks
::
sink
>>
_sinks
;
q_type
_q
;
std
::
thread
_worker_thread
;
formatter_ptr
_formatter
;
std
::
vector
<
std
::
shared_ptr
<
sinks
::
sink
>>
_sinks
;
q_type
_q
;
std
::
thread
_worker_thread
;
// last exception thrown from the worker thread
std
::
shared_ptr
<
spdlog_ex
>
_last_workerthread_ex
;
// last exception thrown from the worker thread
std
::
shared_ptr
<
spdlog_ex
>
_last_workerthread_ex
;
// throw last worker thread exception or if worker thread is not active
void
throw_if_bad_worker
();
// throw last worker thread exception or if worker thread is not active
void
throw_if_bad_worker
();
// worker thread main loop
void
worker_loop
();
// worker thread main loop
void
worker_loop
();
//pop next message from the queue and process it
//return true if a message was available (queue was not empty), will set the last_pop to the pop time
bool
process_next_msg
(
clock
::
time_point
&
last_pop
);
//pop next message from the queue and process it
//return true if a message was available (queue was not empty), will set the last_pop to the pop time
bool
process_next_msg
(
clock
::
time_point
&
last_pop
);
// guess how much to sleep if queue is empty/full using last succesful op time as hint
static
void
sleep_or_yield
(
const
clock
::
time_point
&
last_op_time
);
// guess how much to sleep if queue is empty/full using last succesful op time as hint
static
void
sleep_or_yield
(
const
clock
::
time_point
&
last_op_time
);
};
}
...
...
@@ -148,10 +148,10 @@ private:
// async_sink class implementation
///////////////////////////////////////////////////////////////////////////////
inline
spdlog
::
details
::
async_log_helper
::
async_log_helper
(
formatter_ptr
formatter
,
const
std
::
vector
<
sink_ptr
>&
sinks
,
size_t
queue_size
)
:
_formatter
(
formatter
),
_sinks
(
sinks
),
_q
(
queue_size
),
_worker_thread
(
&
async_log_helper
::
worker_loop
,
this
)
_formatter
(
formatter
),
_sinks
(
sinks
),
_q
(
queue_size
),
_worker_thread
(
&
async_log_helper
::
worker_loop
,
this
)
{}
// Send to the worker thread termination message(level=off)
...
...
@@ -159,48 +159,48 @@ inline spdlog::details::async_log_helper::async_log_helper(formatter_ptr formatt
inline
spdlog
::
details
::
async_log_helper
::~
async_log_helper
()
{
try
{
log
(
log_msg
(
level
::
off
));
_worker_thread
.
join
();
}
catch
(...)
//Dont crash if thread not joinable
{}
try
{
log
(
log_msg
(
level
::
off
));
_worker_thread
.
join
();
}
catch
(...)
//Dont crash if thread not joinable
{}
}
//Try to push and block until succeeded
inline
void
spdlog
::
details
::
async_log_helper
::
log
(
const
details
::
log_msg
&
msg
)
{
throw_if_bad_worker
();
async_msg
new_msg
(
msg
);
if
(
!
_q
.
enqueue
(
std
::
move
(
new_msg
)))
{
auto
last_op_time
=
clock
::
now
();
do
{
sleep_or_yield
(
last_op_time
);
}
while
(
!
_q
.
enqueue
(
std
::
move
(
new_msg
)));
}
throw_if_bad_worker
();
async_msg
new_msg
(
msg
);
if
(
!
_q
.
enqueue
(
std
::
move
(
new_msg
)))
{
auto
last_op_time
=
clock
::
now
();
do
{
sleep_or_yield
(
last_op_time
);
}
while
(
!
_q
.
enqueue
(
std
::
move
(
new_msg
)));
}
}
inline
void
spdlog
::
details
::
async_log_helper
::
worker_loop
()
{
try
try
{
clock
::
time_point
last_pop
=
clock
::
now
();
while
(
process_next_msg
(
last_pop
));
}
clock
::
time_point
last_pop
=
clock
::
now
();
while
(
process_next_msg
(
last_pop
));
}
catch
(
const
std
::
exception
&
ex
)
{
_last_workerthread_ex
=
std
::
make_shared
<
spdlog_ex
>
(
std
::
string
(
"async_logger worker thread exception: "
)
+
ex
.
what
());
}
catch
(...)
{
_last_workerthread_ex
=
std
::
make_shared
<
spdlog_ex
>
(
"async_logger worker thread exception"
);
}
{
_last_workerthread_ex
=
std
::
make_shared
<
spdlog_ex
>
(
std
::
string
(
"async_logger worker thread exception: "
)
+
ex
.
what
());
}
catch
(...)
{
_last_workerthread_ex
=
std
::
make_shared
<
spdlog_ex
>
(
"async_logger worker thread exception"
);
}
}
// Process next message in the queue
...
...
@@ -208,66 +208,66 @@ inline void spdlog::details::async_log_helper::worker_loop()
inline
bool
spdlog
::
details
::
async_log_helper
::
process_next_msg
(
clock
::
time_point
&
last_pop
)
{
async_msg
incoming_async_msg
;
log_msg
incoming_log_msg
;
async_msg
incoming_async_msg
;
log_msg
incoming_log_msg
;
if
(
_q
.
dequeue
(
incoming_async_msg
))
{
if
(
_q
.
dequeue
(
incoming_async_msg
))
{
last_pop
=
clock
::
now
();
if
(
incoming_async_msg
.
level
==
level
::
off
)
if
(
incoming_async_msg
.
level
==
level
::
off
)
return
false
;
incoming_async_msg
.
fill_log_msg
(
incoming_log_msg
);
_formatter
->
format
(
incoming_log_msg
);
for
(
auto
&
s
:
_sinks
)
s
->
log
(
incoming_log_msg
);
}
else
//empty queue
{
sleep_or_yield
(
last_pop
);
}
return
true
;
incoming_async_msg
.
fill_log_msg
(
incoming_log_msg
);
_formatter
->
format
(
incoming_log_msg
);
for
(
auto
&
s
:
_sinks
)
s
->
log
(
incoming_log_msg
);
}
else
//empty queue
{
sleep_or_yield
(
last_pop
);
}
return
true
;
}
inline
void
spdlog
::
details
::
async_log_helper
::
set_formatter
(
formatter_ptr
msg_formatter
)
{
_formatter
=
msg_formatter
;
_formatter
=
msg_formatter
;
}
// Sleep,yield or return immediatly using the time passed since last message as a hint
inline
void
spdlog
::
details
::
async_log_helper
::
sleep_or_yield
(
const
clock
::
time_point
&
last_op_time
)
{
using
std
::
chrono
::
milliseconds
;
using
namespace
std
::
this_thread
;
using
std
::
chrono
::
milliseconds
;
using
namespace
std
::
this_thread
;
auto
time_since_op
=
clock
::
now
()
-
last_op_time
;
auto
time_since_op
=
clock
::
now
()
-
last_op_time
;
//spin upto 1 ms
if
(
time_since_op
<=
milliseconds
(
1
))
return
;
//spin upto 1 ms
if
(
time_since_op
<=
milliseconds
(
1
))
return
;
// yield upto 10ms
if
(
time_since_op
<=
milliseconds
(
10
))
return
yield
();
// yield upto 10ms
if
(
time_since_op
<=
milliseconds
(
10
))
return
yield
();
// sleep for half of duration since last op
if
(
time_since_op
<=
milliseconds
(
100
))
return
sleep_for
(
time_since_op
/
2
);
// sleep for half of duration since last op
if
(
time_since_op
<=
milliseconds
(
100
))
return
sleep_for
(
time_since_op
/
2
);
return
sleep_for
(
milliseconds
(
100
));
return
sleep_for
(
milliseconds
(
100
));
}
//throw if the worker thread threw an exception or not active
inline
void
spdlog
::
details
::
async_log_helper
::
throw_if_bad_worker
()
{
if
(
_last_workerthread_ex
)
{
auto
ex
=
std
::
move
(
_last_workerthread_ex
);
throw
*
ex
;
}
if
(
_last_workerthread_ex
)
{
auto
ex
=
std
::
move
(
_last_workerthread_ex
);
throw
*
ex
;
}
}
...
...
include/spdlog/details/async_logger_impl.h
View file @
d163b8c4
...
...
@@ -35,38 +35,38 @@
template
<
class
It
>
inline
spdlog
::
async_logger
::
async_logger
(
const
std
::
string
&
logger_name
,
const
It
&
begin
,
const
It
&
end
,
size_t
queue_size
)
:
logger
(
logger_name
,
begin
,
end
),
_async_log_helper
(
new
details
::
async_log_helper
(
_formatter
,
_sinks
,
queue_size
))
logger
(
logger_name
,
begin
,
end
),
_async_log_helper
(
new
details
::
async_log_helper
(
_formatter
,
_sinks
,
queue_size
))
{
}
inline
spdlog
::
async_logger
::
async_logger
(
const
std
::
string
&
logger_name
,
sinks_init_list
sinks
,
size_t
queue_size
)
:
async_logger
(
logger_name
,
sinks
.
begin
(),
sinks
.
end
(),
queue_size
)
{}
async_logger
(
logger_name
,
sinks
.
begin
(),
sinks
.
end
(),
queue_size
)
{}
inline
spdlog
::
async_logger
::
async_logger
(
const
std
::
string
&
logger_name
,
sink_ptr
single_sink
,
size_t
queue_size
)
:
async_logger
(
logger_name
,
{
single_sink
},
queue_size
)
{}
async_logger
(
logger_name
,
{
single_sink
},
queue_size
)
{}
inline
void
spdlog
::
async_logger
::
_set_formatter
(
spdlog
::
formatter_ptr
msg_formatter
)
{
_formatter
=
msg_formatter
;
_async_log_helper
->
set_formatter
(
_formatter
);
_formatter
=
msg_formatter
;
_async_log_helper
->
set_formatter
(
_formatter
);
}
inline
void
spdlog
::
async_logger
::
_set_pattern
(
const
std
::
string
&
pattern
)
{
_formatter
=
std
::
make_shared
<
pattern_formatter
>
(
pattern
);
_async_log_helper
->
set_formatter
(
_formatter
);
_formatter
=
std
::
make_shared
<
pattern_formatter
>
(
pattern
);
_async_log_helper
->
set_formatter
(
_formatter
);
}
inline
void
spdlog
::
async_logger
::
_stop
()
{
set_level
(
level
::
off
);
set_level
(
level
::
off
);
}
inline
void
spdlog
::
async_logger
::
_log_msg
(
details
::
log_msg
&
msg
)
{
_async_log_helper
->
log
(
msg
);
_async_log_helper
->
log
(
msg
);
}
include/spdlog/details/file_helper.h
View file @
d163b8c4
...
...
@@ -45,93 +45,93 @@ namespace details
class
file_helper
{
public:
const
int
open_tries
=
5
;
const
int
open_interval
=
10
;
const
int
open_tries
=
5
;
const
int
open_interval
=
10
;
explicit
file_helper
(
bool
auto_flush
)
:
_fd
(
nullptr
),
_auto_flush
(
auto_flush
)
{}
explicit
file_helper
(
bool
auto_flush
)
:
_fd
(
nullptr
),
_auto_flush
(
auto_flush
)
{}
file_helper
(
const
file_helper
&
)
=
delete
;
file_helper
&
operator
=
(
const
file_helper
&
)
=
delete
;
file_helper
(
const
file_helper
&
)
=
delete
;
file_helper
&
operator
=
(
const
file_helper
&
)
=
delete
;
~
file_helper
()
{
close
();
}
~
file_helper
()
{
close
();
}
void
open
(
const
std
::
string
&
fname
,
bool
truncate
=
false
)
{
void
open
(
const
std
::
string
&
fname
,
bool
truncate
=
false
)
{
close
();
close
();
const
char
*
mode
=
truncate
?
"wb"
:
"ab"
;
_filename
=
fname
;
for
(
int
tries
=
0
;
tries
<
open_tries
;
++
tries
)
{
if
(
!
os
::
fopen_s
(
&
_fd
,
fname
,
mode
))
return
;
std
::
this_thread
::
sleep_for
(
std
::
chrono
::
milliseconds
(
open_interval
));
}
throw
spdlog_ex
(
"Failed opening file "
+
fname
+
" for writing"
);
}
void
reopen
(
bool
truncate
)
{
if
(
_filename
.
empty
())
throw
spdlog_ex
(
"Failed re opening file - was not opened before"
);
open
(
_filename
,
truncate
);
}
void
close
()
{
if
(
_fd
)
{
std
::
fclose
(
_fd
);
_fd
=
nullptr
;
}
}
void
write
(
const
log_msg
&
msg
)
{
size_t
size
=
msg
.
formatted
.
size
();
auto
data
=
msg
.
formatted
.
data
();
if
(
std
::
fwrite
(
data
,
1
,
size
,
_fd
)
!=
size
)
throw
spdlog_ex
(
"Failed writing to file "
+
_filename
);
if
(
_auto_flush
)
std
::
fflush
(
_fd
);
}
const
std
::
string
&
filename
()
const
{
return
_filename
;
}
static
bool
file_exists
(
const
std
::
string
&
name
)
{
FILE
*
file
;
if
(
!
os
::
fopen_s
(
&
file
,
name
.
c_str
(),
"r"
))
{
fclose
(
file
);
return
true
;
}
else
{
return
false
;
}
}
_filename
=
fname
;
for
(
int
tries
=
0
;
tries
<
open_tries
;
++
tries
)
{
if
(
!
os
::
fopen_s
(
&
_fd
,
fname
,
mode
))
return
;
std
::
this_thread
::
sleep_for
(
std
::
chrono
::
milliseconds
(
open_interval
));
}
throw
spdlog_ex
(
"Failed opening file "
+
fname
+
" for writing"
);
}
void
reopen
(
bool
truncate
)
{
if
(
_filename
.
empty
())
throw
spdlog_ex
(
"Failed re opening file - was not opened before"
);
open
(
_filename
,
truncate
);
}
void
close
()
{
if
(
_fd
)
{
std
::
fclose
(
_fd
);
_fd
=
nullptr
;
}
}
void
write
(
const
log_msg
&
msg
)
{
size_t
size
=
msg
.
formatted
.
size
();
auto
data
=
msg
.
formatted
.
data
();
if
(
std
::
fwrite
(
data
,
1
,
size
,
_fd
)
!=
size
)
throw
spdlog_ex
(
"Failed writing to file "
+
_filename
);
if
(
_auto_flush
)
std
::
fflush
(
_fd
);
}
const
std
::
string
&
filename
()
const
{
return
_filename
;
}
static
bool
file_exists
(
const
std
::
string
&
name
)
{
FILE
*
file
;
if
(
!
os
::
fopen_s
(
&
file
,
name
.
c_str
(),
"r"
))
{
fclose
(
file
);
return
true
;
}
else
{
return
false
;
}
}
private:
FILE
*
_fd
;
std
::
string
_filename
;
bool
_auto_flush
;
FILE
*
_fd
;
std
::
string
_filename
;
bool
_auto_flush
;
};
...
...
include/spdlog/details/format.h
View file @
d163b8c4
This diff is collapsed.
Click to expand it.
include/spdlog/details/line_logger.h
View file @
d163b8c4
...
...
@@ -38,73 +38,73 @@ namespace details
class
line_logger
{
public:
line_logger
(
logger
*
callback_logger
,
level
::
level_enum
msg_level
,
bool
enabled
)
:
_callback_logger
(
callback_logger
),
_log_msg
(
msg_level
),
_enabled
(
enabled
)
{}
// No copy intended. Only move
line_logger
(
const
line_logger
&
other
)
=
delete
;
line_logger
&
operator
=
(
const
line_logger
&
)
=
delete
;
line_logger
&
operator
=
(
line_logger
&&
)
=
delete
;
line_logger
(
line_logger
&&
other
)
:
_callback_logger
(
other
.
_callback_logger
),
_log_msg
(
std
::
move
(
other
.
_log_msg
)),
_enabled
(
other
.
_enabled
)
{
other
.
disable
();
}
//Log the log message using the callback logger
~
line_logger
()
{
if
(
_enabled
)
{
_log_msg
.
logger_name
=
_callback_logger
->
name
();
_log_msg
.
time
=
log_clock
::
now
();
_callback_logger
->
_log_msg
(
_log_msg
);
}
}
template
<
typename
...
Args
>
void
write
(
const
char
*
fmt
,
const
Args
&
...
args
)
{
if
(
!
_enabled
)
return
;
try
{
_log_msg
.
raw
.
write
(
fmt
,
args
...);
}
catch
(
const
fmt
::
FormatError
&
e
)
{
throw
spdlog_ex
(
fmt
::
format
(
"formatting error while processing format string '{}': {}"
,
fmt
,
e
.
what
()));
}
}
template
<
typename
T
>
line_logger
&
operator
<<
(
const
T
&
what
)
{
if
(
_enabled
)
_log_msg
.
raw
<<
what
;
return
*
this
;
}
void
disable
()
{
_enabled
=
false
;
}
line_logger
(
logger
*
callback_logger
,
level
::
level_enum
msg_level
,
bool
enabled
)
:
_callback_logger
(
callback_logger
),
_log_msg
(
msg_level
),
_enabled
(
enabled
)
{}
// No copy intended. Only move
line_logger
(
const
line_logger
&
other
)
=
delete
;
line_logger
&
operator
=
(
const
line_logger
&
)
=
delete
;
line_logger
&
operator
=
(
line_logger
&&
)
=
delete
;
line_logger
(
line_logger
&&
other
)
:
_callback_logger
(
other
.
_callback_logger
),
_log_msg
(
std
::
move
(
other
.
_log_msg
)),
_enabled
(
other
.
_enabled
)
{
other
.
disable
();
}
//Log the log message using the callback logger
~
line_logger
()
{
if
(
_enabled
)
{
_log_msg
.
logger_name
=
_callback_logger
->
name
();
_log_msg
.
time
=
log_clock
::
now
();
_callback_logger
->
_log_msg
(
_log_msg
);
}
}
template
<
typename
...
Args
>
void
write
(
const
char
*
fmt
,
const
Args
&
...
args
)
{
if
(
!
_enabled
)
return
;
try
{
_log_msg
.
raw
.
write
(
fmt
,
args
...);
}
catch
(
const
fmt
::
FormatError
&
e
)
{
throw
spdlog_ex
(
fmt
::
format
(
"formatting error while processing format string '{}': {}"
,
fmt
,
e
.
what
()));
}
}
template
<
typename
T
>
line_logger
&
operator
<<
(
const
T
&
what
)
{
if
(
_enabled
)
_log_msg
.
raw
<<
what
;
return
*
this
;
}
void
disable
()
{
_enabled
=
false
;
}
private:
logger
*
_callback_logger
;
log_msg
_log_msg
;
bool
_enabled
;
logger
*
_callback_logger
;
log_msg
_log_msg
;
bool
_enabled
;
};
}
//Namespace details
}
// Namespace spdlog
include/spdlog/details/log_msg.h
View file @
d163b8c4
...
...
@@ -33,63 +33,62 @@ namespace details
{
struct
log_msg
{
log_msg
()
=
default
;
log_msg
(
level
::
level_enum
l
)
:
logger_name
(),
level
(
l
),
time
(),
raw
(),
formatted
()
{}
log_msg
()
=
default
;
log_msg
(
level
::
level_enum
l
)
:
logger_name
(),
level
(
l
),
time
(),
raw
(),
formatted
()
{}
log_msg
(
const
log_msg
&
other
)
:
logger_name
(
other
.
logger_name
),
level
(
other
.
level
),
time
(
other
.
time
)
{
if
(
other
.
raw
.
size
())
raw
<<
fmt
::
BasicStringRef
<
char
>
(
other
.
raw
.
data
(),
other
.
raw
.
size
());
if
(
other
.
formatted
.
size
())
formatted
<<
fmt
::
BasicStringRef
<
char
>
(
other
.
formatted
.
data
(),
other
.
formatted
.
size
());
log_msg
(
const
log_msg
&
other
)
:
logger_name
(
other
.
logger_name
),
level
(
other
.
level
),
time
(
other
.
time
)
{
if
(
other
.
raw
.
size
())
raw
<<
fmt
::
BasicStringRef
<
char
>
(
other
.
raw
.
data
(),
other
.
raw
.
size
());
if
(
other
.
formatted
.
size
())
formatted
<<
fmt
::
BasicStringRef
<
char
>
(
other
.
formatted
.
data
(),
other
.
formatted
.
size
());
}
}
log_msg
(
log_msg
&&
other
)
:
logger_name
(
std
::
move
(
other
.
logger_name
)),
level
(
other
.
level
),
time
(
std
::
move
(
other
.
time
)),
raw
(
std
::
move
(
other
.
raw
)),
formatted
(
std
::
move
(
other
.
formatted
))
{
other
.
clear
();
}
log_msg
(
log_msg
&&
other
)
:
logger_name
(
std
::
move
(
other
.
logger_name
)),
level
(
other
.
level
),
time
(
std
::
move
(
other
.
time
)),
raw
(
std
::
move
(
other
.
raw
)),
formatted
(
std
::
move
(
other
.
formatted
))
{
other
.
clear
();
}
log_msg
&
operator
=
(
log_msg
&&
other
)
{
if
(
this
==
&
other
)
return
*
this
;
log_msg
&
operator
=
(
log_msg
&&
other
)
{
if
(
this
==
&
other
)
return
*
this
;
logger_name
=
std
::
move
(
other
.
logger_name
);
level
=
other
.
level
;
time
=
std
::
move
(
other
.
time
);
raw
=
std
::
move
(
other
.
raw
);
formatted
=
std
::
move
(
other
.
formatted
);
other
.
clear
();
return
*
this
;
}
logger_name
=
std
::
move
(
other
.
logger_name
);
level
=
other
.
level
;
time
=
std
::
move
(
other
.
time
);
raw
=
std
::
move
(
other
.
raw
);
formatted
=
std
::
move
(
other
.
formatted
);
other
.
clear
();
return
*
this
;
}
void
clear
()
{
level
=
level
::
off
;
raw
.
clear
();
formatted
.
clear
();
}
void
clear
()
{
level
=
level
::
off
;
raw
.
clear
();
formatted
.
clear
();
}
std
::
string
logger_name
;
level
::
level_enum
level
;
log_clock
::
time_point
time
;
fmt
::
MemoryWriter
raw
;
fmt
::
MemoryWriter
formatted
;
std
::
string
logger_name
;
level
::
level_enum
level
;
log_clock
::
time_point
time
;
fmt
::
MemoryWriter
raw
;
fmt
::
MemoryWriter
formatted
;
};
}
}
include/spdlog/details/logger_impl.h
View file @
d163b8c4
...
...
@@ -34,23 +34,23 @@
// all other ctors will call this one
template
<
class
It
>
inline
spdlog
::
logger
::
logger
(
const
std
::
string
&
logger_name
,
const
It
&
begin
,
const
It
&
end
)
:
_name
(
logger_name
),
_sinks
(
begin
,
end
),
_formatter
(
std
::
make_shared
<
pattern_formatter
>
(
"%+"
))
_name
(
logger_name
),
_sinks
(
begin
,
end
),
_formatter
(
std
::
make_shared
<
pattern_formatter
>
(
"%+"
))
{
// no support under vs2013 for member initialization for std::atomic
_level
=
level
::
info
;
// no support under vs2013 for member initialization for std::atomic
_level
=
level
::
info
;
}
// ctor with sinks as init list
inline
spdlog
::
logger
::
logger
(
const
std
::
string
&
logger_name
,
sinks_init_list
sinks_list
)
:
logger
(
logger_name
,
sinks_list
.
begin
(),
sinks_list
.
end
())
{}
logger
(
logger_name
,
sinks_list
.
begin
(),
sinks_list
.
end
())
{}
// ctor with single sink
inline
spdlog
::
logger
::
logger
(
const
std
::
string
&
logger_name
,
spdlog
::
sink_ptr
single_sink
)
:
logger
(
logger_name
,
{
single_sink
})
{}
logger
(
logger_name
,
{
single_sink
})
{}
inline
spdlog
::
logger
::~
logger
()
=
default
;
...
...
@@ -58,12 +58,12 @@ inline spdlog::logger::~logger() = default;
inline
void
spdlog
::
logger
::
set_formatter
(
spdlog
::
formatter_ptr
msg_formatter
)
{
_set_formatter
(
msg_formatter
);
_set_formatter
(
msg_formatter
);
}
inline
void
spdlog
::
logger
::
set_pattern
(
const
std
::
string
&
pattern
)
{
_set_pattern
(
pattern
);
_set_pattern
(
pattern
);
}
//
...
...
@@ -74,15 +74,15 @@ inline void spdlog::logger::set_pattern(const std::string& pattern)
template
<
typename
...
Args
>
inline
spdlog
::
details
::
line_logger
spdlog
::
logger
::
_log_if_enabled
(
level
::
level_enum
lvl
,
const
char
*
fmt
,
const
Args
&
...
args
)
{
bool
msg_enabled
=
should_log
(
lvl
);
details
::
line_logger
l
(
this
,
lvl
,
msg_enabled
);
l
.
write
(
fmt
,
args
...);
return
l
;
bool
msg_enabled
=
should_log
(
lvl
);
details
::
line_logger
l
(
this
,
lvl
,
msg_enabled
);
l
.
write
(
fmt
,
args
...);
return
l
;
}
inline
spdlog
::
details
::
line_logger
spdlog
::
logger
::
_log_if_enabled
(
level
::
level_enum
lvl
)
{
return
details
::
line_logger
(
this
,
lvl
,
should_log
(
lvl
));
return
details
::
line_logger
(
this
,
lvl
,
should_log
(
lvl
));
}
...
...
@@ -92,55 +92,55 @@ inline spdlog::details::line_logger spdlog::logger::_log_if_enabled(level::level
template
<
typename
...
Args
>
inline
spdlog
::
details
::
line_logger
spdlog
::
logger
::
trace
(
const
char
*
fmt
,
const
Args
&
...
args
)
{
return
_log_if_enabled
(
level
::
trace
,
fmt
,
args
...);
return
_log_if_enabled
(
level
::
trace
,
fmt
,
args
...);
}
template
<
typename
...
Args
>
inline
spdlog
::
details
::
line_logger
spdlog
::
logger
::
debug
(
const
char
*
fmt
,
const
Args
&
...
args
)
{
return
_log_if_enabled
(
level
::
debug
,
fmt
,
args
...);
return
_log_if_enabled
(
level
::
debug
,
fmt
,
args
...);
}
template
<
typename
...
Args
>
inline
spdlog
::
details
::
line_logger
spdlog
::
logger
::
info
(
const
char
*
fmt
,
const
Args
&
...
args
)
{
return
_log_if_enabled
(
level
::
info
,
fmt
,
args
...);
return
_log_if_enabled
(
level
::
info
,
fmt
,
args
...);
}
template
<
typename
...
Args
>
inline
spdlog
::
details
::
line_logger
spdlog
::
logger
::
notice
(
const
char
*
fmt
,
const
Args
&
...
args
)
{
return
_log_if_enabled
(
level
::
notice
,
fmt
,
args
...);
return
_log_if_enabled
(
level
::
notice
,
fmt
,
args
...);
}
template
<
typename
...
Args
>
inline
spdlog
::
details
::
line_logger
spdlog
::
logger
::
warn
(
const
char
*
fmt
,
const
Args
&
...
args
)
{
return
_log_if_enabled
(
level
::
warn
,
fmt
,
args
...);
return
_log_if_enabled
(
level
::
warn
,
fmt
,
args
...);
}
template
<
typename
...
Args
>
inline
spdlog
::
details
::
line_logger
spdlog
::
logger
::
error
(
const
char
*
fmt
,
const
Args
&
...
args
)
{
return
_log_if_enabled
(
level
::
err
,
fmt
,
args
...);
return
_log_if_enabled
(
level
::
err
,
fmt
,
args
...);
}
template
<
typename
...
Args
>
inline
spdlog
::
details
::
line_logger
spdlog
::
logger
::
critical
(
const
char
*
fmt
,
const
Args
&
...
args
)
{
return
_log_if_enabled
(
level
::
critical
,
fmt
,
args
...);
return
_log_if_enabled
(
level
::
critical
,
fmt
,
args
...);
}
template
<
typename
...
Args
>
inline
spdlog
::
details
::
line_logger
spdlog
::
logger
::
alert
(
const
char
*
fmt
,
const
Args
&
...
args
)
{
return
_log_if_enabled
(
level
::
alert
,
fmt
,
args
...);
return
_log_if_enabled
(
level
::
alert
,
fmt
,
args
...);
}
template
<
typename
...
Args
>
inline
spdlog
::
details
::
line_logger
spdlog
::
logger
::
emerg
(
const
char
*
fmt
,
const
Args
&
...
args
)
{
return
_log_if_enabled
(
level
::
emerg
,
fmt
,
args
...);
return
_log_if_enabled
(
level
::
emerg
,
fmt
,
args
...);
}
...
...
@@ -152,48 +152,48 @@ inline spdlog::details::line_logger spdlog::logger::emerg(const char* fmt, const
inline
spdlog
::
details
::
line_logger
spdlog
::
logger
::
trace
()
{
return
_log_if_enabled
(
level
::
trace
);
return
_log_if_enabled
(
level
::
trace
);
}
inline
spdlog
::
details
::
line_logger
spdlog
::
logger
::
debug
()
{
return
_log_if_enabled
(
level
::
debug
);
return
_log_if_enabled
(
level
::
debug
);
}
inline
spdlog
::
details
::
line_logger
spdlog
::
logger
::
info
()
{
return
_log_if_enabled
(
level
::
info
);
return
_log_if_enabled
(
level
::
info
);
}
inline
spdlog
::
details
::
line_logger
spdlog
::
logger
::
notice
()
{
return
_log_if_enabled
(
level
::
notice
);
return
_log_if_enabled
(
level
::
notice
);
}
inline
spdlog
::
details
::
line_logger
spdlog
::
logger
::
warn
()
{
return
_log_if_enabled
(
level
::
warn
);
return
_log_if_enabled
(
level
::
warn
);
}
inline
spdlog
::
details
::
line_logger
spdlog
::
logger
::
error
()
{
return
_log_if_enabled
(
level
::
err
);
return
_log_if_enabled
(
level
::
err
);
}
inline
spdlog
::
details
::
line_logger
spdlog
::
logger
::
critical
()
{
return
_log_if_enabled
(
level
::
critical
);
return
_log_if_enabled
(
level
::
critical
);
}
inline
spdlog
::
details
::
line_logger
spdlog
::
logger
::
alert
()
{
return
_log_if_enabled
(
level
::
alert
);
return
_log_if_enabled
(
level
::
alert
);
}
inline
spdlog
::
details
::
line_logger
spdlog
::
logger
::
emerg
()
{
return
_log_if_enabled
(
level
::
emerg
);
return
_log_if_enabled
(
level
::
emerg
);
}
...
...
@@ -201,9 +201,9 @@ inline spdlog::details::line_logger spdlog::logger::emerg()
template
<
typename
...
Args
>
inline
spdlog
::
details
::
line_logger
spdlog
::
logger
::
force_log
(
level
::
level_enum
lvl
,
const
char
*
fmt
,
const
Args
&
...
args
)
{
details
::
line_logger
l
(
this
,
lvl
,
true
);
l
.
write
(
fmt
,
args
...);
return
l
;
details
::
line_logger
l
(
this
,
lvl
,
true
);
l
.
write
(
fmt
,
args
...);
return
l
;
}
//
...
...
@@ -211,27 +211,27 @@ inline spdlog::details::line_logger spdlog::logger::force_log(level::level_enum
//
inline
const
std
::
string
&
spdlog
::
logger
::
name
()
const
{
return
_name
;
return
_name
;
}
inline
void
spdlog
::
logger
::
set_level
(
spdlog
::
level
::
level_enum
log_level
)
{
_level
.
store
(
log_level
);
_level
.
store
(
log_level
);
}
inline
spdlog
::
level
::
level_enum
spdlog
::
logger
::
level
()
const
{
return
static_cast
<
spdlog
::
level
::
level_enum
>
(
_level
.
load
());
return
static_cast
<
spdlog
::
level
::
level_enum
>
(
_level
.
load
());
}
inline
bool
spdlog
::
logger
::
should_log
(
spdlog
::
level
::
level_enum
msg_level
)
const
{
return
msg_level
>=
_level
.
load
();
return
msg_level
>=
_level
.
load
();
}
inline
void
spdlog
::
logger
::
stop
()
{
_stop
();
_stop
();
}
//
...
...
@@ -239,23 +239,23 @@ inline void spdlog::logger::stop()
//
inline
void
spdlog
::
logger
::
_log_msg
(
details
::
log_msg
&
msg
)
{
_formatter
->
format
(
msg
);
for
(
auto
&
sink
:
_sinks
)
sink
->
log
(
msg
);
_formatter
->
format
(
msg
);
for
(
auto
&
sink
:
_sinks
)
sink
->
log
(
msg
);
}
inline
void
spdlog
::
logger
::
_set_pattern
(
const
std
::
string
&
pattern
)
{
_formatter
=
std
::
make_shared
<
pattern_formatter
>
(
pattern
);
_formatter
=
std
::
make_shared
<
pattern_formatter
>
(
pattern
);
}
inline
void
spdlog
::
logger
::
_set_formatter
(
formatter_ptr
msg_formatter
)
{
_formatter
=
msg_formatter
;
_formatter
=
msg_formatter
;
}
inline
void
spdlog
::
logger
::
_stop
()
{
set_level
(
level
::
off
);
set_level
(
level
::
off
);
}
...
...
include/spdlog/details/mpmc_bounded_q.h
View file @
d163b8c4
...
...
@@ -74,101 +74,101 @@ class mpmc_bounded_queue
{
public:
using
item_type
=
T
;
mpmc_bounded_queue
(
size_t
buffer_size
)
:
buffer_
(
new
cell_t
[
buffer_size
]),
buffer_mask_
(
buffer_size
-
1
)
{
//queue size must be power of two
if
(
!
((
buffer_size
>=
2
)
&&
((
buffer_size
&
(
buffer_size
-
1
))
==
0
)))
throw
spdlog_ex
(
"async logger queue size must be power of two"
);
for
(
size_t
i
=
0
;
i
!=
buffer_size
;
i
+=
1
)
buffer_
[
i
].
sequence_
.
store
(
i
,
std
::
memory_order_relaxed
);
enqueue_pos_
.
store
(
0
,
std
::
memory_order_relaxed
);
dequeue_pos_
.
store
(
0
,
std
::
memory_order_relaxed
);
}
~
mpmc_bounded_queue
()
{
delete
[]
buffer_
;
}
bool
enqueue
(
T
&&
data
)
{
cell_t
*
cell
;
size_t
pos
=
enqueue_pos_
.
load
(
std
::
memory_order_relaxed
);
for
(;;)
{
cell
=
&
buffer_
[
pos
&
buffer_mask_
];
size_t
seq
=
cell
->
sequence_
.
load
(
std
::
memory_order_acquire
);
intptr_t
dif
=
(
intptr_t
)
seq
-
(
intptr_t
)
pos
;
if
(
dif
==
0
)
{
if
(
enqueue_pos_
.
compare_exchange_weak
(
pos
,
pos
+
1
,
std
::
memory_order_relaxed
))
break
;
}
else
if
(
dif
<
0
)
{
return
false
;
}
else
{
pos
=
enqueue_pos_
.
load
(
std
::
memory_order_relaxed
);
}
}
cell
->
data_
=
std
::
move
(
data
);
cell
->
sequence_
.
store
(
pos
+
1
,
std
::
memory_order_release
);
return
true
;
}
bool
dequeue
(
T
&
data
)
{
cell_t
*
cell
;
size_t
pos
=
dequeue_pos_
.
load
(
std
::
memory_order_relaxed
);
for
(;;)
{
cell
=
&
buffer_
[
pos
&
buffer_mask_
];
size_t
seq
=
cell
->
sequence_
.
load
(
std
::
memory_order_acquire
);
intptr_t
dif
=
(
intptr_t
)
seq
-
(
intptr_t
)(
pos
+
1
);
if
(
dif
==
0
)
{
if
(
dequeue_pos_
.
compare_exchange_weak
(
pos
,
pos
+
1
,
std
::
memory_order_relaxed
))
break
;
}
else
if
(
dif
<
0
)
return
false
;
else
pos
=
dequeue_pos_
.
load
(
std
::
memory_order_relaxed
);
}
data
=
std
::
move
(
cell
->
data_
);
cell
->
sequence_
.
store
(
pos
+
buffer_mask_
+
1
,
std
::
memory_order_release
);
return
true
;
}
using
item_type
=
T
;
mpmc_bounded_queue
(
size_t
buffer_size
)
:
buffer_
(
new
cell_t
[
buffer_size
]),
buffer_mask_
(
buffer_size
-
1
)
{
//queue size must be power of two
if
(
!
((
buffer_size
>=
2
)
&&
((
buffer_size
&
(
buffer_size
-
1
))
==
0
)))
throw
spdlog_ex
(
"async logger queue size must be power of two"
);
for
(
size_t
i
=
0
;
i
!=
buffer_size
;
i
+=
1
)
buffer_
[
i
].
sequence_
.
store
(
i
,
std
::
memory_order_relaxed
);
enqueue_pos_
.
store
(
0
,
std
::
memory_order_relaxed
);
dequeue_pos_
.
store
(
0
,
std
::
memory_order_relaxed
);
}
~
mpmc_bounded_queue
()
{
delete
[]
buffer_
;
}
bool
enqueue
(
T
&&
data
)
{
cell_t
*
cell
;
size_t
pos
=
enqueue_pos_
.
load
(
std
::
memory_order_relaxed
);
for
(;;)
{
cell
=
&
buffer_
[
pos
&
buffer_mask_
];
size_t
seq
=
cell
->
sequence_
.
load
(
std
::
memory_order_acquire
);
intptr_t
dif
=
(
intptr_t
)
seq
-
(
intptr_t
)
pos
;
if
(
dif
==
0
)
{
if
(
enqueue_pos_
.
compare_exchange_weak
(
pos
,
pos
+
1
,
std
::
memory_order_relaxed
))
break
;
}
else
if
(
dif
<
0
)
{
return
false
;
}
else
{
pos
=
enqueue_pos_
.
load
(
std
::
memory_order_relaxed
);
}
}
cell
->
data_
=
std
::
move
(
data
);
cell
->
sequence_
.
store
(
pos
+
1
,
std
::
memory_order_release
);
return
true
;
}
bool
dequeue
(
T
&
data
)
{
cell_t
*
cell
;
size_t
pos
=
dequeue_pos_
.
load
(
std
::
memory_order_relaxed
);
for
(;;)
{
cell
=
&
buffer_
[
pos
&
buffer_mask_
];
size_t
seq
=
cell
->
sequence_
.
load
(
std
::
memory_order_acquire
);
intptr_t
dif
=
(
intptr_t
)
seq
-
(
intptr_t
)(
pos
+
1
);
if
(
dif
==
0
)
{
if
(
dequeue_pos_
.
compare_exchange_weak
(
pos
,
pos
+
1
,
std
::
memory_order_relaxed
))
break
;
}
else
if
(
dif
<
0
)
return
false
;
else
pos
=
dequeue_pos_
.
load
(
std
::
memory_order_relaxed
);
}
data
=
std
::
move
(
cell
->
data_
);
cell
->
sequence_
.
store
(
pos
+
buffer_mask_
+
1
,
std
::
memory_order_release
);
return
true
;
}
private:
struct
cell_t
{
std
::
atomic
<
size_t
>
sequence_
;
T
data_
;
};
static
size_t
const
cacheline_size
=
64
;
typedef
char
cacheline_pad_t
[
cacheline_size
];
cacheline_pad_t
pad0_
;
cell_t
*
const
buffer_
;
size_t
const
buffer_mask_
;
cacheline_pad_t
pad1_
;
std
::
atomic
<
size_t
>
enqueue_pos_
;
cacheline_pad_t
pad2_
;
std
::
atomic
<
size_t
>
dequeue_pos_
;
cacheline_pad_t
pad3_
;
mpmc_bounded_queue
(
mpmc_bounded_queue
const
&
);
void
operator
=
(
mpmc_bounded_queue
const
&
);
struct
cell_t
{
std
::
atomic
<
size_t
>
sequence_
;
T
data_
;
};
static
size_t
const
cacheline_size
=
64
;
typedef
char
cacheline_pad_t
[
cacheline_size
];
cacheline_pad_t
pad0_
;
cell_t
*
const
buffer_
;
size_t
const
buffer_mask_
;
cacheline_pad_t
pad1_
;
std
::
atomic
<
size_t
>
enqueue_pos_
;
cacheline_pad_t
pad2_
;
std
::
atomic
<
size_t
>
dequeue_pos_
;
cacheline_pad_t
pad3_
;
mpmc_bounded_queue
(
mpmc_bounded_queue
const
&
);
void
operator
=
(
mpmc_bounded_queue
const
&
);
};
}
// ns details
...
...
include/spdlog/details/null_mutex.h
View file @
d163b8c4
...
...
@@ -32,12 +32,12 @@ namespace details
{
struct
null_mutex
{
void
lock
()
{}
void
unlock
()
{}
bool
try_lock
()
{
return
true
;
}
void
lock
()
{}
void
unlock
()
{}
bool
try_lock
()
{
return
true
;
}
};
}
}
include/spdlog/details/os.h
View file @
d163b8c4
...
...
@@ -31,7 +31,7 @@
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#endif
#endif
namespace
spdlog
{
...
...
@@ -44,19 +44,19 @@ inline std::tm localtime(const std::time_t &time_tt)
{
#ifdef _WIN32
std
::
tm
tm
;
localtime_s
(
&
tm
,
&
time_tt
);
std
::
tm
tm
;
localtime_s
(
&
tm
,
&
time_tt
);
#else
std
::
tm
tm
;
localtime_r
(
&
time_tt
,
&
tm
);
std
::
tm
tm
;
localtime_r
(
&
time_tt
,
&
tm
);
#endif
return
tm
;
return
tm
;
}
inline
std
::
tm
localtime
()
{
std
::
time_t
now_t
=
time
(
0
);
return
localtime
(
now_t
);
std
::
time_t
now_t
=
time
(
0
);
return
localtime
(
now_t
);
}
...
...
@@ -64,57 +64,57 @@ inline std::tm gmtime(const std::time_t &time_tt)
{
#ifdef _WIN32
std
::
tm
tm
;
gmtime_s
(
&
tm
,
&
time_tt
);
std
::
tm
tm
;
gmtime_s
(
&
tm
,
&
time_tt
);
#else
std
::
tm
tm
;
gmtime_r
(
&
time_tt
,
&
tm
);
std
::
tm
tm
;
gmtime_r
(
&
time_tt
,
&
tm
);
#endif
return
tm
;
return
tm
;
}
inline
std
::
tm
gmtime
()
{
std
::
time_t
now_t
=
time
(
0
);
return
gmtime
(
now_t
);
std
::
time_t
now_t
=
time
(
0
);
return
gmtime
(
now_t
);
}
inline
bool
operator
==
(
const
std
::
tm
&
tm1
,
const
std
::
tm
&
tm2
)
{
return
(
tm1
.
tm_sec
==
tm2
.
tm_sec
&&
tm1
.
tm_min
==
tm2
.
tm_min
&&
tm1
.
tm_hour
==
tm2
.
tm_hour
&&
tm1
.
tm_mday
==
tm2
.
tm_mday
&&
tm1
.
tm_mon
==
tm2
.
tm_mon
&&
tm1
.
tm_year
==
tm2
.
tm_year
&&
tm1
.
tm_isdst
==
tm2
.
tm_isdst
);
return
(
tm1
.
tm_sec
==
tm2
.
tm_sec
&&
tm1
.
tm_min
==
tm2
.
tm_min
&&
tm1
.
tm_hour
==
tm2
.
tm_hour
&&
tm1
.
tm_mday
==
tm2
.
tm_mday
&&
tm1
.
tm_mon
==
tm2
.
tm_mon
&&
tm1
.
tm_year
==
tm2
.
tm_year
&&
tm1
.
tm_isdst
==
tm2
.
tm_isdst
);
}
inline
bool
operator
!=
(
const
std
::
tm
&
tm1
,
const
std
::
tm
&
tm2
)
{
return
!
(
tm1
==
tm2
);
return
!
(
tm1
==
tm2
);
}
#ifdef _WIN32
inline
const
char
*
eol
()
{
return
"
\r\n
"
;
return
"
\r\n
"
;
}
#else
constexpr
inline
const
char
*
eol
()
{
return
"
\n
"
;
return
"
\n
"
;
}
#endif
#ifdef _WIN32
inline
unsigned
short
eol_size
()
{
return
2
;
return
2
;
}
#else
constexpr
inline
unsigned
short
eol_size
()
{
return
1
;
return
1
;
}
#endif
...
...
@@ -122,11 +122,11 @@ constexpr inline unsigned short eol_size()
inline
int
fopen_s
(
FILE
**
fp
,
const
std
::
string
&
filename
,
const
char
*
mode
)
{
#ifdef _WIN32
*
fp
=
_fsopen
((
filename
.
c_str
()),
mode
,
_SH_DENYWR
);
return
*
fp
==
nullptr
;
*
fp
=
_fsopen
((
filename
.
c_str
()),
mode
,
_SH_DENYWR
);
return
*
fp
==
nullptr
;
#else
*
fp
=
fopen
((
filename
.
c_str
()),
mode
);
return
*
fp
==
nullptr
;
*
fp
=
fopen
((
filename
.
c_str
()),
mode
);
return
*
fp
==
nullptr
;
#endif
...
...
@@ -137,14 +137,14 @@ inline int utc_minutes_offset(const std::tm& tm = details::os::localtime())
{
#ifdef _WIN32
(
void
)
tm
;
// avoid unused param warning
DYNAMIC_TIME_ZONE_INFORMATION
tzinfo
;
auto
rv
=
GetDynamicTimeZoneInformation
(
&
tzinfo
);
if
(
!
rv
)
return
-
1
;
return
-
1
*
(
tzinfo
.
Bias
+
tzinfo
.
DaylightBias
);
(
void
)
tm
;
// avoid unused param warning
DYNAMIC_TIME_ZONE_INFORMATION
tzinfo
;
auto
rv
=
GetDynamicTimeZoneInformation
(
&
tzinfo
);
if
(
!
rv
)
return
-
1
;
return
-
1
*
(
tzinfo
.
Bias
+
tzinfo
.
DaylightBias
);
#else
return
static_cast
<
int
>
(
tm
.
tm_gmtoff
/
60
);
return
static_cast
<
int
>
(
tm
.
tm_gmtoff
/
60
);
#endif
}
...
...
include/spdlog/details/pattern_formatter_impl.h
View file @
d163b8c4
This diff is collapsed.
Click to expand it.
include/spdlog/details/registry.h
View file @
d163b8c4
...
...
@@ -44,114 +44,114 @@ namespace details
class
registry
{
public:
std
::
shared_ptr
<
logger
>
get
(
const
std
::
string
&
logger_name
)
{
std
::
lock_guard
<
std
::
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
<
std
::
mutex
>
lock
(
_mutex
);
//If already exists, just return it
auto
found
=
_loggers
.
find
(
logger_name
);
if
(
found
!=
_loggers
.
end
())
return
found
->
second
;
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
);
else
new_logger
=
std
::
make_shared
<
logger
>
(
logger_name
,
sinks_begin
,
sinks_end
);
if
(
_formatter
)
new_logger
->
set_formatter
(
_formatter
);
new_logger
->
set_level
(
_level
);
_loggers
[
logger_name
]
=
new_logger
;
return
new_logger
;
}
void
drop
(
const
std
::
string
&
logger_name
)
{
std
::
lock_guard
<
std
::
mutex
>
lock
(
_mutex
);
_loggers
.
erase
(
logger_name
);
}
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
});
}
void
formatter
(
formatter_ptr
f
)
{
std
::
lock_guard
<
std
::
mutex
>
lock
(
_mutex
);
_formatter
=
f
;
for
(
auto
&
l
:
_loggers
)
l
.
second
->
set_formatter
(
_formatter
);
}
void
set_pattern
(
const
std
::
string
&
pattern
)
{
std
::
lock_guard
<
std
::
mutex
>
lock
(
_mutex
);
_formatter
=
std
::
make_shared
<
pattern_formatter
>
(
pattern
);
for
(
auto
&
l
:
_loggers
)
l
.
second
->
set_formatter
(
_formatter
);
}
void
set_level
(
level
::
level_enum
log_level
)
{
std
::
lock_guard
<
std
::
mutex
>
lock
(
_mutex
);
for
(
auto
&
l
:
_loggers
)
l
.
second
->
set_level
(
log_level
);
}
void
set_async_mode
(
size_t
q_size
)
{
std
::
lock_guard
<
std
::
mutex
>
lock
(
_mutex
);
_async_mode
=
true
;
_async_q_size
=
q_size
;
}
void
set_sync_mode
()
{
std
::
lock_guard
<
std
::
mutex
>
lock
(
_mutex
);
_async_mode
=
false
;
}
void
stop_all
()
{
std
::
lock_guard
<
std
::
mutex
>
lock
(
_mutex
);
_level
=
level
::
off
;
for
(
auto
&
l
:
_loggers
)
l
.
second
->
stop
();
}
static
registry
&
instance
()
{
static
registry
s_instance
;
return
s_instance
;
}
std
::
shared_ptr
<
logger
>
get
(
const
std
::
string
&
logger_name
)
{
std
::
lock_guard
<
std
::
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
<
std
::
mutex
>
lock
(
_mutex
);
//If already exists, just return it
auto
found
=
_loggers
.
find
(
logger_name
);
if
(
found
!=
_loggers
.
end
())
return
found
->
second
;
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
);
else
new_logger
=
std
::
make_shared
<
logger
>
(
logger_name
,
sinks_begin
,
sinks_end
);
if
(
_formatter
)
new_logger
->
set_formatter
(
_formatter
);
new_logger
->
set_level
(
_level
);
_loggers
[
logger_name
]
=
new_logger
;
return
new_logger
;
}
void
drop
(
const
std
::
string
&
logger_name
)
{
std
::
lock_guard
<
std
::
mutex
>
lock
(
_mutex
);
_loggers
.
erase
(
logger_name
);
}
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
});
}
void
formatter
(
formatter_ptr
f
)
{
std
::
lock_guard
<
std
::
mutex
>
lock
(
_mutex
);
_formatter
=
f
;
for
(
auto
&
l
:
_loggers
)
l
.
second
->
set_formatter
(
_formatter
);
}
void
set_pattern
(
const
std
::
string
&
pattern
)
{
std
::
lock_guard
<
std
::
mutex
>
lock
(
_mutex
);
_formatter
=
std
::
make_shared
<
pattern_formatter
>
(
pattern
);
for
(
auto
&
l
:
_loggers
)
l
.
second
->
set_formatter
(
_formatter
);
}
void
set_level
(
level
::
level_enum
log_level
)
{
std
::
lock_guard
<
std
::
mutex
>
lock
(
_mutex
);
for
(
auto
&
l
:
_loggers
)
l
.
second
->
set_level
(
log_level
);
}
void
set_async_mode
(
size_t
q_size
)
{
std
::
lock_guard
<
std
::
mutex
>
lock
(
_mutex
);
_async_mode
=
true
;
_async_q_size
=
q_size
;
}
void
set_sync_mode
()
{
std
::
lock_guard
<
std
::
mutex
>
lock
(
_mutex
);
_async_mode
=
false
;
}
void
stop_all
()
{
std
::
lock_guard
<
std
::
mutex
>
lock
(
_mutex
);
_level
=
level
::
off
;
for
(
auto
&
l
:
_loggers
)
l
.
second
->
stop
();
}
static
registry
&
instance
()
{
static
registry
s_instance
;
return
s_instance
;
}
private:
registry
()
=
default
;
registry
(
const
registry
&
)
=
delete
;
registry
&
operator
=
(
const
registry
&
)
=
delete
;
std
::
mutex
_mutex
;
std
::
unordered_map
<
std
::
string
,
std
::
shared_ptr
<
logger
>>
_loggers
;
formatter_ptr
_formatter
;
level
::
level_enum
_level
=
level
::
info
;
bool
_async_mode
=
false
;
size_t
_async_q_size
=
0
;
registry
()
=
default
;
registry
(
const
registry
&
)
=
delete
;
registry
&
operator
=
(
const
registry
&
)
=
delete
;
std
::
mutex
_mutex
;
std
::
unordered_map
<
std
::
string
,
std
::
shared_ptr
<
logger
>>
_loggers
;
formatter_ptr
_formatter
;
level
::
level_enum
_level
=
level
::
info
;
bool
_async_mode
=
false
;
size_t
_async_q_size
=
0
;
};
}
}
include/spdlog/details/spdlog_impl.h
View file @
d163b8c4
...
...
@@ -34,62 +34,62 @@
inline
std
::
shared_ptr
<
spdlog
::
logger
>
spdlog
::
get
(
const
std
::
string
&
name
)
{
return
details
::
registry
::
instance
().
get
(
name
);
return
details
::
registry
::
instance
().
get
(
name
);
}
inline
void
spdlog
::
drop
(
const
std
::
string
&
name
)
{
details
::
registry
::
instance
().
drop
(
name
);
details
::
registry
::
instance
().
drop
(
name
);
}
// Create multi/single threaded rotating file logger
inline
std
::
shared_ptr
<
spdlog
::
logger
>
spdlog
::
rotating_logger_mt
(
const
std
::
string
&
logger_name
,
const
std
::
string
&
filename
,
size_t
max_file_size
,
size_t
max_files
,
bool
auto_flush
)
{
return
create
<
spdlog
::
sinks
::
rotating_file_sink_mt
>
(
logger_name
,
filename
,
"txt"
,
max_file_size
,
max_files
,
auto_flush
);
return
create
<
spdlog
::
sinks
::
rotating_file_sink_mt
>
(
logger_name
,
filename
,
"txt"
,
max_file_size
,
max_files
,
auto_flush
);
}
inline
std
::
shared_ptr
<
spdlog
::
logger
>
spdlog
::
rotating_logger_st
(
const
std
::
string
&
logger_name
,
const
std
::
string
&
filename
,
size_t
max_file_size
,
size_t
max_files
,
bool
auto_flush
)
{
return
create
<
spdlog
::
sinks
::
rotating_file_sink_st
>
(
logger_name
,
filename
,
"txt"
,
max_file_size
,
max_files
,
auto_flush
);
return
create
<
spdlog
::
sinks
::
rotating_file_sink_st
>
(
logger_name
,
filename
,
"txt"
,
max_file_size
,
max_files
,
auto_flush
);
}
// Create file logger which creates new file at midnight):
inline
std
::
shared_ptr
<
spdlog
::
logger
>
spdlog
::
daily_logger_mt
(
const
std
::
string
&
logger_name
,
const
std
::
string
&
filename
,
bool
auto_flush
)
{
return
create
<
spdlog
::
sinks
::
daily_file_sink_mt
>
(
logger_name
,
filename
,
"txt"
,
auto_flush
);
return
create
<
spdlog
::
sinks
::
daily_file_sink_mt
>
(
logger_name
,
filename
,
"txt"
,
auto_flush
);
}
inline
std
::
shared_ptr
<
spdlog
::
logger
>
spdlog
::
daily_logger_st
(
const
std
::
string
&
logger_name
,
const
std
::
string
&
filename
,
bool
auto_flush
)
{
return
create
<
spdlog
::
sinks
::
daily_file_sink_st
>
(
logger_name
,
filename
,
"txt"
,
auto_flush
);
return
create
<
spdlog
::
sinks
::
daily_file_sink_st
>
(
logger_name
,
filename
,
"txt"
,
auto_flush
);
}
// Create stdout/stderr loggers
inline
std
::
shared_ptr
<
spdlog
::
logger
>
spdlog
::
stdout_logger_mt
(
const
std
::
string
&
logger_name
)
{
return
create
<
spdlog
::
sinks
::
stdout_sink_mt
>
(
logger_name
);
return
create
<
spdlog
::
sinks
::
stdout_sink_mt
>
(
logger_name
);
}
inline
std
::
shared_ptr
<
spdlog
::
logger
>
spdlog
::
stdout_logger_st
(
const
std
::
string
&
logger_name
)
{
return
create
<
spdlog
::
sinks
::
stdout_sink_st
>
(
logger_name
);
return
create
<
spdlog
::
sinks
::
stdout_sink_st
>
(
logger_name
);
}
inline
std
::
shared_ptr
<
spdlog
::
logger
>
spdlog
::
stderr_logger_mt
(
const
std
::
string
&
logger_name
)
{
return
create
<
spdlog
::
sinks
::
stderr_sink_mt
>
(
logger_name
);
return
create
<
spdlog
::
sinks
::
stderr_sink_mt
>
(
logger_name
);
}
inline
std
::
shared_ptr
<
spdlog
::
logger
>
spdlog
::
stderr_logger_st
(
const
std
::
string
&
logger_name
)
{
return
create
<
spdlog
::
sinks
::
stderr_sink_st
>
(
logger_name
);
return
create
<
spdlog
::
sinks
::
stderr_sink_st
>
(
logger_name
);
}
#ifdef __linux__
// Create syslog logger
inline
std
::
shared_ptr
<
spdlog
::
logger
>
spdlog
::
syslog_logger
(
const
std
::
string
&
logger_name
,
const
std
::
string
&
syslog_ident
,
int
syslog_option
)
{
return
create
<
spdlog
::
sinks
::
syslog_sink
>
(
logger_name
,
syslog_ident
,
syslog_option
);
return
create
<
spdlog
::
sinks
::
syslog_sink
>
(
logger_name
,
syslog_ident
,
syslog_option
);
}
#endif
...
...
@@ -98,51 +98,51 @@ inline std::shared_ptr<spdlog::logger> spdlog::syslog_logger(const std::string&
inline
std
::
shared_ptr
<
spdlog
::
logger
>
spdlog
::
create
(
const
std
::
string
&
logger_name
,
spdlog
::
sinks_init_list
sinks
)
{
return
details
::
registry
::
instance
().
create
(
logger_name
,
sinks
);
return
details
::
registry
::
instance
().
create
(
logger_name
,
sinks
);
}
template
<
typename
Sink
,
typename
...
Args
>
inline
std
::
shared_ptr
<
spdlog
::
logger
>
spdlog
::
create
(
const
std
::
string
&
logger_name
,
const
Args
&
...
args
)
{
sink_ptr
sink
=
std
::
make_shared
<
Sink
>
(
args
...);
return
details
::
registry
::
instance
().
create
(
logger_name
,
{
sink
});
sink_ptr
sink
=
std
::
make_shared
<
Sink
>
(
args
...);
return
details
::
registry
::
instance
().
create
(
logger_name
,
{
sink
});
}
template
<
class
It
>
inline
std
::
shared_ptr
<
spdlog
::
logger
>
spdlog
::
create
(
const
std
::
string
&
logger_name
,
const
It
&
sinks_begin
,
const
It
&
sinks_end
)
{
return
details
::
registry
::
instance
().
create
(
logger_name
,
sinks_begin
,
sinks_end
);
return
details
::
registry
::
instance
().
create
(
logger_name
,
sinks_begin
,
sinks_end
);
}
inline
void
spdlog
::
set_formatter
(
spdlog
::
formatter_ptr
f
)
{
details
::
registry
::
instance
().
formatter
(
f
);
details
::
registry
::
instance
().
formatter
(
f
);
}
inline
void
spdlog
::
set_pattern
(
const
std
::
string
&
format_string
)
{
return
details
::
registry
::
instance
().
set_pattern
(
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
);
return
details
::
registry
::
instance
().
set_level
(
log_level
);
}
inline
void
spdlog
::
set_async_mode
(
size_t
queue_size
)
{
details
::
registry
::
instance
().
set_async_mode
(
queue_size
);
details
::
registry
::
instance
().
set_async_mode
(
queue_size
);
}
inline
void
spdlog
::
set_sync_mode
()
{
details
::
registry
::
instance
().
set_sync_mode
();
details
::
registry
::
instance
().
set_sync_mode
();
}
inline
void
spdlog
::
stop
()
{
return
details
::
registry
::
instance
().
stop_all
();
return
details
::
registry
::
instance
().
stop_all
();
}
include/spdlog/formatter.h
View file @
d163b8c4
...
...
@@ -34,23 +34,23 @@ class flag_formatter;
class
formatter
{
public:
virtual
~
formatter
()
{}
virtual
void
format
(
details
::
log_msg
&
msg
)
=
0
;
virtual
~
formatter
()
{}
virtual
void
format
(
details
::
log_msg
&
msg
)
=
0
;
};
class
pattern_formatter
:
public
formatter
{
public:
explicit
pattern_formatter
(
const
std
::
string
&
pattern
);
pattern_formatter
(
const
pattern_formatter
&
)
=
delete
;
pattern_formatter
&
operator
=
(
const
pattern_formatter
&
)
=
delete
;
void
format
(
details
::
log_msg
&
msg
)
override
;
explicit
pattern_formatter
(
const
std
::
string
&
pattern
);
pattern_formatter
(
const
pattern_formatter
&
)
=
delete
;
pattern_formatter
&
operator
=
(
const
pattern_formatter
&
)
=
delete
;
void
format
(
details
::
log_msg
&
msg
)
override
;
private:
const
std
::
string
_pattern
;
std
::
vector
<
std
::
unique_ptr
<
details
::
flag_formatter
>>
_formatters
;
void
handle_flag
(
char
flag
);
void
compile_pattern
(
const
std
::
string
&
pattern
);
const
std
::
string
_pattern
;
std
::
vector
<
std
::
unique_ptr
<
details
::
flag_formatter
>>
_formatters
;
void
handle_flag
(
char
flag
);
void
compile_pattern
(
const
std
::
string
&
pattern
);
};
}
...
...
include/spdlog/logger.h
View file @
d163b8c4
...
...
@@ -47,88 +47,88 @@ class line_logger;
class
logger
{
public:
logger
(
const
std
::
string
&
logger_name
,
sink_ptr
single_sink
);
logger
(
const
std
::
string
&
name
,
sinks_init_list
);
template
<
class
It
>
logger
(
const
std
::
string
&
name
,
const
It
&
begin
,
const
It
&
end
);
logger
(
const
std
::
string
&
logger_name
,
sink_ptr
single_sink
);
logger
(
const
std
::
string
&
name
,
sinks_init_list
);
template
<
class
It
>
logger
(
const
std
::
string
&
name
,
const
It
&
begin
,
const
It
&
end
);
virtual
~
logger
();
logger
(
const
logger
&
)
=
delete
;
logger
&
operator
=
(
const
logger
&
)
=
delete
;
virtual
~
logger
();
logger
(
const
logger
&
)
=
delete
;
logger
&
operator
=
(
const
logger
&
)
=
delete
;
void
set_level
(
level
::
level_enum
);
level
::
level_enum
level
()
const
;
void
set_level
(
level
::
level_enum
);
level
::
level_enum
level
()
const
;
const
std
::
string
&
name
()
const
;
bool
should_log
(
level
::
level_enum
)
const
;
const
std
::
string
&
name
()
const
;
bool
should_log
(
level
::
level_enum
)
const
;
//Stop logging
void
stop
();
//Stop logging
void
stop
();
template
<
typename
...
Args
>
details
::
line_logger
trace
(
const
char
*
fmt
,
const
Args
&
...
args
);
template
<
typename
...
Args
>
details
::
line_logger
trace
(
const
char
*
fmt
,
const
Args
&
...
args
);
template
<
typename
...
Args
>
details
::
line_logger
debug
(
const
char
*
fmt
,
const
Args
&
...
args
);
template
<
typename
...
Args
>
details
::
line_logger
debug
(
const
char
*
fmt
,
const
Args
&
...
args
);
template
<
typename
...
Args
>
details
::
line_logger
info
(
const
char
*
fmt
,
const
Args
&
...
args
);
template
<
typename
...
Args
>
details
::
line_logger
info
(
const
char
*
fmt
,
const
Args
&
...
args
);
template
<
typename
...
Args
>
details
::
line_logger
notice
(
const
char
*
fmt
,
const
Args
&
...
args
);
template
<
typename
...
Args
>
details
::
line_logger
notice
(
const
char
*
fmt
,
const
Args
&
...
args
);
template
<
typename
...
Args
>
details
::
line_logger
warn
(
const
char
*
fmt
,
const
Args
&
...
args
);
template
<
typename
...
Args
>
details
::
line_logger
warn
(
const
char
*
fmt
,
const
Args
&
...
args
);
template
<
typename
...
Args
>
details
::
line_logger
error
(
const
char
*
fmt
,
const
Args
&
...
args
);
template
<
typename
...
Args
>
details
::
line_logger
error
(
const
char
*
fmt
,
const
Args
&
...
args
);
template
<
typename
...
Args
>
details
::
line_logger
critical
(
const
char
*
fmt
,
const
Args
&
...
args
);
template
<
typename
...
Args
>
details
::
line_logger
critical
(
const
char
*
fmt
,
const
Args
&
...
args
);
template
<
typename
...
Args
>
details
::
line_logger
alert
(
const
char
*
fmt
,
const
Args
&
...
args
);
template
<
typename
...
Args
>
details
::
line_logger
alert
(
const
char
*
fmt
,
const
Args
&
...
args
);
template
<
typename
...
Args
>
details
::
line_logger
emerg
(
const
char
*
fmt
,
const
Args
&
...
args
);
template
<
typename
...
Args
>
details
::
line_logger
emerg
(
const
char
*
fmt
,
const
Args
&
...
args
);
//API to support logger.info() << ".." call style
details
::
line_logger
trace
();
details
::
line_logger
debug
();
details
::
line_logger
info
();
details
::
line_logger
notice
();
details
::
line_logger
warn
();
details
::
line_logger
error
();
details
::
line_logger
critical
();
details
::
line_logger
alert
();
details
::
line_logger
emerg
();
//API to support logger.info() << ".." call style
details
::
line_logger
trace
();
details
::
line_logger
debug
();
details
::
line_logger
info
();
details
::
line_logger
notice
();
details
::
line_logger
warn
();
details
::
line_logger
error
();
details
::
line_logger
critical
();
details
::
line_logger
alert
();
details
::
line_logger
emerg
();
// Create log message with the given level, no matter what is the actual logger's level
template
<
typename
...
Args
>
details
::
line_logger
force_log
(
level
::
level_enum
lvl
,
const
char
*
fmt
,
const
Args
&
...
args
);
// Create log message with the given level, no matter what is the actual logger's level
template
<
typename
...
Args
>
details
::
line_logger
force_log
(
level
::
level_enum
lvl
,
const
char
*
fmt
,
const
Args
&
...
args
);
// Set the format of the log messages from this logger
void
set_pattern
(
const
std
::
string
&
);
void
set_formatter
(
formatter_ptr
);
// Set the format of the log messages from this logger
void
set_pattern
(
const
std
::
string
&
);
void
set_formatter
(
formatter_ptr
);
protected:
virtual
void
_log_msg
(
details
::
log_msg
&
);
virtual
void
_set_pattern
(
const
std
::
string
&
);
virtual
void
_set_formatter
(
formatter_ptr
);
virtual
void
_stop
();
details
::
line_logger
_log_if_enabled
(
level
::
level_enum
lvl
);
template
<
typename
...
Args
>
details
::
line_logger
_log_if_enabled
(
level
::
level_enum
lvl
,
const
char
*
fmt
,
const
Args
&
...
args
);
friend
details
::
line_logger
;
std
::
string
_name
;
std
::
vector
<
sink_ptr
>
_sinks
;
formatter_ptr
_formatter
;
std
::
atomic_int
_level
;
virtual
void
_log_msg
(
details
::
log_msg
&
);
virtual
void
_set_pattern
(
const
std
::
string
&
);
virtual
void
_set_formatter
(
formatter_ptr
);
virtual
void
_stop
();
details
::
line_logger
_log_if_enabled
(
level
::
level_enum
lvl
);
template
<
typename
...
Args
>
details
::
line_logger
_log_if_enabled
(
level
::
level_enum
lvl
,
const
char
*
fmt
,
const
Args
&
...
args
);
friend
details
::
line_logger
;
std
::
string
_name
;
std
::
vector
<
sink_ptr
>
_sinks
;
formatter_ptr
_formatter
;
std
::
atomic_int
_level
;
};
}
...
...
include/spdlog/sinks/base_sink.h
View file @
d163b8c4
...
...
@@ -46,22 +46,22 @@ template<class Mutex>
class
base_sink
:
public
sink
{
public:
base_sink
()
:
_mutex
()
{}
virtual
~
base_sink
()
=
default
;
base_sink
()
:
_mutex
()
{}
virtual
~
base_sink
()
=
default
;
base_sink
(
const
base_sink
&
)
=
delete
;
base_sink
&
operator
=
(
const
base_sink
&
)
=
delete
;
base_sink
(
const
base_sink
&
)
=
delete
;
base_sink
&
operator
=
(
const
base_sink
&
)
=
delete
;
void
log
(
const
details
::
log_msg
&
msg
)
override
{
std
::
lock_guard
<
Mutex
>
lock
(
_mutex
);
_sink_it
(
msg
);
}
void
log
(
const
details
::
log_msg
&
msg
)
override
{
std
::
lock_guard
<
Mutex
>
lock
(
_mutex
);
_sink_it
(
msg
);
}
protected:
virtual
void
_sink_it
(
const
details
::
log_msg
&
msg
)
=
0
;
Mutex
_mutex
;
virtual
void
_sink_it
(
const
details
::
log_msg
&
msg
)
=
0
;
Mutex
_mutex
;
};
}
}
include/spdlog/sinks/file_sinks.h
View file @
d163b8c4
...
...
@@ -43,20 +43,20 @@ template<class Mutex>
class
simple_file_sink
:
public
base_sink
<
Mutex
>
{
public:
explicit
simple_file_sink
(
const
std
::
string
&
filename
,
bool
auto_flush
=
false
)
:
_file_helper
(
auto_flush
)
{
_file_helper
.
open
(
filename
);
}
explicit
simple_file_sink
(
const
std
::
string
&
filename
,
bool
auto_flush
=
false
)
:
_file_helper
(
auto_flush
)
{
_file_helper
.
open
(
filename
);
}
protected:
void
_sink_it
(
const
details
::
log_msg
&
msg
)
override
{
_file_helper
.
write
(
msg
);
}
void
_sink_it
(
const
details
::
log_msg
&
msg
)
override
{
_file_helper
.
write
(
msg
);
}
private:
details
::
file_helper
_file_helper
;
details
::
file_helper
_file_helper
;
};
typedef
simple_file_sink
<
std
::
mutex
>
simple_file_sink_mt
;
...
...
@@ -69,80 +69,80 @@ template<class Mutex>
class
rotating_file_sink
:
public
base_sink
<
Mutex
>
{
public:
rotating_file_sink
(
const
std
::
string
&
base_filename
,
const
std
::
string
&
extension
,
std
::
size_t
max_size
,
std
::
size_t
max_files
,
bool
auto_flush
=
false
)
:
_base_filename
(
base_filename
),
_extension
(
extension
),
_max_size
(
max_size
),
_max_files
(
max_files
),
_current_size
(
0
),
_file_helper
(
auto_flush
)
{
_file_helper
.
open
(
calc_filename
(
_base_filename
,
0
,
_extension
));
}
rotating_file_sink
(
const
std
::
string
&
base_filename
,
const
std
::
string
&
extension
,
std
::
size_t
max_size
,
std
::
size_t
max_files
,
bool
auto_flush
=
false
)
:
_base_filename
(
base_filename
),
_extension
(
extension
),
_max_size
(
max_size
),
_max_files
(
max_files
),
_current_size
(
0
),
_file_helper
(
auto_flush
)
{
_file_helper
.
open
(
calc_filename
(
_base_filename
,
0
,
_extension
));
}
protected:
void
_sink_it
(
const
details
::
log_msg
&
msg
)
override
{
_current_size
+=
msg
.
formatted
.
size
();
if
(
_current_size
>
_max_size
)
{
_rotate
();
_current_size
=
msg
.
formatted
.
size
();
}
_file_helper
.
write
(
msg
);
}
void
_sink_it
(
const
details
::
log_msg
&
msg
)
override
{
_current_size
+=
msg
.
formatted
.
size
();
if
(
_current_size
>
_max_size
)
{
_rotate
();
_current_size
=
msg
.
formatted
.
size
();
}
_file_helper
.
write
(
msg
);
}
private:
static
std
::
string
calc_filename
(
const
std
::
string
&
filename
,
std
::
size_t
index
,
const
std
::
string
&
extension
)
{
details
::
fmt
::
MemoryWriter
w
;
if
(
index
)
w
.
write
(
"{}.{}.{}"
,
filename
,
index
,
extension
);
else
w
.
write
(
"{}.{}"
,
filename
,
extension
);
return
w
.
str
();
}
// Rotate files:
// log.txt -> log.1.txt
// log.1.txt -> log2.txt
// log.2.txt -> log3.txt
// log.3.txt -> delete
void
_rotate
()
{
_file_helper
.
close
();
for
(
auto
i
=
_max_files
;
i
>
0
;
--
i
)
{
std
::
string
src
=
calc_filename
(
_base_filename
,
i
-
1
,
_extension
);
std
::
string
target
=
calc_filename
(
_base_filename
,
i
,
_extension
);
if
(
details
::
file_helper
::
file_exists
(
target
))
{
if
(
std
::
remove
(
target
.
c_str
())
!=
0
)
{
throw
spdlog_ex
(
"rotating_file_sink: failed removing "
+
target
);
}
}
if
(
details
::
file_helper
::
file_exists
(
src
)
&&
std
::
rename
(
src
.
c_str
(),
target
.
c_str
()))
{
throw
spdlog_ex
(
"rotating_file_sink: failed renaming "
+
src
+
" to "
+
target
);
}
}
_file_helper
.
reopen
(
true
);
}
std
::
string
_base_filename
;
std
::
string
_extension
;
std
::
size_t
_max_size
;
std
::
size_t
_max_files
;
std
::
size_t
_current_size
;
details
::
file_helper
_file_helper
;
static
std
::
string
calc_filename
(
const
std
::
string
&
filename
,
std
::
size_t
index
,
const
std
::
string
&
extension
)
{
details
::
fmt
::
MemoryWriter
w
;
if
(
index
)
w
.
write
(
"{}.{}.{}"
,
filename
,
index
,
extension
);
else
w
.
write
(
"{}.{}"
,
filename
,
extension
);
return
w
.
str
();
}
// Rotate files:
// log.txt -> log.1.txt
// log.1.txt -> log2.txt
// log.2.txt -> log3.txt
// log.3.txt -> delete
void
_rotate
()
{
_file_helper
.
close
();
for
(
auto
i
=
_max_files
;
i
>
0
;
--
i
)
{
std
::
string
src
=
calc_filename
(
_base_filename
,
i
-
1
,
_extension
);
std
::
string
target
=
calc_filename
(
_base_filename
,
i
,
_extension
);
if
(
details
::
file_helper
::
file_exists
(
target
))
{
if
(
std
::
remove
(
target
.
c_str
())
!=
0
)
{
throw
spdlog_ex
(
"rotating_file_sink: failed removing "
+
target
);
}
}
if
(
details
::
file_helper
::
file_exists
(
src
)
&&
std
::
rename
(
src
.
c_str
(),
target
.
c_str
()))
{
throw
spdlog_ex
(
"rotating_file_sink: failed renaming "
+
src
+
" to "
+
target
);
}
}
_file_helper
.
reopen
(
true
);
}
std
::
string
_base_filename
;
std
::
string
_extension
;
std
::
size_t
_max_size
;
std
::
size_t
_max_files
;
std
::
size_t
_current_size
;
details
::
file_helper
_file_helper
;
};
typedef
rotating_file_sink
<
std
::
mutex
>
rotating_file_sink_mt
;
...
...
@@ -155,56 +155,56 @@ template<class Mutex>
class
daily_file_sink
:
public
base_sink
<
Mutex
>
{
public:
explicit
daily_file_sink
(
const
std
::
string
&
base_filename
,
const
std
::
string
&
extension
,
bool
auto_flush
=
false
)
:
_base_filename
(
base_filename
),
_extension
(
extension
),
_midnight_tp
(
_calc_midnight_tp
()
),
_file_helper
(
auto_flush
)
{
_file_helper
.
open
(
calc_filename
(
_base_filename
,
_extension
));
}
explicit
daily_file_sink
(
const
std
::
string
&
base_filename
,
const
std
::
string
&
extension
,
bool
auto_flush
=
false
)
:
_base_filename
(
base_filename
),
_extension
(
extension
),
_midnight_tp
(
_calc_midnight_tp
()
),
_file_helper
(
auto_flush
)
{
_file_helper
.
open
(
calc_filename
(
_base_filename
,
_extension
));
}
protected:
void
_sink_it
(
const
details
::
log_msg
&
msg
)
override
{
if
(
std
::
chrono
::
system_clock
::
now
()
>=
_midnight_tp
)
{
_file_helper
.
close
();
_file_helper
.
open
(
calc_filename
(
_base_filename
,
_extension
));
_midnight_tp
=
_calc_midnight_tp
();
}
_file_helper
.
write
(
msg
);
}
void
_sink_it
(
const
details
::
log_msg
&
msg
)
override
{
if
(
std
::
chrono
::
system_clock
::
now
()
>=
_midnight_tp
)
{
_file_helper
.
close
();
_file_helper
.
open
(
calc_filename
(
_base_filename
,
_extension
));
_midnight_tp
=
_calc_midnight_tp
();
}
_file_helper
.
write
(
msg
);
}
private:
// Return next midnight's time_point
static
std
::
chrono
::
system_clock
::
time_point
_calc_midnight_tp
()
{
using
namespace
std
::
chrono
;
auto
now
=
system_clock
::
now
();
time_t
tnow
=
std
::
chrono
::
system_clock
::
to_time_t
(
now
);
tm
date
=
spdlog
::
details
::
os
::
localtime
(
tnow
);
date
.
tm_hour
=
date
.
tm_min
=
date
.
tm_sec
=
0
;
auto
midnight
=
std
::
chrono
::
system_clock
::
from_time_t
(
std
::
mktime
(
&
date
));
return
system_clock
::
time_point
(
midnight
+
hours
(
24
));
}
//Create filename for the form basename.YYYY-MM-DD.extension
static
std
::
string
calc_filename
(
const
std
::
string
&
basename
,
const
std
::
string
&
extension
)
{
std
::
tm
tm
=
spdlog
::
details
::
os
::
localtime
();
details
::
fmt
::
MemoryWriter
w
;
w
.
write
(
"{}.{:04d}-{:02d}-{:02d}.{}"
,
basename
,
tm
.
tm_year
+
1900
,
tm
.
tm_mon
+
1
,
tm
.
tm_mday
,
extension
);
return
w
.
str
();
}
std
::
string
_base_filename
;
std
::
string
_extension
;
std
::
chrono
::
system_clock
::
time_point
_midnight_tp
;
details
::
file_helper
_file_helper
;
// Return next midnight's time_point
static
std
::
chrono
::
system_clock
::
time_point
_calc_midnight_tp
()
{
using
namespace
std
::
chrono
;
auto
now
=
system_clock
::
now
();
time_t
tnow
=
std
::
chrono
::
system_clock
::
to_time_t
(
now
);
tm
date
=
spdlog
::
details
::
os
::
localtime
(
tnow
);
date
.
tm_hour
=
date
.
tm_min
=
date
.
tm_sec
=
0
;
auto
midnight
=
std
::
chrono
::
system_clock
::
from_time_t
(
std
::
mktime
(
&
date
));
return
system_clock
::
time_point
(
midnight
+
hours
(
24
));
}
//Create filename for the form basename.YYYY-MM-DD.extension
static
std
::
string
calc_filename
(
const
std
::
string
&
basename
,
const
std
::
string
&
extension
)
{
std
::
tm
tm
=
spdlog
::
details
::
os
::
localtime
();
details
::
fmt
::
MemoryWriter
w
;
w
.
write
(
"{}.{:04d}-{:02d}-{:02d}.{}"
,
basename
,
tm
.
tm_year
+
1900
,
tm
.
tm_mon
+
1
,
tm
.
tm_mday
,
extension
);
return
w
.
str
();
}
std
::
string
_base_filename
;
std
::
string
_extension
;
std
::
chrono
::
system_clock
::
time_point
_midnight_tp
;
details
::
file_helper
_file_helper
;
};
...
...
include/spdlog/sinks/null_sink.h
View file @
d163b8c4
...
...
@@ -37,8 +37,8 @@ template <class Mutex>
class
null_sink
:
public
base_sink
<
Mutex
>
{
protected:
void
_sink_it
(
const
details
::
log_msg
&
)
override
{}
void
_sink_it
(
const
details
::
log_msg
&
)
override
{}
};
typedef
null_sink
<
details
::
null_mutex
>
null_sink_st
;
...
...
include/spdlog/sinks/ostream_sink.h
View file @
d163b8c4
...
...
@@ -39,17 +39,17 @@ template<class Mutex>
class
ostream_sink
:
public
base_sink
<
Mutex
>
{
public:
explicit
ostream_sink
(
std
::
ostream
&
os
)
:
_ostream
(
os
)
{}
ostream_sink
(
const
ostream_sink
&
)
=
delete
;
ostream_sink
&
operator
=
(
const
ostream_sink
&
)
=
delete
;
virtual
~
ostream_sink
()
=
default
;
explicit
ostream_sink
(
std
::
ostream
&
os
)
:
_ostream
(
os
)
{}
ostream_sink
(
const
ostream_sink
&
)
=
delete
;
ostream_sink
&
operator
=
(
const
ostream_sink
&
)
=
delete
;
virtual
~
ostream_sink
()
=
default
;
protected:
virtual
void
_sink_it
(
const
details
::
log_msg
&
msg
)
override
{
_ostream
.
write
(
msg
.
formatted
.
data
(),
msg
.
formatted
.
size
());
}
std
::
ostream
&
_ostream
;
virtual
void
_sink_it
(
const
details
::
log_msg
&
msg
)
override
{
_ostream
.
write
(
msg
.
formatted
.
data
(),
msg
.
formatted
.
size
());
}
std
::
ostream
&
_ostream
;
};
typedef
ostream_sink
<
std
::
mutex
>
ostream_sink_mt
;
...
...
include/spdlog/sinks/sink.h
View file @
d163b8c4
...
...
@@ -33,8 +33,8 @@ namespace sinks
class
sink
{
public:
virtual
~
sink
()
{}
virtual
void
log
(
const
details
::
log_msg
&
msg
)
=
0
;
virtual
~
sink
()
{}
virtual
void
log
(
const
details
::
log_msg
&
msg
)
=
0
;
};
}
}
...
...
include/spdlog/sinks/stdout_sinks.h
View file @
d163b8c4
...
...
@@ -38,7 +38,7 @@ template <class Mutex>
class
stdout_sink
:
public
ostream_sink
<
Mutex
>
{
public:
stdout_sink
()
:
ostream_sink
<
Mutex
>
(
std
::
cout
)
{}
stdout_sink
()
:
ostream_sink
<
Mutex
>
(
std
::
cout
)
{}
};
...
...
@@ -50,7 +50,7 @@ template <class Mutex>
class
stderr_sink
:
public
ostream_sink
<
Mutex
>
{
public:
stderr_sink
()
:
ostream_sink
<
Mutex
>
(
std
::
cerr
)
{}
stderr_sink
()
:
ostream_sink
<
Mutex
>
(
std
::
cerr
)
{}
};
typedef
stderr_sink
<
std
::
mutex
>
stderr_sink_mt
;
...
...
include/spdlog/sinks/syslog_sink.h
View file @
d163b8c4
...
...
@@ -47,50 +47,50 @@ class syslog_sink : public sink
{
public:
//
syslog_sink
(
const
std
::
string
&
ident
=
""
,
int
syslog_option
=
0
,
int
syslog_facility
=
LOG_USER
)
:
_ident
(
ident
)
{
_priorities
[
static_cast
<
int
>
(
level
::
trace
)]
=
LOG_DEBUG
;
_priorities
[
static_cast
<
int
>
(
level
::
debug
)]
=
LOG_DEBUG
;
_priorities
[
static_cast
<
int
>
(
level
::
info
)]
=
LOG_INFO
;
_priorities
[
static_cast
<
int
>
(
level
::
notice
)]
=
LOG_NOTICE
;
_priorities
[
static_cast
<
int
>
(
level
::
warn
)]
=
LOG_WARNING
;
_priorities
[
static_cast
<
int
>
(
level
::
err
)]
=
LOG_ERR
;
_priorities
[
static_cast
<
int
>
(
level
::
critical
)]
=
LOG_CRIT
;
_priorities
[
static_cast
<
int
>
(
level
::
alert
)]
=
LOG_ALERT
;
_priorities
[
static_cast
<
int
>
(
level
::
emerg
)]
=
LOG_EMERG
;
_priorities
[
static_cast
<
int
>
(
level
::
off
)]
=
LOG_INFO
;
syslog_sink
(
const
std
::
string
&
ident
=
""
,
int
syslog_option
=
0
,
int
syslog_facility
=
LOG_USER
)
:
_ident
(
ident
)
{
_priorities
[
static_cast
<
int
>
(
level
::
trace
)]
=
LOG_DEBUG
;
_priorities
[
static_cast
<
int
>
(
level
::
debug
)]
=
LOG_DEBUG
;
_priorities
[
static_cast
<
int
>
(
level
::
info
)]
=
LOG_INFO
;
_priorities
[
static_cast
<
int
>
(
level
::
notice
)]
=
LOG_NOTICE
;
_priorities
[
static_cast
<
int
>
(
level
::
warn
)]
=
LOG_WARNING
;
_priorities
[
static_cast
<
int
>
(
level
::
err
)]
=
LOG_ERR
;
_priorities
[
static_cast
<
int
>
(
level
::
critical
)]
=
LOG_CRIT
;
_priorities
[
static_cast
<
int
>
(
level
::
alert
)]
=
LOG_ALERT
;
_priorities
[
static_cast
<
int
>
(
level
::
emerg
)]
=
LOG_EMERG
;
_priorities
[
static_cast
<
int
>
(
level
::
off
)]
=
LOG_INFO
;
//set ident to be program name if empty
::
openlog
(
_ident
.
empty
()
?
nullptr
:
_ident
.
c_str
(),
syslog_option
,
syslog_facility
);
}
~
syslog_sink
()
{
::
openlog
(
_ident
.
empty
()
?
nullptr
:
_ident
.
c_str
(),
syslog_option
,
syslog_facility
);
}
~
syslog_sink
()
{
::
closelog
();
}
}
syslog_sink
(
const
syslog_sink
&
)
=
delete
;
syslog_sink
&
operator
=
(
const
syslog_sink
&
)
=
delete
;
syslog_sink
(
const
syslog_sink
&
)
=
delete
;
syslog_sink
&
operator
=
(
const
syslog_sink
&
)
=
delete
;
void
log
(
const
details
::
log_msg
&
msg
)
override
{
::
syslog
(
syslog_prio_from_level
(
msg
),
"%s"
,
msg
.
formatted
.
str
().
c_str
());
}
void
log
(
const
details
::
log_msg
&
msg
)
override
{
::
syslog
(
syslog_prio_from_level
(
msg
),
"%s"
,
msg
.
formatted
.
str
().
c_str
());
}
private:
std
::
array
<
int
,
10
>
_priorities
;
//must store the ident because the man says openlog might use the pointer as is and not a string copy
const
std
::
string
_ident
;
//
// Simply maps spdlog's log level to syslog priority level.
//
int
syslog_prio_from_level
(
const
details
::
log_msg
&
msg
)
const
{
return
_priorities
[
static_cast
<
int
>
(
msg
.
level
)];
}
std
::
array
<
int
,
10
>
_priorities
;
//must store the ident because the man says openlog might use the pointer as is and not a string copy
const
std
::
string
_ident
;
//
// Simply maps spdlog's log level to syslog priority level.
//
int
syslog_prio_from_level
(
const
details
::
log_msg
&
msg
)
const
{
return
_priorities
[
static_cast
<
int
>
(
msg
.
level
)];
}
};
}
}
...
...
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