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
0cfdad4d
Commit
0cfdad4d
authored
Oct 12, 2016
by
gabime
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Windows console color support. Replaced color param in API with new functions
parent
94dbefe9
Changes
7
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
369 additions
and
179 deletions
+369
-179
README.md
README.md
+81
-75
example/example.cpp
example/example.cpp
+14
-14
example/example.vcxproj
example/example.vcxproj
+1
-0
include/spdlog/details/spdlog_impl.h
include/spdlog/details/spdlog_impl.h
+95
-37
include/spdlog/sinks/stdout_sinks.h
include/spdlog/sinks/stdout_sinks.h
+51
-49
include/spdlog/sinks/wincolor_sink.h
include/spdlog/sinks/wincolor_sink.h
+116
-0
include/spdlog/spdlog.h
include/spdlog/spdlog.h
+11
-4
No files found.
README.md
View file @
0cfdad4d
...
...
@@ -70,81 +70,87 @@ void user_defined_example();
void
err_handler_example
();
namespace
spd
=
spdlog
;
int
main
(
int
,
char
*
[])
{
try
{
// Multithreaded color console
auto
console
=
spd
::
stdout_logger_mt
(
"console"
,
true
);
console
->
info
(
"Welcome to spdlog!"
);
console
->
info
(
"An info message example {}.."
,
1
);
// Formatting examples
console
->
warn
(
"Easy padding in numbers like {:08d}"
,
12
);
console
->
critical
(
"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"
);
spd
::
get
(
"console"
)
->
info
(
"loggers can be retrieved from a global registry using the spdlog::get(logger_name) function"
);
// Runtime log levels
spd
::
set_level
(
spd
::
level
::
info
);
//Set global log level to info
console
->
debug
(
"This message shold not be displayed!"
);
console
->
set_level
(
spd
::
level
::
debug
);
// Set specific logger's log level
console
->
debug
(
"This message shold be displayed.."
);
// Create basic file logger (not rotated)
auto
my_logger
=
spd
::
basic_logger_mt
(
"basic_logger"
,
"logs/basic.txt"
);
my_logger
->
info
(
"Some log message"
);
// Create a file rotating logger with 5mb size max and 3 rotated files
auto
rotating_logger
=
spd
::
rotating_logger_mt
(
"some_logger_name"
,
"logs/mylogfile"
,
1048576
*
5
,
3
);
for
(
int
i
=
0
;
i
<
10
;
++
i
)
rotating_logger
->
info
(
"{} * {} equals {:>10}"
,
i
,
i
,
i
*
i
);
// Create a daily logger - a new file is created every day on 2:30am
auto
daily_logger
=
spd
::
daily_logger_mt
(
"daily_logger"
,
"logs/daily"
,
2
,
30
);
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"
);
// Compile time debug or trace macros.
// Enabled #ifdef SPDLOG_DEBUG_ON or #ifdef SPDLOG_TRACE_ON
SPDLOG_TRACE
(
console
,
"Enabled only #ifdef SPDLOG_TRACE_ON..{} ,{}"
,
1
,
3.23
);
SPDLOG_DEBUG
(
console
,
"Enabled only #ifdef SPDLOG_DEBUG_ON.. {} ,{}"
,
1
,
3.23
);
// Asynchronous logging is very fast..
// Just call spdlog::set_async_mode(q_size) and all created loggers from now on will be asynchronous..
async_example
();
// syslog example. linux/osx only..
syslog_example
();
// Log user-defined types example..
user_defined_example
();
// Change default log error handler
err_handler_example
();
// Apply a function on all registered loggers
spd
::
apply_all
([
&
](
std
::
shared_ptr
<
spdlog
::
logger
>
l
)
{
l
->
info
(
"End of example."
);
});
// Release and close all loggers
spdlog
::
drop_all
();
}
// Exceptions will only be thrown upon failed logger or sink construction (not during logging)
catch
(
const
spd
::
spdlog_ex
&
ex
)
{
std
::
cout
<<
"Log init failed: "
<<
ex
.
what
()
<<
std
::
endl
;
return
1
;
}
int
main
(
int
,
char
*
[])
{
try
{
// Console logger with color
auto
console
=
spd
::
stdout_color_mt
(
"console"
);
console
->
info
(
"Welcome to spdlog!"
);
console
->
error
(
"Some error message with arg{}.."
,
1
);
// Formatting examples
console
->
warn
(
"Easy padding in numbers like {:08d}"
,
12
);
console
->
critical
(
"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"
);
spd
::
get
(
"console"
)
->
info
(
"loggers can be retrieved from a global registry using the spdlog::get(logger_name) function"
);
// Create basic file logger (not rotated)
auto
my_logger
=
spd
::
basic_logger_mt
(
"basic_logger"
,
"logs/basic.txt"
);
my_logger
->
info
(
"Some log message"
);
// Create a file rotating logger with 5mb size max and 3 rotated files
auto
rotating_logger
=
spd
::
rotating_logger_mt
(
"some_logger_name"
,
"logs/mylogfile"
,
1048576
*
5
,
3
);
for
(
int
i
=
0
;
i
<
10
;
++
i
)
rotating_logger
->
info
(
"{} * {} equals {:>10}"
,
i
,
i
,
i
*
i
);
// Create a daily logger - a new file is created every day on 2:30am
auto
daily_logger
=
spd
::
daily_logger_mt
(
"daily_logger"
,
"logs/daily"
,
2
,
30
);
// trigger flush if the log severity is error or higher
daily_logger
->
flush_on
(
spd
::
level
::
err
);
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"
);
// Runtime log levels
spd
::
set_level
(
spd
::
level
::
info
);
//Set global log level to info
console
->
debug
(
"This message shold not be displayed!"
);
console
->
set_level
(
spd
::
level
::
debug
);
// Set specific logger's log level
console
->
debug
(
"This message shold be displayed.."
);
// Compile time log levels
// define SPDLOG_DEBUG_ON or SPDLOG_TRACE_ON
SPDLOG_TRACE
(
console
,
"Enabled only #ifdef SPDLOG_TRACE_ON..{} ,{}"
,
1
,
3.23
);
SPDLOG_DEBUG
(
console
,
"Enabled only #ifdef SPDLOG_DEBUG_ON.. {} ,{}"
,
1
,
3.23
);
// Asynchronous logging is very fast..
// Just call spdlog::set_async_mode(q_size) and all created loggers from now on will be asynchronous..
async_example
();
// syslog example. linux/osx only
syslog_example
();
// android example. compile with NDK
android_example
();
// Log user-defined types example
user_defined_example
();
// Change default log error handler
err_handler_example
();
// Apply a function on all registered loggers
spd
::
apply_all
([
&
](
std
::
shared_ptr
<
spdlog
::
logger
>
l
)
{
l
->
info
(
"End of example."
);
});
// Release and close all loggers
spdlog
::
drop_all
();
}
// Exceptions will only be thrown upon failed logger or sink construction (not during logging)
catch
(
const
spd
::
spdlog_ex
&
ex
)
{
std
::
cout
<<
"Log init failed: "
<<
ex
.
what
()
<<
std
::
endl
;
return
1
;
}
}
void
async_example
()
...
...
example/example.cpp
View file @
0cfdad4d
...
...
@@ -22,29 +22,22 @@ int main(int, char*[])
{
try
{
// Multithreaded color console
auto
console
=
spd
::
stdout_
logger_mt
(
"console"
,
true
);
// Console logger with color
auto
console
=
spd
::
stdout_
color_mt
(
"console"
);
console
->
info
(
"Welcome to spdlog!"
);
console
->
error
(
"An error message example
{}.."
,
1
);
console
->
error
(
"Some error message with arg
{}.."
,
1
);
// Formatting examples
console
->
warn
(
"Easy padding in numbers like {:08d}"
,
12
);
console
->
critical
(
"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"
);
spd
::
get
(
"console"
)
->
info
(
"loggers can be retrieved from a global registry using the spdlog::get(logger_name) function"
);
// Runtime log levels
spd
::
set_level
(
spd
::
level
::
info
);
//Set global log level to info
console
->
debug
(
"This message shold not be displayed!"
);
console
->
set_level
(
spd
::
level
::
debug
);
// Set specific logger's log level
console
->
debug
(
"This message shold be displayed.."
);
// Create basic file logger (not rotated)
auto
my_logger
=
spd
::
basic_logger_mt
(
"basic_logger"
,
"logs/basic.txt"
);
my_logger
->
info
(
"Some log message"
);
...
...
@@ -64,8 +57,15 @@ int main(int, char*[])
spd
::
set_pattern
(
"*** [%H:%M:%S %z] [thread %t] %v ***"
);
rotating_logger
->
info
(
"This is another message with custom format"
);
// Compile time debug or trace macros.
// Enabled #ifdef SPDLOG_DEBUG_ON or #ifdef SPDLOG_TRACE_ON
// Runtime log levels
spd
::
set_level
(
spd
::
level
::
info
);
//Set global log level to info
console
->
debug
(
"This message shold not be displayed!"
);
console
->
set_level
(
spd
::
level
::
debug
);
// Set specific logger's log level
console
->
debug
(
"This message shold be displayed.."
);
// Compile time log levels
// define SPDLOG_DEBUG_ON or SPDLOG_TRACE_ON
SPDLOG_TRACE
(
console
,
"Enabled only #ifdef SPDLOG_TRACE_ON..{} ,{}"
,
1
,
3.23
);
SPDLOG_DEBUG
(
console
,
"Enabled only #ifdef SPDLOG_DEBUG_ON.. {} ,{}"
,
1
,
3.23
);
...
...
example/example.vcxproj
View file @
0cfdad4d
...
...
@@ -42,6 +42,7 @@
<ClInclude
Include=
"..\include\spdlog\sinks\sink.h"
/>
<ClInclude
Include=
"..\include\spdlog\sinks\stdout_sinks.h"
/>
<ClInclude
Include=
"..\include\spdlog\sinks\syslog_sink.h"
/>
<ClInclude
Include=
"..\include\spdlog\sinks\wincolor_sink.h"
/>
<ClInclude
Include=
"..\include\spdlog\spdlog.h"
/>
<ClInclude
Include=
"..\include\spdlog\tweakme.h"
/>
</ItemGroup>
...
...
include/spdlog/details/spdlog_impl.h
View file @
0cfdad4d
This diff is collapsed.
Click to expand it.
include/spdlog/sinks/stdout_sinks.h
View file @
0cfdad4d
...
...
@@ -14,62 +14,64 @@
namespace
spdlog
{
namespace
sinks
{
namespace
sinks
{
template
<
class
Mutex
>
class
stdout_sink
:
public
base_sink
<
Mutex
>
{
using
MyType
=
stdout_sink
<
Mutex
>
;
public:
stdout_sink
()
{}
static
std
::
shared_ptr
<
MyType
>
instance
()
{
static
std
::
shared_ptr
<
MyType
>
instance
=
std
::
make_shared
<
MyType
>
();
return
instance
;
}
template
<
class
Mutex
>
class
stdout_sink
:
public
base_sink
<
Mutex
>
{
using
MyType
=
stdout_sink
<
Mutex
>
;
public:
stdout_sink
()
{}
static
std
::
shared_ptr
<
MyType
>
instance
()
{
static
std
::
shared_ptr
<
MyType
>
instance
=
std
::
make_shared
<
MyType
>
();
return
instance
;
}
void
_sink_it
(
const
details
::
log_msg
&
msg
)
override
{
fwrite
(
msg
.
formatted
.
data
(),
sizeof
(
char
),
msg
.
formatted
.
size
(),
stdout
);
flush
();
}
void
_sink_it
(
const
details
::
log_msg
&
msg
)
override
{
fwrite
(
msg
.
formatted
.
data
(),
sizeof
(
char
),
msg
.
formatted
.
size
(),
stdout
);
flush
();
}
void
flush
()
override
{
fflush
(
stdout
);
}
};
void
flush
()
override
{
fflush
(
stdout
);
}
};
typedef
stdout_sink
<
details
::
null_mutex
>
stdout_sink_st
;
typedef
stdout_sink
<
std
::
mutex
>
stdout_sink_mt
;
typedef
stdout_sink
<
details
::
null_mutex
>
stdout_sink_st
;
typedef
stdout_sink
<
std
::
mutex
>
stdout_sink_mt
;
template
<
class
Mutex
>
class
stderr_sink
:
public
base_sink
<
Mutex
>
{
using
MyType
=
stderr_sink
<
Mutex
>
;
public:
stderr_sink
()
{}
static
std
::
shared_ptr
<
MyType
>
instance
()
{
static
std
::
shared_ptr
<
MyType
>
instance
=
std
::
make_shared
<
MyType
>
();
return
instance
;
}
template
<
class
Mutex
>
class
stderr_sink
:
public
base_sink
<
Mutex
>
{
using
MyType
=
stderr_sink
<
Mutex
>
;
public:
stderr_sink
()
{}
static
std
::
shared_ptr
<
MyType
>
instance
()
{
static
std
::
shared_ptr
<
MyType
>
instance
=
std
::
make_shared
<
MyType
>
();
return
instance
;
}
void
_sink_it
(
const
details
::
log_msg
&
msg
)
override
{
fwrite
(
msg
.
formatted
.
data
(),
sizeof
(
char
),
msg
.
formatted
.
size
(),
stderr
);
flush
();
}
void
_sink_it
(
const
details
::
log_msg
&
msg
)
override
{
fwrite
(
msg
.
formatted
.
data
(),
sizeof
(
char
),
msg
.
formatted
.
size
(),
stderr
);
flush
();
}
void
flush
()
override
{
fflush
(
stderr
);
}
};
void
flush
()
override
{
fflush
(
stderr
);
}
};
typedef
stderr_sink
<
std
::
mutex
>
stderr_sink_mt
;
typedef
stderr_sink
<
details
::
null_mutex
>
stderr_sink_st
;
}
typedef
stderr_sink
<
std
::
mutex
>
stderr_sink_mt
;
typedef
stderr_sink
<
details
::
null_mutex
>
stderr_sink_st
;
}
}
include/spdlog/sinks/wincolor_sink.h
0 → 100644
View file @
0cfdad4d
//
// Copyright(c) 2016 spdlog
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
//
#pragma once
#include <spdlog/sinks/base_sink.h>
#include <spdlog/details/null_mutex.h>
#include <spdlog/common.h>
#include <mutex>
#include <string>
#include <map>
#include <wincon.h>
namespace
spdlog
{
namespace
sinks
{
/*
* Windows color console sink. Uses WriteConsoleA to write to the console with colors
*/
template
<
class
Mutex
>
class
wincolor_sink
:
public
base_sink
<
Mutex
>
{
public:
const
WORD
BOLD
=
FOREGROUND_INTENSITY
;
const
WORD
RED
=
FOREGROUND_RED
;
const
WORD
CYAN
=
FOREGROUND_GREEN
|
FOREGROUND_BLUE
;
const
WORD
WHITE
=
FOREGROUND_RED
|
FOREGROUND_GREEN
|
FOREGROUND_BLUE
;
const
WORD
YELLOW
=
FOREGROUND_RED
|
FOREGROUND_GREEN
;
wincolor_sink
(
HANDLE
std_handle
)
:
out_handle_
(
std_handle
)
{
colors_
[
level
::
trace
]
=
CYAN
;
colors_
[
level
::
debug
]
=
CYAN
;
colors_
[
level
::
info
]
=
WHITE
|
BOLD
;
colors_
[
level
::
warn
]
=
YELLOW
|
BOLD
;
colors_
[
level
::
err
]
=
RED
|
BOLD
;
// red bold
colors_
[
level
::
critical
]
=
BACKGROUND_RED
|
WHITE
|
BOLD
;
// white bold on red background
colors_
[
level
::
off
]
=
0
;
}
virtual
~
wincolor_sink
()
{
flush
();
}
wincolor_sink
(
const
wincolor_sink
&
other
)
=
delete
;
wincolor_sink
&
operator
=
(
const
wincolor_sink
&
other
)
=
delete
;
virtual
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
(),
msg
.
formatted
.
size
(),
nullptr
,
nullptr
);
SetConsoleTextAttribute
(
out_handle_
,
orig_attribs
);
//reset to orig colors
}
virtual
void
flush
()
override
{
// windows console always flushed?
}
// change the color for the given level
void
set_color
(
level
::
level_enum
level
,
WORD
color
)
{
std
::
lock_guard
<
Mutex
>
lock
(
_mutex
);
colors_
[
level
]
=
color
;
}
private:
HANDLE
out_handle_
;
std
::
map
<
level
::
level_enum
,
WORD
>
colors_
;
// set color and return the orig console attributes (for resetting later)
WORD
set_console_attribs
(
WORD
attribs
)
{
CONSOLE_SCREEN_BUFFER_INFO
orig_buffer_info
;
GetConsoleScreenBufferInfo
(
out_handle_
,
&
orig_buffer_info
);
SetConsoleTextAttribute
(
out_handle_
,
attribs
);
return
orig_buffer_info
.
wAttributes
;
//return orig attribs
}
};
//
// windows color console to stdout
//
template
<
class
Mutex
>
class
wincolor_stdout_sink
:
public
wincolor_sink
<
Mutex
>
{
public:
wincolor_stdout_sink
()
:
wincolor_sink
(
GetStdHandle
(
STD_OUTPUT_HANDLE
))
{}
};
typedef
wincolor_stdout_sink
<
std
::
mutex
>
wincolor_stdout_sink_mt
;
typedef
wincolor_stdout_sink
<
details
::
null_mutex
>
wincolor_stdout_sink_st
;
//
// windows color console to stderr
//
template
<
class
Mutex
>
class
wincolor_stderr_sink
:
public
wincolor_sink
<
Mutex
>
{
public:
wincolor_stderr_sink
()
:
wincolor_sink
(
GetStdHandle
(
STD_ERROR_HANDLE
))
{}
};
typedef
wincolor_stderr_sink
<
std
::
mutex
>
wincolor_stderr_sink_mt
;
typedef
wincolor_stderr_sink
<
details
::
null_mutex
>
wincolor_stderr_sink_st
;
}
}
\ No newline at end of file
include/spdlog/spdlog.h
View file @
0cfdad4d
...
...
@@ -88,10 +88,17 @@ std::shared_ptr<logger> daily_logger_st(const std::string& logger_name, const fi
//
// Create and register stdout/stderr loggers
//
std
::
shared_ptr
<
logger
>
stdout_logger_mt
(
const
std
::
string
&
logger_name
,
bool
color
=
false
);
std
::
shared_ptr
<
logger
>
stdout_logger_st
(
const
std
::
string
&
logger_name
,
bool
color
=
false
);
std
::
shared_ptr
<
logger
>
stderr_logger_mt
(
const
std
::
string
&
logger_name
,
bool
color
=
false
);
std
::
shared_ptr
<
logger
>
stderr_logger_st
(
const
std
::
string
&
logger_name
,
bool
color
=
false
);
std
::
shared_ptr
<
logger
>
stdout_logger_mt
(
const
std
::
string
&
logger_name
);
std
::
shared_ptr
<
logger
>
stdout_logger_st
(
const
std
::
string
&
logger_name
);
std
::
shared_ptr
<
logger
>
stderr_logger_mt
(
const
std
::
string
&
logger_name
);
std
::
shared_ptr
<
logger
>
stderr_logger_st
(
const
std
::
string
&
logger_name
);
//
// Create and register colored stdout/stderr loggers
//
std
::
shared_ptr
<
logger
>
stdout_color_mt
(
const
std
::
string
&
logger_name
);
std
::
shared_ptr
<
logger
>
stdout_color_st
(
const
std
::
string
&
logger_name
);
std
::
shared_ptr
<
logger
>
stderr_color_mt
(
const
std
::
string
&
logger_name
);
std
::
shared_ptr
<
logger
>
stderr_color_st
(
const
std
::
string
&
logger_name
);
//
...
...
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