Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
S
spdlog
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
spdlog
Commits
84c7f927
Unverified
Commit
84c7f927
authored
Apr 06, 2018
by
Gabi Melman
Committed by
GitHub
Apr 06, 2018
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #679 from gabime/color-formatting
Color formatting
parents
93d41b2c
644c81b9
Hide whitespace changes
Inline
Side-by-side
Showing
21 changed files
with
199 additions
and
84 deletions
+199
-84
boost-bench-mt.cpp
bench/boost-bench-mt.cpp
+0
-1
easylogging-bench-async.cpp
bench/easylogging-bench-async.cpp
+1
-1
easylogging-bench-mt.cpp
bench/easylogging-bench-mt.cpp
+1
-1
easylogging-bench.cpp
bench/easylogging-bench.cpp
+2
-2
g3log-async.cpp
bench/g3log-async.cpp
+3
-2
glog-bench.cpp
bench/glog-bench.cpp
+0
-1
log4cplus-bench-mt.cpp
bench/log4cplus-bench-mt.cpp
+6
-8
log4cplus-bench.cpp
bench/log4cplus-bench.cpp
+5
-7
log4cpp-bench-mt.cpp
bench/log4cpp-bench-mt.cpp
+6
-6
log4cpp-bench.cpp
bench/log4cpp-bench.cpp
+5
-5
p7-bench-mt.cpp
bench/p7-bench-mt.cpp
+10
-13
p7-bench.cpp
bench/p7-bench.cpp
+7
-11
spdlog-async.cpp
bench/spdlog-async.cpp
+3
-3
spdlog-bench-mt.cpp
bench/spdlog-bench-mt.cpp
+1
-1
example.cpp
example/example.cpp
+4
-3
log_msg.h
include/spdlog/details/log_msg.h
+3
-0
os.h
include/spdlog/details/os.h
+1
-1
pattern_formatter_impl.h
include/spdlog/details/pattern_formatter_impl.h
+31
-1
ansicolor_sink.h
include/spdlog/sinks/ansicolor_sink.h
+21
-9
wincolor_sink.h
include/spdlog/sinks/wincolor_sink.h
+26
-6
test_pattern_formatter.cpp
tests/test_pattern_formatter.cpp
+63
-2
No files found.
bench/boost-bench-mt.cpp
View file @
84c7f927
...
...
@@ -82,6 +82,5 @@ int main(int argc, char *argv[])
std
::
cout
<<
"Delta = "
<<
deltaf
<<
" seconds"
<<
std
::
endl
;
std
::
cout
<<
"Rate = "
<<
rate
<<
"/sec"
<<
std
::
endl
;
return
0
;
}
bench/easylogging-bench-async.cpp
View file @
84c7f927
...
...
@@ -11,8 +11,8 @@
#define ELPP_THREAD_SAFE
#define ELPP_EXPERIMENTAL_ASYNC
#include "easylogging++.h"
#include "easylogging++.cc"
#include "easylogging++.h"
INITIALIZE_EASYLOGGINGPP
using
namespace
std
;
...
...
bench/easylogging-bench-mt.cpp
View file @
84c7f927
...
...
@@ -10,8 +10,8 @@
#include <vector>
#define ELPP_THREAD_SAFE
#include "easylogging++.h"
#include "easylogging++.cc"
#include "easylogging++.h"
INITIALIZE_EASYLOGGINGPP
using
namespace
std
;
...
...
bench/easylogging-bench.cpp
View file @
84c7f927
...
...
@@ -6,8 +6,8 @@
#include <chrono>
#include <iostream>
#include "easylogging++.h"
#include "easylogging++.cc"
#include "easylogging++.h"
INITIALIZE_EASYLOGGINGPP
int
main
(
int
,
char
*
[])
...
...
@@ -21,7 +21,7 @@ int main(int, char *[])
el
::
Configurations
conf
(
"easyl.conf"
);
el
::
Loggers
::
reconfigureLogger
(
"default"
,
conf
);
el
::
Logger
*
defaultLogger
=
el
::
Loggers
::
getLogger
(
"default"
);
el
::
Logger
*
defaultLogger
=
el
::
Loggers
::
getLogger
(
"default"
);
auto
start
=
clock
::
now
();
for
(
int
i
=
0
;
i
<
howmany
;
++
i
)
...
...
bench/g3log-async.cpp
View file @
84c7f927
...
...
@@ -13,7 +13,8 @@
#include "g3log/logworker.hpp"
using
namespace
std
;
template
<
typename
T
>
std
::
string
format
(
const
T
&
value
);
template
<
typename
T
>
std
::
string
format
(
const
T
&
value
);
int
main
(
int
argc
,
char
*
argv
[])
{
...
...
@@ -27,7 +28,7 @@ int main(int argc, char *argv[])
int
howmany
=
1000000
;
auto
worker
=
g3
::
LogWorker
::
createLogWorker
();
auto
handle
=
worker
->
addDefaultLogger
(
argv
[
0
],
"logs"
);
auto
handle
=
worker
->
addDefaultLogger
(
argv
[
0
],
"logs"
);
g3
::
initializeLogging
(
worker
.
get
());
std
::
atomic
<
int
>
msg_counter
{
0
};
...
...
bench/glog-bench.cpp
View file @
84c7f927
...
...
@@ -8,7 +8,6 @@
#include "glog/logging.h"
int
main
(
int
,
char
*
argv
[])
{
using
namespace
std
::
chrono
;
...
...
bench/log4cplus-bench-mt.cpp
View file @
84c7f927
...
...
@@ -10,17 +10,17 @@
#include <thread>
#include <vector>
#include "log4cplus/logger.h"
#include "log4cplus/fileappender.h"
#include "log4cplus/layout.h"
#include "log4cplus/ndc.h"
#include "log4cplus/helpers/loglog.h"
#include "log4cplus/helpers/property.h"
#include "log4cplus/layout.h"
#include "log4cplus/logger.h"
#include "log4cplus/loggingmacros.h"
#include "log4cplus/ndc.h"
using
namespace
log4cplus
;
int
main
(
int
argc
,
char
*
argv
[])
int
main
(
int
argc
,
char
*
argv
[])
{
using
namespace
std
::
chrono
;
using
clock
=
steady_clock
;
...
...
@@ -32,13 +32,11 @@ int main(int argc, char * argv[])
int
howmany
=
1000000
;
log4cplus
::
initialize
();
SharedFileAppenderPtr
append
(
new
FileAppender
(
LOG4CPLUS_TEXT
(
"logs/log4cplus-bench-mt.log"
),
std
::
ios_base
::
trunc
,
true
,
true
));
SharedFileAppenderPtr
append
(
new
FileAppender
(
LOG4CPLUS_TEXT
(
"logs/log4cplus-bench-mt.log"
),
std
::
ios_base
::
trunc
,
true
,
true
));
append
->
setName
(
LOG4CPLUS_TEXT
(
"File"
));
log4cplus
::
tstring
pattern
=
LOG4CPLUS_TEXT
(
"%d{%Y-%m-%d %H:%M:%S.%Q}: %p - %m %n"
);
append
->
setLayout
(
std
::
auto_ptr
<
Layout
>
(
new
PatternLayout
(
pattern
))
);
append
->
setLayout
(
std
::
auto_ptr
<
Layout
>
(
new
PatternLayout
(
pattern
))
);
append
->
getloc
();
Logger
::
getRoot
().
addAppender
(
SharedAppenderPtr
(
append
.
get
()));
...
...
bench/log4cplus-bench.cpp
View file @
84c7f927
...
...
@@ -7,13 +7,13 @@
#include <iostream>
#include <memory>
#include "log4cplus/logger.h"
#include "log4cplus/fileappender.h"
#include "log4cplus/layout.h"
#include "log4cplus/ndc.h"
#include "log4cplus/helpers/loglog.h"
#include "log4cplus/helpers/property.h"
#include "log4cplus/layout.h"
#include "log4cplus/logger.h"
#include "log4cplus/loggingmacros.h"
#include "log4cplus/ndc.h"
using
namespace
log4cplus
;
...
...
@@ -25,13 +25,11 @@ int main(int, char *[])
int
howmany
=
1000000
;
log4cplus
::
initialize
();
SharedFileAppenderPtr
append
(
new
FileAppender
(
LOG4CPLUS_TEXT
(
"logs/log4cplus-bench.log"
),
std
::
ios_base
::
trunc
,
true
,
true
));
SharedFileAppenderPtr
append
(
new
FileAppender
(
LOG4CPLUS_TEXT
(
"logs/log4cplus-bench.log"
),
std
::
ios_base
::
trunc
,
true
,
true
));
append
->
setName
(
LOG4CPLUS_TEXT
(
"File"
));
log4cplus
::
tstring
pattern
=
LOG4CPLUS_TEXT
(
"%d{%Y-%m-%d %H:%M:%S.%Q}: %p - %m %n"
);
append
->
setLayout
(
std
::
auto_ptr
<
Layout
>
(
new
PatternLayout
(
pattern
))
);
append
->
setLayout
(
std
::
auto_ptr
<
Layout
>
(
new
PatternLayout
(
pattern
))
);
append
->
getloc
();
Logger
::
getRoot
().
addAppender
(
SharedAppenderPtr
(
append
.
get
()));
...
...
bench/log4cpp-bench-mt.cpp
View file @
84c7f927
...
...
@@ -10,15 +10,15 @@
#include <thread>
#include <vector>
#include "log4cpp/Category.hh"
#include "log4cpp/Appender.hh"
#include "log4cpp/BasicLayout.hh"
#include "log4cpp/Category.hh"
#include "log4cpp/FileAppender.hh"
#include "log4cpp/Layout.hh"
#include "log4cpp/BasicLayout.hh"
#include "log4cpp/Priority.hh"
#include "log4cpp/PatternLayout.hh"
#include "log4cpp/Priority.hh"
int
main
(
int
argc
,
char
*
argv
[])
int
main
(
int
argc
,
char
*
argv
[])
{
using
namespace
std
::
chrono
;
using
clock
=
steady_clock
;
...
...
@@ -29,12 +29,12 @@ int main(int argc, char * argv[])
int
howmany
=
1000000
;
log4cpp
::
Appender
*
appender
=
new
log4cpp
::
FileAppender
(
"default"
,
"logs/log4cpp-bench-mt.log"
);
log4cpp
::
Appender
*
appender
=
new
log4cpp
::
FileAppender
(
"default"
,
"logs/log4cpp-bench-mt.log"
);
log4cpp
::
PatternLayout
*
layout
=
new
log4cpp
::
PatternLayout
();
layout
->
setConversionPattern
(
"%d{%Y-%m-%d %H:%M:%S.%l}: %p - %m %n"
);
appender
->
setLayout
(
layout
);
log4cpp
::
Category
&
root
=
log4cpp
::
Category
::
getRoot
();
log4cpp
::
Category
&
root
=
log4cpp
::
Category
::
getRoot
();
root
.
addAppender
(
appender
);
root
.
setPriority
(
log4cpp
::
Priority
::
INFO
);
...
...
bench/log4cpp-bench.cpp
View file @
84c7f927
...
...
@@ -7,13 +7,13 @@
#include <iostream>
#include <memory>
#include "log4cpp/Category.hh"
#include "log4cpp/Appender.hh"
#include "log4cpp/BasicLayout.hh"
#include "log4cpp/Category.hh"
#include "log4cpp/FileAppender.hh"
#include "log4cpp/Layout.hh"
#include "log4cpp/BasicLayout.hh"
#include "log4cpp/Priority.hh"
#include "log4cpp/PatternLayout.hh"
#include "log4cpp/Priority.hh"
int
main
(
int
,
char
*
[])
{
...
...
@@ -22,12 +22,12 @@ int main(int, char *[])
int
howmany
=
1000000
;
log4cpp
::
Appender
*
appender
=
new
log4cpp
::
FileAppender
(
"default"
,
"logs/log4cpp-bench.log"
);
log4cpp
::
Appender
*
appender
=
new
log4cpp
::
FileAppender
(
"default"
,
"logs/log4cpp-bench.log"
);
log4cpp
::
PatternLayout
*
layout
=
new
log4cpp
::
PatternLayout
();
layout
->
setConversionPattern
(
"%d{%Y-%m-%d %H:%M:%S.%l}: %p - %m %n"
);
appender
->
setLayout
(
layout
);
log4cpp
::
Category
&
root
=
log4cpp
::
Category
::
getRoot
();
log4cpp
::
Category
&
root
=
log4cpp
::
Category
::
getRoot
();
root
.
addAppender
(
appender
);
root
.
setPriority
(
log4cpp
::
Priority
::
INFO
);
...
...
bench/p7-bench-mt.cpp
View file @
84c7f927
...
...
@@ -5,15 +5,14 @@
#include <atomic>
#include <chrono>
#include <functional>
#include <iostream>
#include <memory>
#include <thread>
#include <vector>
#include <memory>
#include <functional>
#include "P7_Trace.h"
int
main
(
int
argc
,
char
*
argv
[])
{
using
namespace
std
::
chrono
;
...
...
@@ -27,10 +26,9 @@ int main(int argc, char *argv[])
IP7_Trace
::
hModule
module
=
NULL
;
//create P7 client object
std
::
unique_ptr
<
IP7_Client
,
std
::
function
<
void
(
IP7_Client
*
)
>>
client
(
P7_Create_Client
(
TM
(
"/P7.Pool=1024 /P7.Sink=FileTxt /P7.Dir=logs/p7-bench-mt"
)),
[
&
](
IP7_Client
*
ptr
){
// create P7 client object
std
::
unique_ptr
<
IP7_Client
,
std
::
function
<
void
(
IP7_Client
*
)
>>
client
(
P7_Create_Client
(
TM
(
"/P7.Pool=1024 /P7.Sink=FileTxt /P7.Dir=logs/p7-bench-mt"
)),
[
&
](
IP7_Client
*
ptr
)
{
if
(
ptr
)
ptr
->
Release
();
});
...
...
@@ -41,10 +39,9 @@ int main(int argc, char *argv[])
return
1
;
}
//create P7 trace object 1
std
::
unique_ptr
<
IP7_Trace
,
std
::
function
<
void
(
IP7_Trace
*
)
>>
trace
(
P7_Create_Trace
(
client
.
get
(),
TM
(
"Trace channel 1"
)),
[
&
](
IP7_Trace
*
ptr
){
// create P7 trace object 1
std
::
unique_ptr
<
IP7_Trace
,
std
::
function
<
void
(
IP7_Trace
*
)
>>
trace
(
P7_Create_Trace
(
client
.
get
(),
TM
(
"Trace channel 1"
)),
[
&
](
IP7_Trace
*
ptr
)
{
if
(
ptr
)
ptr
->
Release
();
});
...
...
@@ -65,7 +62,7 @@ int main(int argc, char *argv[])
for
(
int
t
=
0
;
t
<
thread_count
;
++
t
)
{
threads
.
push_back
(
std
::
thread
([
&
]()
{
trace
->
Register_Thread
(
TM
(
"Application"
),
t
+
1
);
trace
->
Register_Thread
(
TM
(
"Application"
),
t
+
1
);
while
(
true
)
{
int
counter
=
++
msg_counter
;
...
...
@@ -73,7 +70,7 @@ int main(int argc, char *argv[])
break
;
trace
->
P7_INFO
(
module
,
TM
(
"p7 message #%d: This is some text for your pleasure"
),
counter
);
}
trace
->
Register_Thread
(
TM
(
"Application"
),
t
+
1
);
trace
->
Register_Thread
(
TM
(
"Application"
),
t
+
1
);
}));
}
...
...
bench/p7-bench.cpp
View file @
84c7f927
...
...
@@ -4,13 +4,12 @@
//
#include <chrono>
#include <functional>
#include <iostream>
#include <memory>
#include <functional>
#include "P7_Trace.h"
int
main
(
int
,
char
*
[])
{
using
namespace
std
::
chrono
;
...
...
@@ -20,10 +19,9 @@ int main(int, char *[])
IP7_Trace
::
hModule
module
=
NULL
;
//create P7 client object
std
::
unique_ptr
<
IP7_Client
,
std
::
function
<
void
(
IP7_Client
*
)
>>
client
(
P7_Create_Client
(
TM
(
"/P7.Pool=1024 /P7.Sink=FileTxt /P7.Dir=logs/p7-bench"
)),
[
&
](
IP7_Client
*
ptr
){
// create P7 client object
std
::
unique_ptr
<
IP7_Client
,
std
::
function
<
void
(
IP7_Client
*
)
>>
client
(
P7_Create_Client
(
TM
(
"/P7.Pool=1024 /P7.Sink=FileTxt /P7.Dir=logs/p7-bench"
)),
[
&
](
IP7_Client
*
ptr
)
{
if
(
ptr
)
ptr
->
Release
();
});
...
...
@@ -34,10 +32,9 @@ int main(int, char *[])
return
1
;
}
//create P7 trace object 1
std
::
unique_ptr
<
IP7_Trace
,
std
::
function
<
void
(
IP7_Trace
*
)
>>
trace
(
P7_Create_Trace
(
client
.
get
(),
TM
(
"Trace channel 1"
)),
[
&
](
IP7_Trace
*
ptr
){
// create P7 trace object 1
std
::
unique_ptr
<
IP7_Trace
,
std
::
function
<
void
(
IP7_Trace
*
)
>>
trace
(
P7_Create_Trace
(
client
.
get
(),
TM
(
"Trace channel 1"
)),
[
&
](
IP7_Trace
*
ptr
)
{
if
(
ptr
)
ptr
->
Release
();
});
...
...
@@ -55,7 +52,6 @@ int main(int, char *[])
for
(
int
i
=
0
;
i
<
howmany
;
++
i
)
trace
->
P7_INFO
(
module
,
TM
(
"p7 message #%d: This is some text for your pleasure"
),
i
);
duration
<
float
>
delta
=
clock
::
now
()
-
start
;
float
deltaf
=
delta
.
count
();
auto
rate
=
howmany
/
deltaf
;
...
...
bench/spdlog-async.cpp
View file @
84c7f927
...
...
@@ -5,8 +5,8 @@
#include <atomic>
#include <chrono>
#include <iostream>
#include <cstdlib>
#include <iostream>
#include <thread>
#include <vector>
...
...
@@ -36,7 +36,7 @@ int main(int argc, char *argv[])
run
=
false
;
}));
while
(
run
)
while
(
run
)
{
std
::
atomic
<
int
>
msg_counter
{
0
};
std
::
vector
<
std
::
thread
>
threads
;
...
...
@@ -68,7 +68,7 @@ int main(int argc, char *argv[])
std
::
cout
<<
"Threads: "
<<
thread_count
<<
std
::
endl
;
std
::
cout
<<
"Delta = "
<<
std
::
fixed
<<
deltaf
<<
" seconds"
<<
std
::
endl
;
std
::
cout
<<
"Rate = "
<<
std
::
fixed
<<
rate
<<
"/sec"
<<
std
::
endl
;
}
//while
}
//
while
stoper
.
join
();
...
...
bench/spdlog-bench-mt.cpp
View file @
84c7f927
...
...
@@ -5,8 +5,8 @@
#include <atomic>
#include <chrono>
#include <iostream>
#include <cstdlib>
#include <iostream>
#include <thread>
#include <vector>
...
...
example/example.cpp
View file @
84c7f927
...
...
@@ -58,9 +58,10 @@ int main(int, char *[])
daily_logger
->
info
(
123.44
);
// Customize msg format for all messages
spd
::
set_pattern
(
"*** [%H:%M:%S %z] [thread %t] %v ***"
);
rotating_logger
->
info
(
"This is another message with custom format"
);
spd
::
set_pattern
(
"[%^+++%$] [%H:%M:%S %z] [thread %t] %v"
);
console
->
info
(
"This an info message with custom format (and custom color range between the '%^' and '%$')"
);
console
->
error
(
"This an error message with custom format (and custom color range between the '%^' and '%$')"
);
// Runtime log levels
spd
::
set_level
(
spd
::
level
::
info
);
// Set global log level to info
console
->
debug
(
"This message should not be displayed!"
);
...
...
include/spdlog/details/log_msg.h
View file @
84c7f927
...
...
@@ -40,6 +40,9 @@ struct log_msg
fmt
::
MemoryWriter
raw
;
fmt
::
MemoryWriter
formatted
;
size_t
msg_id
{
0
};
// wrap this range with color codes
size_t
color_range_start
{
0
};
size_t
color_range_end
{
0
};
};
}
// namespace details
}
// namespace spdlog
include/spdlog/details/os.h
View file @
84c7f927
...
...
@@ -238,7 +238,7 @@ inline size_t filesize(FILE *f)
int
fd
=
fileno
(
f
);
// 64 bits(but not in osx or cygwin, where fstat64 is deprecated)
#if !defined(__FreeBSD__) && !defined(__APPLE__) && (defined(__x86_64__) || defined(__ppc64__)) && !defined(__CYGWIN__)
struct
stat64
st
;
struct
stat64
st
;
if
(
fstat64
(
fd
,
&
st
)
==
0
)
{
return
static_cast
<
size_t
>
(
st
.
st_size
);
...
...
include/spdlog/details/pattern_formatter_impl.h
View file @
84c7f927
...
...
@@ -421,6 +421,22 @@ private:
std
::
string
_str
;
};
// mark the color range. expect it to be in the form of "%^colored text%$"
class
color_start_formatter
SPDLOG_FINAL
:
public
flag_formatter
{
void
format
(
details
::
log_msg
&
msg
,
const
std
::
tm
&
)
override
{
msg
.
color_range_start
=
msg
.
formatted
.
size
();
}
};
class
color_stop_formatter
SPDLOG_FINAL
:
public
flag_formatter
{
void
format
(
details
::
log_msg
&
msg
,
const
std
::
tm
&
)
override
{
msg
.
color_range_end
=
msg
.
formatted
.
size
();
}
};
// Full info formatter
// pattern: [%Y-%m-%d %H:%M:%S.%e] [%n] [%l] %v
class
full_formatter
SPDLOG_FINAL
:
public
flag_formatter
...
...
@@ -462,8 +478,13 @@ class full_formatter SPDLOG_FINAL : public flag_formatter
msg
.
formatted
<<
'['
<<
*
msg
.
logger_name
<<
"] "
;
#endif
msg
.
formatted
<<
'['
<<
level
::
to_str
(
msg
.
level
)
<<
"] "
;
const
char
*
level_name
=
level
::
to_str
(
msg
.
level
);
size_t
level_name_size
=
strlen
(
level_name
);
msg
.
formatted
<<
'['
<<
fmt
::
StringRef
(
level_name
,
level_name_size
)
<<
"] "
;
msg
.
formatted
<<
fmt
::
StringRef
(
msg
.
raw
.
data
(),
msg
.
raw
.
size
());
// wrap the level with color
msg
.
color_range_start
=
37
;
msg
.
color_range_end
=
37
+
level_name_size
;
}
};
...
...
@@ -491,6 +512,7 @@ inline void spdlog::pattern_formatter::compile_pattern(const std::string &patter
{
_formatters
.
push_back
(
std
::
move
(
user_chars
));
}
// if(
if
(
++
it
!=
end
)
{
handle_flag
(
*
it
);
...
...
@@ -645,6 +667,14 @@ inline void spdlog::pattern_formatter::handle_flag(char flag)
_formatters
.
emplace_back
(
new
details
::
i_formatter
());
break
;
case
(
'^'
):
_formatters
.
emplace_back
(
new
details
::
color_start_formatter
());
break
;
case
(
'$'
):
_formatters
.
emplace_back
(
new
details
::
color_stop_formatter
());
break
;
default
:
// Unknown flag appears as is
_formatters
.
emplace_back
(
new
details
::
ch_formatter
(
'%'
));
_formatters
.
emplace_back
(
new
details
::
ch_formatter
(
flag
));
...
...
include/spdlog/sinks/ansicolor_sink.h
View file @
84c7f927
...
...
@@ -28,9 +28,9 @@ public:
:
target_file_
(
file
)
{
should_do_colors_
=
details
::
os
::
in_terminal
(
file
)
&&
details
::
os
::
is_color_terminal
();
colors_
[
level
::
trace
]
=
cyan
;
colors_
[
level
::
trace
]
=
white
;
colors_
[
level
::
debug
]
=
cyan
;
colors_
[
level
::
info
]
=
reset
;
colors_
[
level
::
info
]
=
green
;
colors_
[
level
::
warn
]
=
yellow
+
bold
;
colors_
[
level
::
err
]
=
red
+
bold
;
colors_
[
level
::
critical
]
=
bold
+
on_red
;
...
...
@@ -83,17 +83,20 @@ protected:
{
// Wrap the originally formatted message in color codes.
// If color is not supported in the terminal, log as is instead.
if
(
should_do_colors_
)
if
(
should_do_colors_
&&
msg
.
color_range_end
>
msg
.
color_range_start
)
{
const
std
::
string
&
prefix
=
colors_
[
msg
.
level
];
fwrite
(
prefix
.
data
(),
sizeof
(
char
),
prefix
.
size
(),
target_file_
);
fwrite
(
msg
.
formatted
.
data
(),
sizeof
(
char
),
msg
.
formatted
.
size
(),
target_file_
);
fwrite
(
reset
.
data
(),
sizeof
(
char
),
reset
.
size
(),
target_file_
);
fwrite
(
clear_line
.
data
(),
sizeof
(
char
),
clear_line
.
size
(),
target_file_
);
// before color range
_print_range
(
msg
,
0
,
msg
.
color_range_start
);
// in color range
_print_ccode
(
colors_
[
msg
.
level
]);
_print_range
(
msg
,
msg
.
color_range_start
,
msg
.
color_range_end
);
_print_ccode
(
reset
);
// after color range
_print_range
(
msg
,
msg
.
color_range_end
,
msg
.
formatted
.
size
());
}
else
{
fwrite
(
msg
.
formatted
.
data
(),
sizeof
(
char
),
msg
.
formatted
.
size
(),
target_file_
);
_print_range
(
msg
,
0
,
msg
.
formatted
.
size
()
);
}
_flush
();
}
...
...
@@ -103,6 +106,15 @@ protected:
fflush
(
target_file_
);
}
private
:
void
_print_ccode
(
const
std
::
string
&
color_code
)
{
fwrite
(
color_code
.
data
(),
sizeof
(
char
),
color_code
.
size
(),
target_file_
);
}
void
_print_range
(
const
details
::
log_msg
&
msg
,
size_t
start
,
size_t
end
)
{
fwrite
(
msg
.
formatted
.
data
()
+
start
,
sizeof
(
char
),
end
-
start
,
target_file_
);
}
FILE
*
target_file_
;
bool
should_do_colors_
;
std
::
unordered_map
<
level
::
level_enum
,
std
::
string
,
level
::
level_hasher
>
colors_
;
...
...
include/spdlog/sinks/wincolor_sink.h
View file @
84c7f927
...
...
@@ -25,6 +25,7 @@ class wincolor_sink : public base_sink<Mutex>
public
:
const
WORD
BOLD
=
FOREGROUND_INTENSITY
;
const
WORD
RED
=
FOREGROUND_RED
;
const
WORD
GREEN
=
FOREGROUND_GREEN
;
const
WORD
CYAN
=
FOREGROUND_GREEN
|
FOREGROUND_BLUE
;
const
WORD
WHITE
=
FOREGROUND_RED
|
FOREGROUND_GREEN
|
FOREGROUND_BLUE
;
const
WORD
YELLOW
=
FOREGROUND_RED
|
FOREGROUND_GREEN
;
...
...
@@ -32,9 +33,9 @@ public:
wincolor_sink
(
HANDLE
std_handle
)
:
out_handle_
(
std_handle
)
{
colors_
[
level
::
trace
]
=
CYAN
;
colors_
[
level
::
trace
]
=
WHITE
;
colors_
[
level
::
debug
]
=
CYAN
;
colors_
[
level
::
info
]
=
WHITE
|
BOLD
;
colors_
[
level
::
info
]
=
GREEN
;
colors_
[
level
::
warn
]
=
YELLOW
|
BOLD
;
colors_
[
level
::
err
]
=
RED
|
BOLD
;
// red bold
colors_
[
level
::
critical
]
=
BACKGROUND_RED
|
WHITE
|
BOLD
;
// white bold on red background
...
...
@@ -59,10 +60,22 @@ public:
protected
:
void
_sink_it
(
const
details
::
log_msg
&
msg
)
override
{
auto
color
=
colors_
[
msg
.
level
];
auto
orig_attribs
=
set_console_attribs
(
color
);
WriteConsoleA
(
out_handle_
,
msg
.
formatted
.
data
(),
static_cast
<
DWORD
>
(
msg
.
formatted
.
size
()),
nullptr
,
nullptr
);
SetConsoleTextAttribute
(
out_handle_
,
orig_attribs
);
// reset to orig colors
if
(
msg
.
color_range_end
>
msg
.
color_range_start
)
{
// before color range
_print_range
(
msg
,
0
,
msg
.
color_range_start
);
// in color range
auto
orig_attribs
=
set_console_attribs
(
colors_
[
msg
.
level
]);
_print_range
(
msg
,
msg
.
color_range_start
,
msg
.
color_range_end
);
::
SetConsoleTextAttribute
(
out_handle_
,
orig_attribs
);
// reset to orig colors
// after color range
_print_range
(
msg
,
msg
.
color_range_end
,
msg
.
formatted
.
size
());
}
else
// print without colors if color range is invalid
{
_print_range
(
msg
,
0
,
msg
.
formatted
.
size
());
}
}
void
_flush
()
override
...
...
@@ -86,6 +99,13 @@ private:
SetConsoleTextAttribute
(
out_handle_
,
attribs
|
back_color
);
return
orig_buffer_info
.
wAttributes
;
// return orig attribs
}
// print a range of formatted message to console
void
_print_range
(
const
details
::
log_msg
&
msg
,
size_t
start
,
size_t
end
)
{
DWORD
size
=
static_cast
<
DWORD
>
(
end
-
start
);
WriteConsoleA
(
out_handle_
,
msg
.
formatted
.
data
()
+
start
,
size
,
nullptr
,
nullptr
);
}
};
//
...
...
tests/test_pattern_formatter.cpp
View file @
84c7f927
...
...
@@ -7,8 +7,10 @@ static std::string log_to_str(const std::string &msg, const std::shared_ptr<spdl
auto
oss_sink
=
std
::
make_shared
<
spdlog
::
sinks
::
ostream_sink_mt
>
(
oss
);
spdlog
::
logger
oss_logger
(
"pattern_tester"
,
oss_sink
);
oss_logger
.
set_level
(
spdlog
::
level
::
info
);
if
(
formatter
)
oss_logger
.
set_formatter
(
formatter
);
if
(
formatter
)
{
oss_logger
.
set_formatter
(
formatter
);
}
oss_logger
.
info
(
msg
);
return
oss
.
str
();
}
...
...
@@ -61,3 +63,62 @@ TEST_CASE("date MM/DD/YY ", "[pattern_formatter]")
<<
(
now_tm
.
tm_year
+
1900
)
%
1000
<<
" Some message
\n
"
;
REQUIRE
(
log_to_str
(
"Some message"
,
formatter
)
==
oss
.
str
());
}
TEST_CASE
(
"color range test1"
,
"[pattern_formatter]"
)
{
auto
formatter
=
std
::
make_shared
<
spdlog
::
pattern_formatter
>
(
"%^%v%$"
,
spdlog
::
pattern_time_type
::
local
,
"
\n
"
);
spdlog
::
details
::
log_msg
msg
;
msg
.
raw
<<
"Hello"
;
formatter
->
format
(
msg
);
REQUIRE
(
msg
.
color_range_start
==
0
);
REQUIRE
(
msg
.
color_range_end
==
5
);
REQUIRE
(
log_to_str
(
"hello"
,
formatter
)
==
"hello
\n
"
);
}
TEST_CASE
(
"color range test2"
,
"[pattern_formatter]"
)
{
auto
formatter
=
std
::
make_shared
<
spdlog
::
pattern_formatter
>
(
"%^%$"
,
spdlog
::
pattern_time_type
::
local
,
"
\n
"
);
spdlog
::
details
::
log_msg
msg
;
formatter
->
format
(
msg
);
REQUIRE
(
msg
.
color_range_start
==
0
);
REQUIRE
(
msg
.
color_range_end
==
0
);
REQUIRE
(
log_to_str
(
""
,
formatter
)
==
"
\n
"
);
}
TEST_CASE
(
"color range test3"
,
"[pattern_formatter]"
)
{
auto
formatter
=
std
::
make_shared
<
spdlog
::
pattern_formatter
>
(
"%^***%$"
);
spdlog
::
details
::
log_msg
msg
;
formatter
->
format
(
msg
);
REQUIRE
(
msg
.
color_range_start
==
0
);
REQUIRE
(
msg
.
color_range_end
==
3
);
}
TEST_CASE
(
"color range test4"
,
"[pattern_formatter]"
)
{
auto
formatter
=
std
::
make_shared
<
spdlog
::
pattern_formatter
>
(
"XX%^YYY%$"
,
spdlog
::
pattern_time_type
::
local
,
"
\n
"
);
spdlog
::
details
::
log_msg
msg
;
msg
.
raw
<<
"ignored"
;
formatter
->
format
(
msg
);
REQUIRE
(
msg
.
color_range_start
==
2
);
REQUIRE
(
msg
.
color_range_end
==
5
);
REQUIRE
(
log_to_str
(
"ignored"
,
formatter
)
==
"XXYYY
\n
"
);
}
TEST_CASE
(
"color range test5"
,
"[pattern_formatter]"
)
{
auto
formatter
=
std
::
make_shared
<
spdlog
::
pattern_formatter
>
(
"**%^"
);
spdlog
::
details
::
log_msg
msg
;
formatter
->
format
(
msg
);
REQUIRE
(
msg
.
color_range_start
==
2
);
REQUIRE
(
msg
.
color_range_end
==
0
);
}
TEST_CASE
(
"color range test6"
,
"[pattern_formatter]"
)
{
auto
formatter
=
std
::
make_shared
<
spdlog
::
pattern_formatter
>
(
"**%$"
);
spdlog
::
details
::
log_msg
msg
;
formatter
->
format
(
msg
);
REQUIRE
(
msg
.
color_range_start
==
0
);
REQUIRE
(
msg
.
color_range_end
==
2
);
}
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