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
dfe57cdc
Commit
dfe57cdc
authored
May 02, 2020
by
Gabi Melman
Committed by
gabime
May 02, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
initial commit
parent
75c15e80
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
48 additions
and
252 deletions
+48
-252
example/example.cpp
example/example.cpp
+8
-248
include/spdlog/common.h
include/spdlog/common.h
+8
-0
include/spdlog/details/file_helper-inl.h
include/spdlog/details/file_helper-inl.h
+18
-0
include/spdlog/details/file_helper.h
include/spdlog/details/file_helper.h
+3
-1
include/spdlog/sinks/basic_file_sink-inl.h
include/spdlog/sinks/basic_file_sink-inl.h
+8
-1
include/spdlog/sinks/basic_file_sink.h
include/spdlog/sinks/basic_file_sink.h
+3
-2
No files found.
example/example.cpp
View file @
dfe57cdc
...
...
@@ -23,260 +23,20 @@ void custom_flags_example();
#include "spdlog/spdlog.h"
#include "spdlog/cfg/env.h" // for loading levels from the environment variable
int
main
(
int
,
char
*
[])
{
// Log levels can be loaded from argv/env using "SPDLOG_LEVEL"
load_levels_example
();
spdlog
::
info
(
"Welcome to spdlog version {}.{}.{} !"
,
SPDLOG_VER_MAJOR
,
SPDLOG_VER_MINOR
,
SPDLOG_VER_PATCH
);
spdlog
::
warn
(
"Easy padding in numbers like {:08d}"
,
12
);
spdlog
::
critical
(
"Support for int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}"
,
42
);
spdlog
::
info
(
"Support for floats {:03.2f}"
,
1.23456
);
spdlog
::
info
(
"Positional args are {1} {0}.."
,
"too"
,
"supported"
);
spdlog
::
info
(
"{:>8} aligned, {:<8} aligned"
,
"right"
,
"left"
);
// Runtime log levels
spdlog
::
set_level
(
spdlog
::
level
::
info
);
// Set global log level to info
spdlog
::
debug
(
"This message should not be displayed!"
);
spdlog
::
set_level
(
spdlog
::
level
::
trace
);
// Set specific logger's log level
spdlog
::
debug
(
"This message should be displayed.."
);
// Customize msg format for all loggers
spdlog
::
set_pattern
(
"[%H:%M:%S %z] [%^%L%$] [thread %t] %v"
);
spdlog
::
info
(
"This an info message with custom format"
);
spdlog
::
set_pattern
(
"%+"
);
// back to default format
spdlog
::
set_level
(
spdlog
::
level
::
info
);
// Backtrace support
// Loggers can store in a ring buffer all messages (including debug/trace) for later inspection.
// When needed, call dump_backtrace() to see what happened:
spdlog
::
enable_backtrace
(
10
);
// create ring buffer with capacity of 10 messages
for
(
int
i
=
0
;
i
<
100
;
i
++
)
{
spdlog
::
debug
(
"Backtrace message {}"
,
i
);
// not logged..
}
// e.g. if some error happened:
spdlog
::
dump_backtrace
();
// log them now!
try
{
stdout_logger_example
();
basic_example
();
rotating_example
();
daily_example
();
async_example
();
binary_example
();
multi_sink_example
();
user_defined_example
();
err_handler_example
();
trace_example
();
custom_flags_example
();
// Flush all *registered* loggers using a worker thread every 3 seconds.
// note: registered loggers *must* be thread safe for this to work correctly!
spdlog
::
flush_every
(
std
::
chrono
::
seconds
(
3
));
// Apply some function on all registered loggers
spdlog
::
apply_all
([
&
](
std
::
shared_ptr
<
spdlog
::
logger
>
l
)
{
l
->
info
(
"End of example."
);
});
// Release all spdlog resources, and drop all loggers in the registry.
// This is optional (only mandatory if using windows + async log).
spdlog
::
shutdown
();
}
// Exceptions will only be thrown upon failed logger or sink construction (not during logging).
catch
(
const
spdlog
::
spdlog_ex
&
ex
)
{
std
::
printf
(
"Log initialization failed: %s
\n
"
,
ex
.
what
());
return
1
;
}
}
#include "spdlog/sinks/stdout_color_sinks.h"
// or #include "spdlog/sinks/stdout_sinks.h" if no colors needed.
void
stdout_logger_example
()
{
// Create color multi threaded logger.
auto
console
=
spdlog
::
stdout_color_mt
(
"console"
);
// or for stderr:
// auto console = spdlog::stderr_color_mt("error-logger");
}
#include "spdlog/sinks/basic_file_sink.h"
void
basic_example
()
{
// Create basic file logger (not rotated).
auto
my_logger
=
spdlog
::
basic_logger_mt
(
"file_logger"
,
"logs/basic-log.txt"
);
}
#include "spdlog/sinks/rotating_file_sink.h"
void
rotating_example
()
{
// Create a file rotating logger with 5mb size max and 3 rotated files.
auto
rotating_logger
=
spdlog
::
rotating_logger_mt
(
"some_logger_name"
,
"logs/rotating.txt"
,
1048576
*
5
,
3
);
}
#include "spdlog/sinks/daily_file_sink.h"
void
daily_example
()
{
// Create a daily logger - a new file is created every day on 2:30am.
auto
daily_logger
=
spdlog
::
daily_logger_mt
(
"daily_logger"
,
"logs/daily.txt"
,
2
,
30
);
}
#include "spdlog/cfg/env.h"
void
load_levels_example
()
{
// Set the log level to "info" and mylogger to to "trace":
// SPDLOG_LEVEL=info,mylogger=trace && ./example
spdlog
::
cfg
::
load_env_levels
();
// or from command line:
// ./example SPDLOG_LEVEL=info,mylogger=trace
// #include "spdlog/cfg/argv.h" // for loading levels from argv
// spdlog::cfg::load_argv_levels(args, argv);
}
#include "spdlog/async.h"
void
async_example
()
{
// Default thread pool settings can be modified *before* creating the async logger:
// spdlog::init_thread_pool(32768, 1); // queue with max 32k items 1 backing thread.
auto
async_file
=
spdlog
::
basic_logger_mt
<
spdlog
::
async_factory
>
(
"async_file_logger"
,
"logs/async_log.txt"
);
// alternatively:
// auto async_file = spdlog::create_async<spdlog::sinks::basic_file_sink_mt>("async_file_logger", "logs/async_log.txt");
for
(
int
i
=
1
;
i
<
101
;
++
i
)
{
async_file
->
info
(
"Async message #{}"
,
i
);
}
}
// Log binary data as hex.
// Many types of std::container<char> types can be used.
// Iterator ranges are supported too.
// Format flags:
// {:X} - print in uppercase.
// {:s} - don't separate each byte with space.
// {:p} - don't print the position on each line start.
// {:n} - don't split the output to lines.
#include "spdlog/fmt/bin_to_hex.h"
void
binary_example
()
{
std
::
vector
<
char
>
buf
(
80
);
for
(
int
i
=
0
;
i
<
80
;
i
++
)
{
buf
.
push_back
(
static_cast
<
char
>
(
i
&
0xff
));
}
spdlog
::
info
(
"Binary example: {}"
,
spdlog
::
to_hex
(
buf
));
spdlog
::
info
(
"Another binary example:{:n}"
,
spdlog
::
to_hex
(
std
::
begin
(
buf
),
std
::
begin
(
buf
)
+
10
));
// more examples:
// logger->info("uppercase: {:X}", spdlog::to_hex(buf));
// logger->info("uppercase, no delimiters: {:Xs}", spdlog::to_hex(buf));
// logger->info("uppercase, no delimiters, no position info: {:Xsp}", spdlog::to_hex(buf));
// logger->info("hexdump style: {:a}", spdlog::to_hex(buf));
// logger->info("hexdump style, 20 chars per line {:a}", spdlog::to_hex(buf, 20));
}
// Compile time log levels.
// define SPDLOG_ACTIVE_LEVEL to required level (e.g. SPDLOG_LEVEL_TRACE)
void
trace_example
()
{
// trace from default logger
SPDLOG_TRACE
(
"Some trace message.. {} ,{}"
,
1
,
3.23
);
// debug from default logger
SPDLOG_DEBUG
(
"Some debug message.. {} ,{}"
,
1
,
3.23
);
// trace from logger object
auto
logger
=
spdlog
::
get
(
"file_logger"
);
SPDLOG_LOGGER_TRACE
(
logger
,
"another trace message"
);
}
// A logger with multiple sinks (stdout and file) - each with a different format and log level.
void
multi_sink_example
()
{
auto
console_sink
=
std
::
make_shared
<
spdlog
::
sinks
::
stdout_color_sink_mt
>
();
console_sink
->
set_level
(
spdlog
::
level
::
warn
);
console_sink
->
set_pattern
(
"[multi_sink_example] [%^%l%$] %v"
);
auto
file_sink
=
std
::
make_shared
<
spdlog
::
sinks
::
basic_file_sink_mt
>
(
"logs/multisink.txt"
,
true
);
file_sink
->
set_level
(
spdlog
::
level
::
trace
);
spdlog
::
logger
logger
(
"multi_sink"
,
{
console_sink
,
file_sink
});
logger
.
set_level
(
spdlog
::
level
::
debug
);
logger
.
warn
(
"this should appear in both console and file"
);
logger
.
info
(
"this message should not appear in the console, only in the file"
);
}
// User defined types logging by implementing operator<<
#include "spdlog/fmt/ostr.h" // must be included
struct
my_type
{
int
i
;
template
<
typename
OStream
>
friend
OStream
&
operator
<<
(
OStream
&
os
,
const
my_type
&
c
)
spdlog
::
file_event_handlers
handlers
;
handlers
.
after_open
=
[](
spdlog
::
filename_t
,
std
::
FILE
*
fstream
)
{
return
os
<<
"[my_type i="
<<
c
.
i
<<
"]"
;
}
};
void
user_defined_example
()
{
spdlog
::
info
(
"user defined type: {}"
,
my_type
{
14
});
fputs
(
"OPEN!
\r\n
"
,
fstream
);
};
auto
fsink
=
std
::
make_shared
<
spdlog
::
sinks
::
basic_file_sink_mt
>
(
"c:
\\
temp
\\
test.log"
,
true
,
handlers
);
}
// Custom error handler. Will be triggered on log failure.
void
err_handler_example
()
{
// can be set globally or per logger(logger->set_error_handler(..))
spdlog
::
set_error_handler
([](
const
std
::
string
&
msg
)
{
printf
(
"*** Custom log error handler: %s ***
\n
"
,
msg
.
c_str
());
});
}
// syslog example (linux/osx/freebsd)
#ifndef _WIN32
#include "spdlog/sinks/syslog_sink.h"
void
syslog_example
()
{
std
::
string
ident
=
"spdlog-example"
;
auto
syslog_logger
=
spdlog
::
syslog_logger_mt
(
"syslog"
,
ident
,
LOG_PID
);
syslog_logger
->
warn
(
"This is warning that will end up in syslog."
);
}
#endif
// Android example.
#if defined(__ANDROID__)
#include "spdlog/sinks/android_sink.h"
void
android_example
()
{
std
::
string
tag
=
"spdlog-android"
;
auto
android_logger
=
spdlog
::
android_logger_mt
(
"android"
,
tag
);
android_logger
->
critical
(
"Use
\"
adb shell logcat
\"
to view this message."
);
}
#endif
// Log patterns can contain custom flags.
// this will add custom flag '%*' which will be bound to a <my_formatter_flag> instance
#include "spdlog/pattern_formatter.h"
class
my_formatter_flag
:
public
spdlog
::
custom_flag_formatter
{
public:
void
format
(
const
spdlog
::
details
::
log_msg
&
,
const
std
::
tm
&
,
spdlog
::
memory_buf_t
&
dest
)
override
{
std
::
string
some_txt
=
"custom-flag"
;
dest
.
append
(
some_txt
.
data
(),
some_txt
.
data
()
+
some_txt
.
size
());
}
std
::
unique_ptr
<
custom_flag_formatter
>
clone
()
const
override
{
return
spdlog
::
details
::
make_unique
<
my_formatter_flag
>
();
}
};
void
custom_flags_example
()
int
main
(
int
,
char
*
[])
{
using
spdlog
::
details
::
make_unique
;
// for pre c++14
auto
formatter
=
make_unique
<
spdlog
::
pattern_formatter
>
();
formatter
->
add_flag
<
my_formatter_flag
>
(
'*'
).
set_pattern
(
"[%n] [%*] [%^%l%$] %v"
);
spdlog
::
set_formatter
(
std
::
move
(
formatter
));
basic_example
();
}
\ No newline at end of file
include/spdlog/common.h
View file @
dfe57cdc
...
...
@@ -14,6 +14,7 @@
#include <string>
#include <type_traits>
#include <functional>
#include <cstdio>
#ifdef SPDLOG_COMPILED_LIB
#undef SPDLOG_HEADER_ONLY
...
...
@@ -225,6 +226,13 @@ struct source_loc
const
char
*
funcname
{
nullptr
};
};
struct
file_event_handlers
{
std
::
function
<
void
(
const
filename_t
&
filename
,
std
::
FILE
*
file_stream
)
>
after_open
;
std
::
function
<
void
(
const
filename_t
&
filename
,
std
::
FILE
*
file_stream
)
>
before_close
;
std
::
function
<
void
(
const
filename_t
&
filename
)
>
after_close
;
};
namespace
details
{
// make_unique support for pre c++14
...
...
include/spdlog/details/file_helper-inl.h
View file @
dfe57cdc
...
...
@@ -20,6 +20,10 @@
namespace
spdlog
{
namespace
details
{
SPDLOG_INLINE
file_helper
::
file_helper
(
file_event_handlers
event_handlers
)
:
event_handlers_
{
std
::
move
(
event_handlers_
)}
{}
SPDLOG_INLINE
file_helper
::~
file_helper
()
{
close
();
...
...
@@ -37,6 +41,10 @@ SPDLOG_INLINE void file_helper::open(const filename_t &fname, bool truncate)
os
::
create_dir
(
os
::
dir_name
(
fname
));
if
(
!
os
::
fopen_s
(
&
fd_
,
fname
,
mode
))
{
if
(
event_handlers_
.
after_open
)
{
event_handlers_
.
after_open
(
filename_
,
fd_
);
}
return
;
}
...
...
@@ -64,8 +72,18 @@ SPDLOG_INLINE void file_helper::close()
{
if
(
fd_
!=
nullptr
)
{
if
(
event_handlers_
.
before_close
)
{
event_handlers_
.
before_close
(
filename_
,
fd_
);
}
std
::
fclose
(
fd_
);
fd_
=
nullptr
;
if
(
event_handlers_
.
after_close
)
{
event_handlers_
.
after_close
(
filename_
);
}
}
}
...
...
include/spdlog/details/file_helper.h
View file @
dfe57cdc
...
...
@@ -16,7 +16,8 @@ namespace details {
class
SPDLOG_API
file_helper
{
public:
explicit
file_helper
()
=
default
;
file_helper
()
=
default
;
explicit
file_helper
(
file_event_handlers
handlers
);
file_helper
(
const
file_helper
&
)
=
delete
;
file_helper
&
operator
=
(
const
file_helper
&
)
=
delete
;
...
...
@@ -50,6 +51,7 @@ private:
const
int
open_interval_
=
10
;
std
::
FILE
*
fd_
{
nullptr
};
filename_t
filename_
;
file_event_handlers
event_handlers_
{};
};
}
// namespace details
}
// namespace spdlog
...
...
include/spdlog/sinks/basic_file_sink-inl.h
View file @
dfe57cdc
...
...
@@ -14,11 +14,18 @@ namespace spdlog {
namespace
sinks
{
template
<
typename
Mutex
>
SPDLOG_INLINE
basic_file_sink
<
Mutex
>::
basic_file_sink
(
const
filename_t
&
filename
,
bool
truncate
)
SPDLOG_INLINE
basic_file_sink
<
Mutex
>::
basic_file_sink
(
const
filename_t
&
filename
,
bool
truncate
,
file_event_handlers
handlers
)
:
file_helper_
{
std
::
move
(
handlers
)}
{
file_helper_
.
open
(
filename
,
truncate
);
}
template
<
typename
Mutex
>
SPDLOG_INLINE
basic_file_sink
<
Mutex
>::
basic_file_sink
(
const
filename_t
&
filename
,
bool
truncate
)
:
basic_file_sink
<
Mutex
>::
basic_file_sink
(
filename
,
truncate
,
file_event_handlers
{})
{}
template
<
typename
Mutex
>
SPDLOG_INLINE
const
filename_t
&
basic_file_sink
<
Mutex
>::
filename
()
const
{
...
...
include/spdlog/sinks/basic_file_sink.h
View file @
dfe57cdc
...
...
@@ -21,6 +21,7 @@ class basic_file_sink final : public base_sink<Mutex>
{
public:
explicit
basic_file_sink
(
const
filename_t
&
filename
,
bool
truncate
=
false
);
explicit
basic_file_sink
(
const
filename_t
&
filename
,
bool
truncate
,
file_event_handlers
);
const
filename_t
&
filename
()
const
;
protected:
...
...
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