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
60f8a68a
Commit
60f8a68a
authored
Apr 29, 2018
by
gabime
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Splitted file sinks to seperate headers
parent
99ca7f1c
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
361 additions
and
6 deletions
+361
-6
example/bench.cpp
example/bench.cpp
+7
-5
example/example.cpp
example/example.cpp
+3
-1
include/spdlog/sinks/file/daily_file_sink.h
include/spdlog/sinks/file/daily_file_sink.h
+139
-0
include/spdlog/sinks/file/rotating_file_sink.h
include/spdlog/sinks/file/rotating_file_sink.h
+134
-0
include/spdlog/sinks/file/simple_file_sink.h
include/spdlog/sinks/file/simple_file_sink.h
+78
-0
No files found.
example/bench.cpp
View file @
60f8a68a
...
...
@@ -7,7 +7,9 @@
// bench.cpp : spdlog benchmarks
//
#include "spdlog/async.h"
#include "spdlog/sinks/file_sinks.h"
#include "spdlog/sinks/file/simple_file_sink.h"
#include "spdlog/sinks/file/daily_file_sink.h"
#include "spdlog/sinks/file/rotating_file_sink.h"
#include "spdlog/sinks/null_sink.h"
#include "spdlog/spdlog.h"
...
...
@@ -33,7 +35,7 @@ int main(int argc, char *argv[])
int
queue_size
=
1048576
;
int
howmany
=
1000000
;
int
threads
=
1
;
int
threads
=
1
0
;
int
file_size
=
30
*
1024
*
1024
;
int
rotating_files
=
5
;
...
...
@@ -46,7 +48,7 @@ int main(int argc, char *argv[])
threads
=
atoi
(
argv
[
2
]);
if
(
argc
>
3
)
queue_size
=
atoi
(
argv
[
3
]);
/*
cout
<<
"*******************************************************************************
\n
"
;
cout
<<
"Single thread, "
<<
format
(
howmany
)
<<
" iterations"
<<
endl
;
cout
<<
"*******************************************************************************
\n
"
;
...
...
@@ -67,12 +69,12 @@ int main(int argc, char *argv[])
auto
daily_mt
=
spdlog
::
daily_logger_mt
(
"daily_mt"
,
"logs/daily_mt.log"
);
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 "
<<
endl
;
cout
<<
"*******************************************************************************
\n
"
;
for
(
int
i
=
0
;
i
<
3
00
;
++
i
)
for
(
int
i
=
0
;
i
<
3
;
++
i
)
{
spdlog
::
init_thread_pool
(
queue_size
,
1
);
auto
as
=
spdlog
::
basic_logger_mt
<
spdlog
::
create_async
>
(
"as"
,
"logs/basic_async.log"
,
true
);
...
...
example/example.cpp
View file @
60f8a68a
...
...
@@ -10,7 +10,9 @@
#define SPDLOG_TRACE_ON
#define SPDLOG_DEBUG_ON
#include "spdlog/sinks/file_sinks.h"
#include "spdlog/sinks/file/simple_file_sink.h"
#include "spdlog/sinks/file/daily_file_sink.h"
#include "spdlog/sinks/file/rotating_file_sink.h"
#include "spdlog/sinks/stdout_color_sinks.h"
#include <iostream>
...
...
include/spdlog/sinks/file
_sinks
.h
→
include/spdlog/sinks/file
/daily_file_sink
.h
View file @
60f8a68a
...
...
@@ -4,11 +4,11 @@
//
#pragma once
#include "
../details/file_helper
.h"
#include "
../details/null_mutex
.h"
#include "
../fmt/fmt
.h"
#include "
../spdlog
.h"
#include "base_sink.h"
#include "
spdlog/spdlog
.h"
#include "
spdlog/details/file_helper
.h"
#include "
spdlog/details/null_mutex
.h"
#include "
spdlog/fmt/fmt
.h"
#include "
spdlog/sinks/
base_sink.h"
#include <algorithm>
#include <cerrno>
...
...
@@ -20,137 +20,6 @@
namespace
spdlog
{
namespace
sinks
{
/*
* Trivial file sink with single file as target
*/
template
<
class
Mutex
>
class
simple_file_sink
SPDLOG_FINAL
:
public
base_sink
<
Mutex
>
{
public:
explicit
simple_file_sink
(
const
filename_t
&
filename
,
bool
truncate
=
false
)
:
_force_flush
(
false
)
{
_file_helper
.
open
(
filename
,
truncate
);
}
void
set_force_flush
(
bool
force_flush
)
{
_force_flush
=
force_flush
;
}
protected:
void
_sink_it
(
const
details
::
log_msg
&
msg
)
override
{
_file_helper
.
write
(
msg
);
if
(
_force_flush
)
{
_file_helper
.
flush
();
}
}
void
_flush
()
override
{
_file_helper
.
flush
();
}
private:
details
::
file_helper
_file_helper
;
bool
_force_flush
;
};
using
simple_file_sink_mt
=
simple_file_sink
<
std
::
mutex
>
;
using
simple_file_sink_st
=
simple_file_sink
<
details
::
null_mutex
>
;
/*
* Rotating file sink based on size
*/
template
<
class
Mutex
>
class
rotating_file_sink
SPDLOG_FINAL
:
public
base_sink
<
Mutex
>
{
public:
rotating_file_sink
(
filename_t
base_filename
,
std
::
size_t
max_size
,
std
::
size_t
max_files
)
:
_base_filename
(
std
::
move
(
base_filename
))
,
_max_size
(
max_size
)
,
_max_files
(
max_files
)
{
_file_helper
.
open
(
calc_filename
(
_base_filename
,
0
));
_current_size
=
_file_helper
.
size
();
// expensive. called only once
}
// calc filename according to index and file extension if exists.
// e.g. calc_filename("logs/mylog.txt, 3) => "logs/mylog.3.txt".
static
filename_t
calc_filename
(
const
filename_t
&
filename
,
std
::
size_t
index
)
{
typename
std
::
conditional
<
std
::
is_same
<
filename_t
::
value_type
,
char
>::
value
,
fmt
::
MemoryWriter
,
fmt
::
WMemoryWriter
>::
type
w
;
if
(
index
!=
0u
)
{
filename_t
basename
,
ext
;
std
::
tie
(
basename
,
ext
)
=
details
::
file_helper
::
split_by_extenstion
(
filename
);
w
.
write
(
SPDLOG_FILENAME_T
(
"{}.{}{}"
),
basename
,
index
,
ext
);
}
else
{
w
.
write
(
SPDLOG_FILENAME_T
(
"{}"
),
filename
);
}
return
w
.
str
();
}
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
_flush
()
override
{
_file_helper
.
flush
();
}
private:
// Rotate files:
// log.txt -> log.1.txt
// log.1.txt -> log.2.txt
// log.2.txt -> log.3.txt
// log.3.txt -> delete
void
_rotate
()
{
using
details
::
os
::
filename_to_str
;
_file_helper
.
close
();
for
(
auto
i
=
_max_files
;
i
>
0
;
--
i
)
{
filename_t
src
=
calc_filename
(
_base_filename
,
i
-
1
);
filename_t
target
=
calc_filename
(
_base_filename
,
i
);
if
(
details
::
file_helper
::
file_exists
(
target
))
{
if
(
details
::
os
::
remove
(
target
)
!=
0
)
{
throw
spdlog_ex
(
"rotating_file_sink: failed removing "
+
filename_to_str
(
target
),
errno
);
}
}
if
(
details
::
file_helper
::
file_exists
(
src
)
&&
details
::
os
::
rename
(
src
,
target
)
!=
0
)
{
throw
spdlog_ex
(
"rotating_file_sink: failed renaming "
+
filename_to_str
(
src
)
+
" to "
+
filename_to_str
(
target
),
errno
);
}
}
_file_helper
.
reopen
(
true
);
}
filename_t
_base_filename
;
std
::
size_t
_max_size
;
std
::
size_t
_max_files
;
std
::
size_t
_current_size
;
details
::
file_helper
_file_helper
;
};
using
rotating_file_sink_mt
=
rotating_file_sink
<
std
::
mutex
>
;
using
rotating_file_sink_st
=
rotating_file_sink
<
details
::
null_mutex
>
;
/*
* Default generator of daily log file names.
...
...
@@ -254,41 +123,7 @@ using daily_file_sink_st = daily_file_sink<details::null_mutex>;
}
// namespace sinks
//
// factory functions to create and register file loggers
//
// Basic logger simply writes to given file without any limitations or rotations.
template
<
typename
Factory
=
default_factory
>
inline
std
::
shared_ptr
<
logger
>
basic_logger_mt
(
const
std
::
string
&
logger_name
,
const
filename_t
&
filename
,
bool
truncate
=
false
)
{
return
Factory
::
template
create
<
sinks
::
simple_file_sink_mt
>(
logger_name
,
filename
,
truncate
);
}
template
<
typename
Factory
=
default_factory
>
inline
std
::
shared_ptr
<
logger
>
basic_logger_st
(
const
std
::
string
&
logger_name
,
const
filename_t
&
filename
,
bool
truncate
=
false
)
{
return
Factory
::
template
create
<
sinks
::
simple_file_sink_st
>(
logger_name
,
filename
,
truncate
);
}
//
// Create and register multi/single threaded rotating file logger
//
template
<
typename
Factory
=
default_factory
>
inline
std
::
shared_ptr
<
logger
>
rotating_logger_mt
(
const
std
::
string
&
logger_name
,
const
filename_t
&
filename
,
size_t
max_file_size
,
size_t
max_files
)
{
return
Factory
::
template
create
<
sinks
::
rotating_file_sink_mt
>(
logger_name
,
filename
,
max_file_size
,
max_files
);
}
template
<
typename
Factory
=
default_factory
>
inline
std
::
shared_ptr
<
logger
>
rotating_logger_st
(
const
std
::
string
&
logger_name
,
const
filename_t
&
filename
,
size_t
max_file_size
,
size_t
max_files
)
{
return
Factory
::
template
create
<
sinks
::
rotating_file_sink_st
>(
logger_name
,
filename
,
max_file_size
,
max_files
);
}
//
// Create file logger which creates new file on the given time (default in midnight):
// factory functions
//
template
<
typename
Factory
=
default_factory
>
inline
std
::
shared_ptr
<
logger
>
daily_logger_mt
(
const
std
::
string
&
logger_name
,
const
filename_t
&
filename
,
int
hour
=
0
,
int
minute
=
0
)
...
...
include/spdlog/sinks/file/rotating_file_sink.h
0 → 100644
View file @
60f8a68a
//
// Copyright(c) 2015 Gabi Melman.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
//
#pragma once
#include "spdlog/spdlog.h"
#include "spdlog/details/file_helper.h"
#include "spdlog/details/null_mutex.h"
#include "spdlog/fmt/fmt.h"
#include "spdlog/sinks/base_sink.h"
#include <cerrno>
#include <chrono>
#include <tuple>
#include <ctime>
#include <mutex>
#include <string>
namespace
spdlog
{
namespace
sinks
{
//
// Rotating file sink based on size
//
template
<
class
Mutex
>
class
rotating_file_sink
SPDLOG_FINAL
:
public
base_sink
<
Mutex
>
{
public:
rotating_file_sink
(
filename_t
base_filename
,
std
::
size_t
max_size
,
std
::
size_t
max_files
)
:
_base_filename
(
std
::
move
(
base_filename
))
,
_max_size
(
max_size
)
,
_max_files
(
max_files
)
{
_file_helper
.
open
(
calc_filename
(
_base_filename
,
0
));
_current_size
=
_file_helper
.
size
();
// expensive. called only once
}
// calc filename according to index and file extension if exists.
// e.g. calc_filename("logs/mylog.txt, 3) => "logs/mylog.3.txt".
static
filename_t
calc_filename
(
const
filename_t
&
filename
,
std
::
size_t
index
)
{
typename
std
::
conditional
<
std
::
is_same
<
filename_t
::
value_type
,
char
>::
value
,
fmt
::
MemoryWriter
,
fmt
::
WMemoryWriter
>::
type
w
;
if
(
index
!=
0u
)
{
filename_t
basename
,
ext
;
std
::
tie
(
basename
,
ext
)
=
details
::
file_helper
::
split_by_extenstion
(
filename
);
w
.
write
(
SPDLOG_FILENAME_T
(
"{}.{}{}"
),
basename
,
index
,
ext
);
}
else
{
w
.
write
(
SPDLOG_FILENAME_T
(
"{}"
),
filename
);
}
return
w
.
str
();
}
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
_flush
()
override
{
_file_helper
.
flush
();
}
private:
// Rotate files:
// log.txt -> log.1.txt
// log.1.txt -> log.2.txt
// log.2.txt -> log.3.txt
// log.3.txt -> delete
void
_rotate
()
{
using
details
::
os
::
filename_to_str
;
_file_helper
.
close
();
for
(
auto
i
=
_max_files
;
i
>
0
;
--
i
)
{
filename_t
src
=
calc_filename
(
_base_filename
,
i
-
1
);
filename_t
target
=
calc_filename
(
_base_filename
,
i
);
if
(
details
::
file_helper
::
file_exists
(
target
))
{
if
(
details
::
os
::
remove
(
target
)
!=
0
)
{
throw
spdlog_ex
(
"rotating_file_sink: failed removing "
+
filename_to_str
(
target
),
errno
);
}
}
if
(
details
::
file_helper
::
file_exists
(
src
)
&&
details
::
os
::
rename
(
src
,
target
)
!=
0
)
{
throw
spdlog_ex
(
"rotating_file_sink: failed renaming "
+
filename_to_str
(
src
)
+
" to "
+
filename_to_str
(
target
),
errno
);
}
}
_file_helper
.
reopen
(
true
);
}
filename_t
_base_filename
;
std
::
size_t
_max_size
;
std
::
size_t
_max_files
;
std
::
size_t
_current_size
;
details
::
file_helper
_file_helper
;
};
using
rotating_file_sink_mt
=
rotating_file_sink
<
std
::
mutex
>
;
using
rotating_file_sink_st
=
rotating_file_sink
<
details
::
null_mutex
>
;
}
// namespace sinks
//
// factory functions
//
template
<
typename
Factory
=
default_factory
>
inline
std
::
shared_ptr
<
logger
>
rotating_logger_mt
(
const
std
::
string
&
logger_name
,
const
filename_t
&
filename
,
size_t
max_file_size
,
size_t
max_files
)
{
return
Factory
::
template
create
<
sinks
::
rotating_file_sink_mt
>(
logger_name
,
filename
,
max_file_size
,
max_files
);
}
template
<
typename
Factory
=
default_factory
>
inline
std
::
shared_ptr
<
logger
>
rotating_logger_st
(
const
std
::
string
&
logger_name
,
const
filename_t
&
filename
,
size_t
max_file_size
,
size_t
max_files
)
{
return
Factory
::
template
create
<
sinks
::
rotating_file_sink_st
>(
logger_name
,
filename
,
max_file_size
,
max_files
);
}
}
// namespace spdlog
include/spdlog/sinks/file/simple_file_sink.h
0 → 100644
View file @
60f8a68a
//
// Copyright(c) 2015-2018 Gabi Melman.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
//
#pragma once
#include "spdlog/spdlog.h"
#include "spdlog/details/file_helper.h"
#include "spdlog/details/null_mutex.h"
#include "spdlog/sinks/base_sink.h"
#include <mutex>
#include <string>
namespace
spdlog
{
namespace
sinks
{
/*
* Trivial file sink with single file as target
*/
template
<
class
Mutex
>
class
simple_file_sink
SPDLOG_FINAL
:
public
base_sink
<
Mutex
>
{
public:
explicit
simple_file_sink
(
const
filename_t
&
filename
,
bool
truncate
=
false
)
:
_force_flush
(
false
)
{
_file_helper
.
open
(
filename
,
truncate
);
}
void
set_force_flush
(
bool
force_flush
)
{
_force_flush
=
force_flush
;
}
protected:
void
_sink_it
(
const
details
::
log_msg
&
msg
)
override
{
_file_helper
.
write
(
msg
);
if
(
_force_flush
)
{
_file_helper
.
flush
();
}
}
void
_flush
()
override
{
_file_helper
.
flush
();
}
private:
details
::
file_helper
_file_helper
;
bool
_force_flush
;
};
using
simple_file_sink_mt
=
simple_file_sink
<
std
::
mutex
>
;
using
simple_file_sink_st
=
simple_file_sink
<
details
::
null_mutex
>
;
}
// namespace sinks
//
// factory functions
//
// Basic logger simply writes to given file without any limitations or rotations.
template
<
typename
Factory
=
default_factory
>
inline
std
::
shared_ptr
<
logger
>
basic_logger_mt
(
const
std
::
string
&
logger_name
,
const
filename_t
&
filename
,
bool
truncate
=
false
)
{
return
Factory
::
template
create
<
sinks
::
simple_file_sink_mt
>(
logger_name
,
filename
,
truncate
);
}
template
<
typename
Factory
=
default_factory
>
inline
std
::
shared_ptr
<
logger
>
basic_logger_st
(
const
std
::
string
&
logger_name
,
const
filename_t
&
filename
,
bool
truncate
=
false
)
{
return
Factory
::
template
create
<
sinks
::
simple_file_sink_st
>(
logger_name
,
filename
,
truncate
);
}
}
// namespace spdlog
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