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
8494590f
Commit
8494590f
authored
Mar 22, 2014
by
gabime
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
astyle+dos2unix
parent
6a83c344
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
950 additions
and
949 deletions
+950
-949
astyle.sh
astyle.sh
+2
-1
example.cpp
example/example.cpp
+4
-4
common_types.h
include/c11log/common_types.h
+29
-29
blocking_queue.h
include/c11log/details/blocking_queue.h
+125
-125
factory.h
include/c11log/details/factory.h
+61
-61
fast_buf.h
include/c11log/details/fast_buf.h
+11
-11
fast_oss.h
include/c11log/details/fast_oss.h
+106
-106
line_logger.h
include/c11log/details/line_logger.h
+75
-75
os.h
include/c11log/details/os.h
+63
-63
formatter.h
include/c11log/formatter.h
+97
-97
logger.h
include/c11log/logger.h
+163
-163
async_sink.h
include/c11log/sinks/async_sink.h
+116
-116
base_sink.h
include/c11log/sinks/base_sink.h
+51
-51
console_sinks.h
include/c11log/sinks/console_sinks.h
+47
-47
file_sinks.h
include/c11log/sinks/file_sinks.h
+0
-0
No files found.
astyle.sh
View file @
8494590f
#!/bin/bash
#!/bin/bash
find
.
-name
"*
\.
h"
-o
-name
"*
\.
cpp"
|xargs astyle
-A1
find
.
-name
"*
\.
h"
-o
-name
"*
\.
cpp"
|xargs dos2unix
find
.
-name
"*
\.
h"
-o
-name
"*
\.
cpp"
|xargs astyle
-n
-A1
example/example.cpp
View file @
8494590f
...
@@ -32,12 +32,12 @@ int main(int argc, char* argv[])
...
@@ -32,12 +32,12 @@ int main(int argc, char* argv[])
logger
my_logger
(
"my_logger"
,
{
null_sink
});
logger
my_logger
(
"my_logger"
,
{
null_sink
});
std
::
string
s
(
100
,
'0'
);
std
::
string
s
(
100
,
'0'
);
const
unsigned
int
howmany
=
5000000
;
const
unsigned
int
howmany
=
5000000
;
auto
start
=
system_clock
::
now
();
auto
start
=
system_clock
::
now
();
for
(
unsigned
int
i
=
0
;
i
<
howmany
;
i
++
)
for
(
unsigned
int
i
=
0
;
i
<
howmany
;
i
++
)
my_logger
.
info
()
<<
s
;
my_logger
.
info
()
<<
s
;
//my_logger.info() << "Hello logger " << i;;
//my_logger.info() << "Hello logger " << i;;
//async->shutdown(seconds(3));
//async->shutdown(seconds(3));
auto
delta
=
system_clock
::
now
()
-
start
;
auto
delta
=
system_clock
::
now
()
-
start
;
...
...
include/c11log/common_types.h
View file @
8494590f
#pragma once
#pragma once
#include <chrono>
#include <chrono>
namespace
c11log
namespace
c11log
{
{
typedef
std
::
chrono
::
system_clock
log_clock
;
typedef
std
::
chrono
::
system_clock
log_clock
;
typedef
std
::
pair
<
const
char
*
,
std
::
size_t
>
bufpair_t
;
typedef
std
::
pair
<
const
char
*
,
std
::
size_t
>
bufpair_t
;
namespace
level
namespace
level
{
{
typedef
enum
typedef
enum
{
{
DEBUG
,
DEBUG
,
INFO
,
INFO
,
WARNING
,
WARNING
,
ERROR
,
ERROR
,
FATAL
,
FATAL
,
NONE
=
99
NONE
=
99
}
level_enum
;
}
level_enum
;
static
const
char
*
level_names
[]
{
"debug"
,
"info"
,
"warning"
,
"error"
,
"fatal"
};
static
const
char
*
level_names
[]
{
"debug"
,
"info"
,
"warning"
,
"error"
,
"fatal"
};
inline
const
char
*
to_str
(
c11log
::
level
::
level_enum
l
)
inline
const
char
*
to_str
(
c11log
::
level
::
level_enum
l
)
{
{
return
level_names
[
l
];
return
level_names
[
l
];
}
}
}
}
}
}
include/c11log/details/blocking_queue.h
View file @
8494590f
#pragma once
#pragma once
// blocking_queue:
// blocking_queue:
// A blocking multi-consumer/multi-producer thread safe queue.
// A blocking multi-consumer/multi-producer thread safe queue.
// Has max capacity and supports timeout on push or pop operations.
// Has max capacity and supports timeout on push or pop operations.
#include <chrono>
#include <chrono>
#include <memory>
#include <memory>
#include <queue>
#include <queue>
#include <mutex>
#include <mutex>
#include <condition_variable>
#include <condition_variable>
namespace
c11log
namespace
c11log
{
{
namespace
details
namespace
details
{
{
template
<
typename
T
>
template
<
typename
T
>
class
blocking_queue
class
blocking_queue
{
{
public
:
public
:
using
queue_t
=
std
::
queue
<
T
>
;
using
queue_t
=
std
::
queue
<
T
>
;
using
size_type
=
typename
queue_t
::
size_type
;
using
size_type
=
typename
queue_t
::
size_type
;
using
clock
=
std
::
chrono
::
system_clock
;
using
clock
=
std
::
chrono
::
system_clock
;
explicit
blocking_queue
(
size_type
max_size
)
:
explicit
blocking_queue
(
size_type
max_size
)
:
_max_size
(
max_size
),
_max_size
(
max_size
),
_q
(),
_q
(),
_mutex
()
_mutex
()
{
{
}
}
blocking_queue
(
const
blocking_queue
&
)
=
delete
;
blocking_queue
(
const
blocking_queue
&
)
=
delete
;
blocking_queue
&
operator
=
(
const
blocking_queue
&
)
=
delete
;
blocking_queue
&
operator
=
(
const
blocking_queue
&
)
=
delete
;
~
blocking_queue
()
=
default
;
~
blocking_queue
()
=
default
;
size_type
size
()
size_type
size
()
{
{
std
::
lock_guard
<
std
::
mutex
>
lock
(
_mutex
);
std
::
lock_guard
<
std
::
mutex
>
lock
(
_mutex
);
return
_q
.
size
();
return
_q
.
size
();
}
}
// Push copy of item into the back of the queue.
// Push copy of item into the back of the queue.
// If the queue is full, block the calling thread util there is room or timeout have passed.
// If the queue is full, block the calling thread util there is room or timeout have passed.
// Return: false on timeout, true on successful push.
// Return: false on timeout, true on successful push.
template
<
typename
Duration_Rep
,
typename
Duration_Period
,
typename
TT
>
template
<
typename
Duration_Rep
,
typename
Duration_Period
,
typename
TT
>
bool
push
(
TT
&&
item
,
const
std
::
chrono
::
duration
<
Duration_Rep
,
Duration_Period
>&
timeout
)
bool
push
(
TT
&&
item
,
const
std
::
chrono
::
duration
<
Duration_Rep
,
Duration_Period
>&
timeout
)
{
{
std
::
unique_lock
<
std
::
mutex
>
ul
(
_mutex
);
std
::
unique_lock
<
std
::
mutex
>
ul
(
_mutex
);
if
(
_q
.
size
()
>=
_max_size
)
if
(
_q
.
size
()
>=
_max_size
)
{
{
if
(
!
_item_popped_cond
.
wait_until
(
ul
,
clock
::
now
()
+
timeout
,
[
this
]()
if
(
!
_item_popped_cond
.
wait_until
(
ul
,
clock
::
now
()
+
timeout
,
[
this
]()
{
{
return
this
->
_q
.
size
()
<
this
->
_max_size
;
return
this
->
_q
.
size
()
<
this
->
_max_size
;
}))
}))
return
false
;
return
false
;
}
}
_q
.
push
(
std
::
forward
<
TT
>
(
item
));
_q
.
push
(
std
::
forward
<
TT
>
(
item
));
if
(
_q
.
size
()
<=
1
)
if
(
_q
.
size
()
<=
1
)
{
{
ul
.
unlock
();
//So the notified thread will have better chance to accuire the lock immediatly..
ul
.
unlock
();
//So the notified thread will have better chance to accuire the lock immediatly..
_item_pushed_cond
.
notify_one
();
_item_pushed_cond
.
notify_one
();
}
}
return
true
;
return
true
;
}
}
// Push copy of item into the back of the queue.
// Push copy of item into the back of the queue.
// If the queue is full, block the calling thread until there is room.
// If the queue is full, block the calling thread until there is room.
template
<
typename
TT
>
template
<
typename
TT
>
void
push
(
TT
&&
item
)
void
push
(
TT
&&
item
)
{
{
while
(
!
push
(
std
::
forward
<
TT
>
(
item
),
std
::
chrono
::
hours
(
1
)));
while
(
!
push
(
std
::
forward
<
TT
>
(
item
),
std
::
chrono
::
hours
(
1
)));
}
}
// Pop a copy of the front item in the queue into the given item ref.
// Pop a copy of the front item in the queue into the given item ref.
// If the queue is empty, block the calling thread util there is item to pop or timeout have passed.
// If the queue is empty, block the calling thread util there is item to pop or timeout have passed.
// Return: false on timeout , true on successful pop/
// Return: false on timeout , true on successful pop/
template
<
class
Duration_Rep
,
class
Duration_Period
>
template
<
class
Duration_Rep
,
class
Duration_Period
>
bool
pop
(
T
&
item
,
const
std
::
chrono
::
duration
<
Duration_Rep
,
Duration_Period
>&
timeout
)
bool
pop
(
T
&
item
,
const
std
::
chrono
::
duration
<
Duration_Rep
,
Duration_Period
>&
timeout
)
{
{
std
::
unique_lock
<
std
::
mutex
>
ul
(
_mutex
);
std
::
unique_lock
<
std
::
mutex
>
ul
(
_mutex
);
if
(
_q
.
empty
())
if
(
_q
.
empty
())
{
{
if
(
!
_item_pushed_cond
.
wait_until
(
ul
,
clock
::
now
()
+
timeout
,
[
this
]()
if
(
!
_item_pushed_cond
.
wait_until
(
ul
,
clock
::
now
()
+
timeout
,
[
this
]()
{
{
return
!
this
->
_q
.
empty
();
return
!
this
->
_q
.
empty
();
}))
}))
return
false
;
return
false
;
}
}
item
=
std
::
move
(
_q
.
front
());
item
=
std
::
move
(
_q
.
front
());
_q
.
pop
();
_q
.
pop
();
if
(
_q
.
size
()
>=
_max_size
-
1
)
if
(
_q
.
size
()
>=
_max_size
-
1
)
{
{
ul
.
unlock
();
//So the notified thread will have better chance to accuire the lock immediatly..
ul
.
unlock
();
//So the notified thread will have better chance to accuire the lock immediatly..
_item_popped_cond
.
notify_one
();
_item_popped_cond
.
notify_one
();
}
}
return
true
;
return
true
;
}
}
// Pop a copy of the front item in the queue into the given item ref.
// Pop a copy of the front item in the queue into the given item ref.
// If the queue is empty, block the calling thread util there is item to pop.
// If the queue is empty, block the calling thread util there is item to pop.
void
pop
(
T
&
item
)
void
pop
(
T
&
item
)
{
{
while
(
!
pop
(
item
,
std
::
chrono
::
hours
(
1
)));
while
(
!
pop
(
item
,
std
::
chrono
::
hours
(
1
)));
}
}
// Clear the queue
// Clear the queue
void
clear
()
void
clear
()
{
{
{
{
std
::
unique_lock
<
std
::
mutex
>
ul
(
_mutex
);
std
::
unique_lock
<
std
::
mutex
>
ul
(
_mutex
);
queue_t
().
swap
(
_q
);
queue_t
().
swap
(
_q
);
}
}
_item_popped_cond
.
notify_all
();
_item_popped_cond
.
notify_all
();
}
}
private
:
private
:
size_type
_max_size
;
size_type
_max_size
;
std
::
queue
<
T
>
_q
;
std
::
queue
<
T
>
_q
;
std
::
mutex
_mutex
;
std
::
mutex
_mutex
;
std
::
condition_variable
_item_pushed_cond
;
std
::
condition_variable
_item_pushed_cond
;
std
::
condition_variable
_item_popped_cond
;
std
::
condition_variable
_item_popped_cond
;
};
};
}
}
}
}
include/c11log/details/factory.h
View file @
8494590f
#pragma once
#pragma once
#include <unordered_map>
#include <unordered_map>
#include <string>
#include <string>
#include <memory>
#include <memory>
#include <mutex>
#include <mutex>
namespace
c11log
namespace
c11log
{
{
class
logger
;
class
logger
;
namespace
details
namespace
details
{
{
class
factory
class
factory
{
{
public
:
public
:
using
logger_ptr
=
std
::
shared_ptr
<
c11log
::
logger
>
;
using
logger_ptr
=
std
::
shared_ptr
<
c11log
::
logger
>
;
using
logger_map
=
std
::
unordered_map
<
std
::
string
,
logger_ptr
>
;
using
logger_map
=
std
::
unordered_map
<
std
::
string
,
logger_ptr
>
;
void
add_logger
(
const
std
::
string
&
name
,
logger_ptr
);
void
add_logger
(
const
std
::
string
&
name
,
logger_ptr
);
logger_ptr
get_logger
(
const
std
::
string
&
name
);
logger_ptr
get_logger
(
const
std
::
string
&
name
);
static
c11log
::
details
::
factory
&
instance
();
static
c11log
::
details
::
factory
&
instance
();
private
:
private
:
std
::
mutex
_loggers_mutex
;
std
::
mutex
_loggers_mutex
;
logger_map
_loggers
;
logger_map
_loggers
;
};
};
}
}
}
}
inline
void
c11log
::
details
::
factory
::
add_logger
(
const
std
::
string
&
name
,
logger_ptr
logger_p
)
inline
void
c11log
::
details
::
factory
::
add_logger
(
const
std
::
string
&
name
,
logger_ptr
logger_p
)
{
{
std
::
lock_guard
<
std
::
mutex
>
lock
(
_loggers_mutex
);
std
::
lock_guard
<
std
::
mutex
>
lock
(
_loggers_mutex
);
_loggers
.
insert
(
logger_map
::
value_type
(
name
,
logger_p
));
_loggers
.
insert
(
logger_map
::
value_type
(
name
,
logger_p
));
}
}
inline
c11log
::
details
::
factory
::
logger_ptr
c11log
::
details
::
factory
::
get_logger
(
const
std
::
string
&
name
)
inline
c11log
::
details
::
factory
::
logger_ptr
c11log
::
details
::
factory
::
get_logger
(
const
std
::
string
&
name
)
{
{
std
::
lock_guard
<
std
::
mutex
>
lock
(
_loggers_mutex
);
std
::
lock_guard
<
std
::
mutex
>
lock
(
_loggers_mutex
);
auto
found
=
_loggers
.
find
(
name
);
auto
found
=
_loggers
.
find
(
name
);
if
(
found
!=
_loggers
.
end
())
if
(
found
!=
_loggers
.
end
())
return
found
->
second
;
return
found
->
second
;
else
else
return
logger_ptr
(
nullptr
);
return
logger_ptr
(
nullptr
);
/*
/*
auto found = _loggers.find(name);
auto found = _loggers.find(name);
if (found == _loggers.end()) {
if (found == _loggers.end()) {
auto new_logger_ptr = std::make_shared<c11log::logger>(name);
auto new_logger_ptr = std::make_shared<c11log::logger>(name);
_loggers.insert(std::make_pair(name, new_logger_ptr));
_loggers.insert(std::make_pair(name, new_logger_ptr));
return new_logger_ptr;
return new_logger_ptr;
} else {
} else {
return found->second;
return found->second;
}*/
}*/
}
}
inline
c11log
::
details
::
factory
&
c11log
::
details
::
factory
::
instance
()
inline
c11log
::
details
::
factory
&
c11log
::
details
::
factory
::
instance
()
{
{
static
c11log
::
details
::
factory
instance
;
static
c11log
::
details
::
factory
instance
;
return
instance
;
return
instance
;
}
}
include/c11log/details/fast_buf.h
View file @
8494590f
...
@@ -21,10 +21,10 @@ public:
...
@@ -21,10 +21,10 @@ public:
fast_buf
()
:
_stack_size
(
0
)
{}
fast_buf
()
:
_stack_size
(
0
)
{}
~
fast_buf
()
{};
~
fast_buf
()
{};
fast_buf
(
const
bufpair_t
&
buf_to_copy
)
:
fast_buf
()
fast_buf
(
const
bufpair_t
&
buf_to_copy
)
:
fast_buf
()
{
{
append
(
buf_to_copy
);
append
(
buf_to_copy
);
}
}
fast_buf
(
const
fast_buf
&
other
)
fast_buf
(
const
fast_buf
&
other
)
{
{
...
@@ -46,7 +46,7 @@ public:
...
@@ -46,7 +46,7 @@ public:
}
}
fast_buf
&
operator
=
(
const
fast_buf
&
other
)
=
delete
;
fast_buf
&
operator
=
(
const
fast_buf
&
other
)
=
delete
;
fast_buf
&
operator
=
(
fast_buf
&&
other
)
=
delete
;
fast_buf
&
operator
=
(
fast_buf
&&
other
)
=
delete
;
void
append
(
const
char
*
buf
,
std
::
size_t
size
)
void
append
(
const
char
*
buf
,
std
::
size_t
size
)
{
{
...
@@ -66,7 +66,7 @@ public:
...
@@ -66,7 +66,7 @@ public:
//Not enough stack space. Copy all to _v
//Not enough stack space. Copy all to _v
else
else
{
{
_v
.
reserve
(
_stack_size
+
size
);
_v
.
reserve
(
_stack_size
+
size
);
if
(
_stack_size
)
if
(
_stack_size
)
_v
.
insert
(
_v
.
end
(),
_stack_buf
.
begin
(),
_stack_buf
.
begin
()
+
_stack_size
);
_v
.
insert
(
_v
.
end
(),
_stack_buf
.
begin
(),
_stack_buf
.
begin
()
+
_stack_size
);
_v
.
insert
(
_v
.
end
(),
buf
,
buf
+
size
);
_v
.
insert
(
_v
.
end
(),
buf
,
buf
+
size
);
...
@@ -74,10 +74,10 @@ public:
...
@@ -74,10 +74,10 @@ public:
}
}
}
}
void
append
(
const
bufpair_t
&
buf
)
void
append
(
const
bufpair_t
&
buf
)
{
{
append
(
buf
.
first
,
buf
.
second
);
append
(
buf
.
first
,
buf
.
second
);
}
}
void
clear
()
void
clear
()
{
{
...
@@ -96,7 +96,7 @@ public:
...
@@ -96,7 +96,7 @@ public:
private
:
private
:
std
::
vector
<
char
>
_v
;
std
::
vector
<
char
>
_v
;
std
::
array
<
char
,
STACK_SIZE
>
_stack_buf
;
std
::
array
<
char
,
STACK_SIZE
>
_stack_buf
;
std
::
size_t
_stack_size
;
std
::
size_t
_stack_size
;
};
};
}
}
...
...
include/c11log/details/fast_oss.h
View file @
8494590f
#pragma once
#pragma once
// Faster than ostringstream--returns its string by ref
// Faster than ostringstream--returns its string by ref
#include "c11log/details/fast_buf.h"
#include "c11log/details/fast_buf.h"
namespace
c11log
namespace
c11log
{
{
namespace
details
namespace
details
{
{
class
str_devicebuf
:
public
std
::
streambuf
class
str_devicebuf
:
public
std
::
streambuf
{
{
public
:
public
:
str_devicebuf
()
=
default
;
str_devicebuf
()
=
default
;
~
str_devicebuf
()
=
default
;
~
str_devicebuf
()
=
default
;
str_devicebuf
(
const
str_devicebuf
&
other
)
=
delete
;
str_devicebuf
(
const
str_devicebuf
&
other
)
=
delete
;
str_devicebuf
(
str_devicebuf
&&
other
)
=
delete
;
str_devicebuf
(
str_devicebuf
&&
other
)
=
delete
;
str_devicebuf
&
operator
=
(
const
str_devicebuf
&
)
=
delete
;
str_devicebuf
&
operator
=
(
const
str_devicebuf
&
)
=
delete
;
str_devicebuf
&
operator
=
(
str_devicebuf
&&
)
=
delete
;
str_devicebuf
&
operator
=
(
str_devicebuf
&&
)
=
delete
;
/*
/*
const std::string& str_ref() const
const std::string& str_ref() const
{
{
return _str;
return _str;
}
}
*/
*/
bufpair_t
buf
()
bufpair_t
buf
()
{
{
return
_fastbuf
.
get
();
return
_fastbuf
.
get
();
}
}
void
reset_str
()
void
reset_str
()
{
{
//_str.clear();
//_str.clear();
_fastbuf
.
clear
();
_fastbuf
.
clear
();
}
}
protected
:
protected
:
int
sync
()
override
int
sync
()
override
{
{
return
0
;
return
0
;
}
}
// copy the give buffer into the accumulated string.
// copy the give buffer into the accumulated string.
// reserve initially 128 bytes which should be enough for common log lines
// reserve initially 128 bytes which should be enough for common log lines
std
::
streamsize
xsputn
(
const
char_type
*
s
,
std
::
streamsize
count
)
override
std
::
streamsize
xsputn
(
const
char_type
*
s
,
std
::
streamsize
count
)
override
{
{
/*
/*
if(_str.capacity() < k_initial_reserve)
if(_str.capacity() < k_initial_reserve)
{
{
_str.reserve(k_initial_reserve);
_str.reserve(k_initial_reserve);
}
}
_str.append(s, static_cast<unsigned int>(count));
_str.append(s, static_cast<unsigned int>(count));
*/
*/
_fastbuf
.
append
(
s
,
static_cast
<
unsigned
int
>
(
count
));
_fastbuf
.
append
(
s
,
static_cast
<
unsigned
int
>
(
count
));
return
count
;
return
count
;
}
}
int_type
overflow
(
int_type
ch
)
override
int_type
overflow
(
int_type
ch
)
override
{
{
bool
not_eofile
=
traits_type
::
not_eof
(
ch
);
bool
not_eofile
=
traits_type
::
not_eof
(
ch
);
if
(
not_eofile
)
if
(
not_eofile
)
{
{
char
c
=
traits_type
::
to_char_type
(
ch
);
char
c
=
traits_type
::
to_char_type
(
ch
);
xsputn
(
&
c
,
1
);
xsputn
(
&
c
,
1
);
}
}
return
not_eofile
;
return
not_eofile
;
}
}
private
:
private
:
//std::string _str;
//std::string _str;
fast_buf
<
192
>
_fastbuf
;
fast_buf
<
192
>
_fastbuf
;
};
};
class
fast_oss
:
public
std
::
ostream
class
fast_oss
:
public
std
::
ostream
{
{
public
:
public
:
fast_oss
()
:
std
::
ostream
(
&
_dev
)
{}
fast_oss
()
:
std
::
ostream
(
&
_dev
)
{}
~
fast_oss
()
=
default
;
~
fast_oss
()
=
default
;
fast_oss
(
const
fast_oss
&
other
)
=
delete
;
fast_oss
(
const
fast_oss
&
other
)
=
delete
;
fast_oss
(
fast_oss
&&
other
)
=
delete
;
fast_oss
(
fast_oss
&&
other
)
=
delete
;
fast_oss
&
operator
=
(
const
fast_oss
&
other
)
=
delete
;
fast_oss
&
operator
=
(
const
fast_oss
&
other
)
=
delete
;
/*
/*
const std::string& str_ref() const
const std::string& str_ref() const
{
{
return _dev.str_ref();
return _dev.str_ref();
}
}
*/
*/
bufpair_t
buf
()
bufpair_t
buf
()
{
{
return
_dev
.
buf
();
return
_dev
.
buf
();
}
}
void
reset_str
()
void
reset_str
()
{
{
_dev
.
reset_str
();
_dev
.
reset_str
();
}
}
private
:
private
:
str_devicebuf
_dev
;
str_devicebuf
_dev
;
};
};
}
}
}
}
include/c11log/details/line_logger.h
View file @
8494590f
#pragma once
#pragma once
#include "../common_types.h"
#include "../common_types.h"
#include "../logger.h"
#include "../logger.h"
#include "fast_oss.h"
#include "fast_oss.h"
// line logger class. should be used by the logger as an rvalue only.
// line logger class. should be used by the logger as an rvalue only.
// aggregates logging string until the end of the line and then calls the logger upon destruction
// aggregates logging string until the end of the line and then calls the logger upon destruction
namespace
c11log
namespace
c11log
{
{
//class logger;
//class logger;
namespace
details
namespace
details
{
{
class
line_logger
class
line_logger
{
{
public
:
public
:
line_logger
(
logger
*
callback_logger
,
level
::
level_enum
msg_level
,
bool
enabled
)
:
line_logger
(
logger
*
callback_logger
,
level
::
level_enum
msg_level
,
bool
enabled
)
:
_callback_logger
(
callback_logger
),
_callback_logger
(
callback_logger
),
_oss
(),
_oss
(),
_level
(
msg_level
),
_level
(
msg_level
),
_enabled
(
enabled
)
_enabled
(
enabled
)
{
{
if
(
enabled
)
if
(
enabled
)
{
{
callback_logger
->
_formatter
->
format_header
(
callback_logger
->
_logger_name
,
callback_logger
->
_formatter
->
format_header
(
callback_logger
->
_logger_name
,
msg_level
,
msg_level
,
log_clock
::
now
(),
log_clock
::
now
(),
_oss
);
_oss
);
}
}
}
}
// No copy intended. Only move
// No copy intended. Only move
line_logger
(
const
line_logger
&
other
)
=
delete
;
line_logger
(
const
line_logger
&
other
)
=
delete
;
line_logger
&
operator
=
(
const
line_logger
&
)
=
delete
;
line_logger
&
operator
=
(
const
line_logger
&
)
=
delete
;
line_logger
&
operator
=
(
line_logger
&&
)
=
delete
;
line_logger
&
operator
=
(
line_logger
&&
)
=
delete
;
line_logger
(
line_logger
&&
other
)
:
line_logger
(
line_logger
&&
other
)
:
_callback_logger
(
other
.
_callback_logger
),
_callback_logger
(
other
.
_callback_logger
),
// The move ctor should only be called on start of logging line,
// The move ctor should only be called on start of logging line,
// where no logging happened yet for this line so no need to copy the string from the other
// where no logging happened yet for this line so no need to copy the string from the other
_oss
(),
_oss
(),
_level
(
other
.
_level
)
{};
_level
(
other
.
_level
)
{};
~
line_logger
()
~
line_logger
()
{
{
if
(
_enabled
)
if
(
_enabled
)
{
{
_oss
<<
os
::
eol
();
_oss
<<
os
::
eol
();
_callback_logger
->
_log_it
(
_oss
.
buf
(),
_level
);
_callback_logger
->
_log_it
(
_oss
.
buf
(),
_level
);
}
}
}
}
template
<
typename
T
>
template
<
typename
T
>
line_logger
&&
operator
<<
(
const
T
&
msg
)
line_logger
&&
operator
<<
(
const
T
&
msg
)
{
{
if
(
_enabled
)
if
(
_enabled
)
_oss
<<
msg
;
_oss
<<
msg
;
return
std
::
move
(
*
this
);
return
std
::
move
(
*
this
);
}
}
private
:
private
:
logger
*
_callback_logger
;
logger
*
_callback_logger
;
details
::
fast_oss
_oss
;
details
::
fast_oss
_oss
;
level
::
level_enum
_level
;
level
::
level_enum
_level
;
bool
_enabled
;
bool
_enabled
;
};
};
}
//Namespace details
}
//Namespace details
}
// Namespace c11log
}
// Namespace c11log
include/c11log/details/os.h
View file @
8494590f
#pragma once
#pragma once
#include<string>
#include<string>
#include<cstdio>
#include<cstdio>
#include<ctime>
#include<ctime>
namespace
c11log
namespace
c11log
{
{
namespace
details
namespace
details
{
{
namespace
os
namespace
os
{
{
inline
std
::
tm
localtime
(
const
std
::
time_t
&
time_tt
)
inline
std
::
tm
localtime
(
const
std
::
time_t
&
time_tt
)
{
{
std
::
tm
tm
;
std
::
tm
tm
;
#ifdef _WIN32
#ifdef _WIN32
localtime_s
(
&
tm
,
&
time_tt
);
localtime_s
(
&
tm
,
&
time_tt
);
#else
#else
localtime_r
(
&
time_tt
,
&
tm
);
localtime_r
(
&
time_tt
,
&
tm
);
#endif
#endif
return
tm
;
return
tm
;
}
}
inline
std
::
tm
localtime
()
inline
std
::
tm
localtime
()
{
{
std
::
time_t
now_t
=
time
(
0
);
std
::
time_t
now_t
=
time
(
0
);
return
localtime
(
now_t
);
return
localtime
(
now_t
);
}
}
inline
bool
operator
==
(
const
std
::
tm
&
tm1
,
const
std
::
tm
&
tm2
)
inline
bool
operator
==
(
const
std
::
tm
&
tm1
,
const
std
::
tm
&
tm2
)
{
{
return
(
tm1
.
tm_sec
==
tm2
.
tm_sec
&&
return
(
tm1
.
tm_sec
==
tm2
.
tm_sec
&&
tm1
.
tm_min
==
tm2
.
tm_min
&&
tm1
.
tm_min
==
tm2
.
tm_min
&&
tm1
.
tm_hour
==
tm2
.
tm_hour
&&
tm1
.
tm_hour
==
tm2
.
tm_hour
&&
tm1
.
tm_mday
==
tm2
.
tm_mday
&&
tm1
.
tm_mday
==
tm2
.
tm_mday
&&
tm1
.
tm_mon
==
tm2
.
tm_mon
&&
tm1
.
tm_mon
==
tm2
.
tm_mon
&&
tm1
.
tm_year
==
tm2
.
tm_year
&&
tm1
.
tm_year
==
tm2
.
tm_year
&&
tm1
.
tm_isdst
==
tm2
.
tm_isdst
);
tm1
.
tm_isdst
==
tm2
.
tm_isdst
);
}
}
inline
bool
operator
!=
(
const
std
::
tm
&
tm1
,
const
std
::
tm
&
tm2
)
inline
bool
operator
!=
(
const
std
::
tm
&
tm1
,
const
std
::
tm
&
tm2
)
{
{
return
!
(
tm1
==
tm2
);
return
!
(
tm1
==
tm2
);
}
}
constexpr
inline
const
char
*
eol
()
constexpr
inline
const
char
*
eol
()
{
{
#ifdef _WIN32
#ifdef _WIN32
return
"
\r\n
"
;
return
"
\r\n
"
;
#else
#else
return
"
\n
"
;
return
"
\n
"
;
#endif
#endif
}
}
}
//os
}
//os
}
//details
}
//details
}
//c11log
}
//c11log
include/c11log/formatter.h
View file @
8494590f
#pragma once
#pragma once
#include <string>
#include <string>
#include <chrono>
#include <chrono>
#include <functional>
#include <functional>
#include <sstream>
#include <sstream>
#include <iomanip>
#include <iomanip>
#include <thread>
#include <thread>
#include <cstdlib>
#include <cstdlib>
#include <cstring>
#include <cstring>
#include "common_types.h"
#include "common_types.h"
#include "details/os.h"
#include "details/os.h"
#include "details/fast_oss.h"
#include "details/fast_oss.h"
namespace
c11log
namespace
c11log
{
{
namespace
formatters
namespace
formatters
{
{
typedef
std
::
function
<
std
::
string
(
const
std
::
string
&
logger_name
,
const
std
::
string
&
,
level
::
level_enum
,
const
c11log
::
log_clock
::
time_point
&
)
>
format_fn
;
typedef
std
::
function
<
std
::
string
(
const
std
::
string
&
logger_name
,
const
std
::
string
&
,
level
::
level_enum
,
const
c11log
::
log_clock
::
time_point
&
)
>
format_fn
;
class
formatter
class
formatter
{
{
public
:
public
:
formatter
()
{}
formatter
()
{}
virtual
~
formatter
()
{}
virtual
~
formatter
()
{}
virtual
void
format_header
(
const
std
::
string
&
logger_name
,
level
::
level_enum
level
,
const
log_clock
::
time_point
&
tp
,
std
::
ostream
&
dest
)
=
0
;
virtual
void
format_header
(
const
std
::
string
&
logger_name
,
level
::
level_enum
level
,
const
log_clock
::
time_point
&
tp
,
std
::
ostream
&
dest
)
=
0
;
};
};
class
default_formatter
:
public
formatter
class
default_formatter
:
public
formatter
{
{
public
:
public
:
// Format: [2013-12-29 01:04:42.900] [logger_name:Info] Message body
// Format: [2013-12-29 01:04:42.900] [logger_name:Info] Message body
void
format_header
(
const
std
::
string
&
logger_name
,
level
::
level_enum
level
,
const
log_clock
::
time_point
&
tp
,
std
::
ostream
&
dest
)
override
void
format_header
(
const
std
::
string
&
logger_name
,
level
::
level_enum
level
,
const
log_clock
::
time_point
&
tp
,
std
::
ostream
&
dest
)
override
{
{
_format_time
(
tp
,
dest
);
_format_time
(
tp
,
dest
);
if
(
!
logger_name
.
empty
())
if
(
!
logger_name
.
empty
())
dest
<<
" ["
<<
logger_name
<<
':'
<<
c11log
::
level
::
to_str
(
level
)
<<
"] "
;
dest
<<
" ["
<<
logger_name
<<
':'
<<
c11log
::
level
::
to_str
(
level
)
<<
"] "
;
else
else
dest
<<
" ["
<<
c11log
::
level
::
to_str
(
level
)
<<
"] "
;
dest
<<
" ["
<<
c11log
::
level
::
to_str
(
level
)
<<
"] "
;
}
}
private
:
private
:
void
_format_time
(
const
log_clock
::
time_point
&
tp
,
std
::
ostream
&
dest
);
void
_format_time
(
const
log_clock
::
time_point
&
tp
,
std
::
ostream
&
dest
);
};
};
}
//namespace formatter
}
//namespace formatter
}
//namespace c11log
}
//namespace c11log
// Format datetime like this: [2014-03-14 17:15:22]
// Format datetime like this: [2014-03-14 17:15:22]
inline
void
c11log
::
formatters
::
default_formatter
::
_format_time
(
const
log_clock
::
time_point
&
tp
,
std
::
ostream
&
dest
)
inline
void
c11log
::
formatters
::
default_formatter
::
_format_time
(
const
log_clock
::
time_point
&
tp
,
std
::
ostream
&
dest
)
{
{
using
namespace
c11log
::
details
::
os
;
using
namespace
c11log
::
details
::
os
;
using
namespace
std
::
chrono
;
using
namespace
std
::
chrono
;
#ifdef _WIN32 //VS2013 doesn't support yet thread_local keyword
#ifdef _WIN32 //VS2013 doesn't support yet thread_local keyword
__declspec
(
thread
)
static
char
s_cache_str
[
64
];
__declspec
(
thread
)
static
char
s_cache_str
[
64
];
__declspec
(
thread
)
static
size_t
s_cache_size
;
__declspec
(
thread
)
static
size_t
s_cache_size
;
__declspec
(
thread
)
static
std
::
time_t
s_cache_time_t
=
0
;
__declspec
(
thread
)
static
std
::
time_t
s_cache_time_t
=
0
;
#else
#else
thread_local
static
char
s_cache_str
[
64
];
thread_local
static
char
s_cache_str
[
64
];
thread_local
static
size_t
s_cache_size
;
thread_local
static
size_t
s_cache_size
;
thread_local
static
std
::
time_t
s_cache_time_t
=
0
;
thread_local
static
std
::
time_t
s_cache_time_t
=
0
;
#endif
#endif
//Cache every second
//Cache every second
std
::
time_t
tp_time_t
=
log_clock
::
to_time_t
(
tp
);
std
::
time_t
tp_time_t
=
log_clock
::
to_time_t
(
tp
);
if
(
tp_time_t
!=
s_cache_time_t
)
if
(
tp_time_t
!=
s_cache_time_t
)
{
{
auto
tm_now
=
details
::
os
::
localtime
(
tp_time_t
);
auto
tm_now
=
details
::
os
::
localtime
(
tp_time_t
);
details
::
fast_oss
time_oss
;
details
::
fast_oss
time_oss
;
time_oss
.
fill
(
'0'
);
time_oss
.
fill
(
'0'
);
time_oss
<<
'['
<<
tm_now
.
tm_year
+
1900
<<
'-'
;
time_oss
<<
'['
<<
tm_now
.
tm_year
+
1900
<<
'-'
;
time_oss
.
width
(
2
);
time_oss
.
width
(
2
);
time_oss
<<
tm_now
.
tm_mon
+
1
<<
'-'
;
time_oss
<<
tm_now
.
tm_mon
+
1
<<
'-'
;
time_oss
.
width
(
2
);
time_oss
.
width
(
2
);
time_oss
<<
tm_now
.
tm_mday
<<
' '
;
time_oss
<<
tm_now
.
tm_mday
<<
' '
;
time_oss
.
width
(
2
);
time_oss
.
width
(
2
);
time_oss
<<
tm_now
.
tm_hour
<<
':'
;
time_oss
<<
tm_now
.
tm_hour
<<
':'
;
time_oss
.
width
(
2
);
time_oss
.
width
(
2
);
time_oss
<<
tm_now
.
tm_min
<<
':'
;
time_oss
<<
tm_now
.
tm_min
<<
':'
;
time_oss
.
width
(
2
);
time_oss
.
width
(
2
);
time_oss
<<
tm_now
.
tm_sec
<<
']'
;
time_oss
<<
tm_now
.
tm_sec
<<
']'
;
//Cache the resulted string and its size
//Cache the resulted string and its size
s_cache_time_t
=
tp_time_t
;
s_cache_time_t
=
tp_time_t
;
//const std::string &s = time_oss.str_ref();
//const std::string &s = time_oss.str_ref();
bufpair_t
buf
=
time_oss
.
buf
();
bufpair_t
buf
=
time_oss
.
buf
();
std
::
memcpy
(
s_cache_str
,
buf
.
first
,
buf
.
second
);
std
::
memcpy
(
s_cache_str
,
buf
.
first
,
buf
.
second
);
s_cache_size
=
buf
.
second
;
s_cache_size
=
buf
.
second
;
}
}
dest
.
write
(
s_cache_str
,
s_cache_size
);
dest
.
write
(
s_cache_str
,
s_cache_size
);
}
}
include/c11log/logger.h
View file @
8494590f
#pragma once
#pragma once
// Thread safe logger
// Thread safe logger
// Has log level and vector sinks which do the actual logging
// Has log level and vector sinks which do the actual logging
#include<vector>
#include<vector>
#include<memory>
#include<memory>
#include<mutex>
#include<mutex>
#include<atomic>
#include<atomic>
#include <algorithm>
#include <algorithm>
#include "common_types.h"
#include "common_types.h"
#include "sinks/base_sink.h"
#include "sinks/base_sink.h"
#include "details/factory.h"
#include "details/factory.h"
#include "c11log/details/log_msg.h"
#include "c11log/details/log_msg.h"
//Thread safe, fast logger.
//Thread safe, fast logger.
//All initialization is done in ctor only, so we get away lot of locking
//All initialization is done in ctor only, so we get away lot of locking
namespace
c11log
namespace
c11log
{
{
namespace
details
namespace
details
{
{
class
line_logger
;
class
line_logger
;
template
<
std
::
size_t
>
class
fast_buf
;
template
<
std
::
size_t
>
class
fast_buf
;
}
}
class
logger
class
logger
{
{
public
:
public
:
using
sink_ptr
=
std
::
shared_ptr
<
sinks
::
base_sink
>
;
using
sink_ptr
=
std
::
shared_ptr
<
sinks
::
base_sink
>
;
using
formatter_ptr
=
std
::
shared_ptr
<
c11log
::
formatters
::
formatter
>
;
using
formatter_ptr
=
std
::
shared_ptr
<
c11log
::
formatters
::
formatter
>
;
using
sinks_vector_t
=
std
::
vector
<
sink_ptr
>
;
using
sinks_vector_t
=
std
::
vector
<
sink_ptr
>
;
using
sinks_init_list
=
std
::
initializer_list
<
sink_ptr
>
;
using
sinks_init_list
=
std
::
initializer_list
<
sink_ptr
>
;
logger
(
const
std
::
string
&
name
,
formatter_ptr
,
sinks_init_list
);
logger
(
const
std
::
string
&
name
,
formatter_ptr
,
sinks_init_list
);
logger
(
const
std
::
string
&
name
,
sinks_init_list
);
logger
(
const
std
::
string
&
name
,
sinks_init_list
);
logger
(
sinks_init_list
sinks_list
);
logger
(
sinks_init_list
sinks_list
);
~
logger
()
=
default
;
~
logger
()
=
default
;
//Non copybale in anyway
//Non copybale in anyway
logger
(
const
logger
&
)
=
delete
;
logger
(
const
logger
&
)
=
delete
;
logger
(
logger
&&
)
=
delete
;
logger
(
logger
&&
)
=
delete
;
logger
&
operator
=
(
const
logger
&
)
=
delete
;
logger
&
operator
=
(
const
logger
&
)
=
delete
;
logger
&
operator
=
(
logger
&&
)
=
delete
;
logger
&
operator
=
(
logger
&&
)
=
delete
;
void
set_level
(
c11log
::
level
::
level_enum
);
void
set_level
(
c11log
::
level
::
level_enum
);
c11log
::
level
::
level_enum
get_level
()
const
;
c11log
::
level
::
level_enum
get_level
()
const
;
const
std
::
string
&
get_name
()
const
;
const
std
::
string
&
get_name
()
const
;
bool
should_log
(
c11log
::
level
::
level_enum
)
const
;
bool
should_log
(
c11log
::
level
::
level_enum
)
const
;
details
::
line_logger
log
(
level
::
level_enum
);
details
::
line_logger
log
(
level
::
level_enum
);
details
::
line_logger
debug
();
details
::
line_logger
debug
();
details
::
line_logger
info
();
details
::
line_logger
info
();
details
::
line_logger
warn
();
details
::
line_logger
warn
();
details
::
line_logger
error
();
details
::
line_logger
error
();
details
::
line_logger
fatal
();
details
::
line_logger
fatal
();
private
:
private
:
friend
details
::
line_logger
;
friend
details
::
line_logger
;
std
::
string
_logger_name
=
""
;
std
::
string
_logger_name
=
""
;
formatter_ptr
_formatter
;
formatter_ptr
_formatter
;
sinks_vector_t
_sinks
;
sinks_vector_t
_sinks
;
std
::
atomic_int
_atomic_level
;
std
::
atomic_int
_atomic_level
;
void
_log_it
(
const
bufpair_t
&
buf
,
const
level
::
level_enum
level
);
void
_log_it
(
const
bufpair_t
&
buf
,
const
level
::
level_enum
level
);
};
};
logger
&
get_logger
(
const
std
::
string
&
name
);
logger
&
get_logger
(
const
std
::
string
&
name
);
}
}
//
//
// Logger inline implementation
// Logger inline implementation
//
//
#include "details/line_logger.h"
#include "details/line_logger.h"
#include "details/fast_buf.h"
#include "details/fast_buf.h"
inline
c11log
::
logger
::
logger
(
const
std
::
string
&
name
,
formatter_ptr
f
,
sinks_init_list
sinks_list
)
:
inline
c11log
::
logger
::
logger
(
const
std
::
string
&
name
,
formatter_ptr
f
,
sinks_init_list
sinks_list
)
:
_logger_name
(
name
),
_logger_name
(
name
),
_formatter
(
f
),
_formatter
(
f
),
_sinks
(
sinks_list
)
_sinks
(
sinks_list
)
{
{
//Seems that vs2013 doesnt support atomic member initialization in ctor, so its done here
//Seems that vs2013 doesnt support atomic member initialization in ctor, so its done here
_atomic_level
=
level
::
INFO
;
_atomic_level
=
level
::
INFO
;
}
}
inline
c11log
::
logger
::
logger
(
const
std
::
string
&
name
,
sinks_init_list
sinks_list
)
:
inline
c11log
::
logger
::
logger
(
const
std
::
string
&
name
,
sinks_init_list
sinks_list
)
:
logger
(
name
,
std
::
make_shared
<
formatters
::
default_formatter
>
(),
sinks_list
)
{}
logger
(
name
,
std
::
make_shared
<
formatters
::
default_formatter
>
(),
sinks_list
)
{}
inline
c11log
::
logger
::
logger
(
sinks_init_list
sinks_list
)
:
inline
c11log
::
logger
::
logger
(
sinks_init_list
sinks_list
)
:
logger
(
""
,
std
::
make_shared
<
formatters
::
default_formatter
>
(),
sinks_list
)
{}
logger
(
""
,
std
::
make_shared
<
formatters
::
default_formatter
>
(),
sinks_list
)
{}
inline
c11log
::
details
::
line_logger
c11log
::
logger
::
log
(
c11log
::
level
::
level_enum
msg_level
)
inline
c11log
::
details
::
line_logger
c11log
::
logger
::
log
(
c11log
::
level
::
level_enum
msg_level
)
{
{
return
details
::
line_logger
(
this
,
msg_level
,
msg_level
>=
_atomic_level
);
return
details
::
line_logger
(
this
,
msg_level
,
msg_level
>=
_atomic_level
);
}
}
inline
c11log
::
details
::
line_logger
c11log
::
logger
::
debug
()
inline
c11log
::
details
::
line_logger
c11log
::
logger
::
debug
()
{
{
return
log
(
c11log
::
level
::
DEBUG
);
return
log
(
c11log
::
level
::
DEBUG
);
}
}
inline
c11log
::
details
::
line_logger
c11log
::
logger
::
info
()
inline
c11log
::
details
::
line_logger
c11log
::
logger
::
info
()
{
{
return
log
(
c11log
::
level
::
INFO
);
return
log
(
c11log
::
level
::
INFO
);
}
}
inline
c11log
::
details
::
line_logger
c11log
::
logger
::
warn
()
inline
c11log
::
details
::
line_logger
c11log
::
logger
::
warn
()
{
{
return
log
(
c11log
::
level
::
WARNING
);
return
log
(
c11log
::
level
::
WARNING
);
}
}
inline
c11log
::
details
::
line_logger
c11log
::
logger
::
error
()
inline
c11log
::
details
::
line_logger
c11log
::
logger
::
error
()
{
{
return
log
(
level
::
ERROR
);
return
log
(
level
::
ERROR
);
}
}
inline
c11log
::
details
::
line_logger
c11log
::
logger
::
fatal
()
inline
c11log
::
details
::
line_logger
c11log
::
logger
::
fatal
()
{
{
return
log
(
c11log
::
level
::
FATAL
);
return
log
(
c11log
::
level
::
FATAL
);
}
}
inline
const
std
::
string
&
c11log
::
logger
::
get_name
()
const
inline
const
std
::
string
&
c11log
::
logger
::
get_name
()
const
{
{
return
_logger_name
;
return
_logger_name
;
}
}
inline
void
c11log
::
logger
::
set_level
(
c11log
::
level
::
level_enum
level
)
inline
void
c11log
::
logger
::
set_level
(
c11log
::
level
::
level_enum
level
)
{
{
_atomic_level
.
store
(
level
);
_atomic_level
.
store
(
level
);
}
}
inline
c11log
::
level
::
level_enum
c11log
::
logger
::
get_level
()
const
inline
c11log
::
level
::
level_enum
c11log
::
logger
::
get_level
()
const
{
{
return
static_cast
<
c11log
::
level
::
level_enum
>
(
_atomic_level
.
load
());
return
static_cast
<
c11log
::
level
::
level_enum
>
(
_atomic_level
.
load
());
}
}
inline
bool
c11log
::
logger
::
should_log
(
c11log
::
level
::
level_enum
level
)
const
inline
bool
c11log
::
logger
::
should_log
(
c11log
::
level
::
level_enum
level
)
const
{
{
return
level
>=
_atomic_level
.
load
();
return
level
>=
_atomic_level
.
load
();
}
}
inline
void
c11log
::
logger
::
_log_it
(
const
bufpair_t
&
buf
,
const
level
::
level_enum
level
)
inline
void
c11log
::
logger
::
_log_it
(
const
bufpair_t
&
buf
,
const
level
::
level_enum
level
)
{
{
for
(
auto
&
sink
:
_sinks
)
for
(
auto
&
sink
:
_sinks
)
sink
->
log
(
buf
,
level
);
sink
->
log
(
buf
,
level
);
}
}
// Static factory function
// Static factory function
inline
c11log
::
logger
&
c11log
::
get_logger
(
const
std
::
string
&
name
)
inline
c11log
::
logger
&
c11log
::
get_logger
(
const
std
::
string
&
name
)
{
{
return
*
(
c11log
::
details
::
factory
::
instance
().
get_logger
(
name
));
return
*
(
c11log
::
details
::
factory
::
instance
().
get_logger
(
name
));
}
}
include/c11log/sinks/async_sink.h
View file @
8494590f
#pragma once
#pragma once
#include <thread>
#include <thread>
#include <chrono>
#include <chrono>
#include <atomic>
#include <atomic>
#include "base_sink.h"
#include "base_sink.h"
#include "../logger.h"
#include "../logger.h"
#include "../details/blocking_queue.h"
#include "../details/blocking_queue.h"
namespace
c11log
namespace
c11log
{
{
namespace
sinks
namespace
sinks
{
{
class
async_sink
:
public
base_sink
class
async_sink
:
public
base_sink
{
{
public
:
public
:
using
size_type
=
c11log
::
details
::
blocking_queue
<
std
::
string
>::
size_type
;
using
size_type
=
c11log
::
details
::
blocking_queue
<
std
::
string
>::
size_type
;
explicit
async_sink
(
const
size_type
max_queue_size
);
explicit
async_sink
(
const
size_type
max_queue_size
);
~
async_sink
();
~
async_sink
();
void
add_sink
(
logger
::
sink_ptr
sink
);
void
add_sink
(
logger
::
sink_ptr
sink
);
void
remove_sink
(
logger
::
sink_ptr
sink_ptr
);
void
remove_sink
(
logger
::
sink_ptr
sink_ptr
);
//Wait to remaining items (if any) in the queue to be written and shutdown
//Wait to remaining items (if any) in the queue to be written and shutdown
void
shutdown
(
const
std
::
chrono
::
seconds
&
timeout
);
void
shutdown
(
const
std
::
chrono
::
seconds
&
timeout
);
protected
:
protected
:
void
_sink_it
(
const
bufpair_t
&
msg
)
override
;
void
_sink_it
(
const
bufpair_t
&
msg
)
override
;
void
_thread_loop
();
void
_thread_loop
();
private
:
private
:
c11log
::
logger
::
sinks_vector_t
_sinks
;
c11log
::
logger
::
sinks_vector_t
_sinks
;
std
::
atomic
<
bool
>
_active
;
std
::
atomic
<
bool
>
_active
;
c11log
::
details
::
blocking_queue
<
std
::
string
>
_q
;
c11log
::
details
::
blocking_queue
<
std
::
string
>
_q
;
std
::
thread
_back_thread
;
std
::
thread
_back_thread
;
//Clear all remaining messages(if any), stop the _back_thread and join it
//Clear all remaining messages(if any), stop the _back_thread and join it
void
_shutdown
();
void
_shutdown
();
};
};
}
}
}
}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// async_sink class implementation
// async_sink class implementation
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
inline
c11log
::
sinks
::
async_sink
::
async_sink
(
const
std
::
size_t
max_queue_size
)
inline
c11log
::
sinks
::
async_sink
::
async_sink
(
const
std
::
size_t
max_queue_size
)
:
_sinks
(),
:
_sinks
(),
_active
(
true
),
_active
(
true
),
_q
(
max_queue_size
),
_q
(
max_queue_size
),
_back_thread
(
&
async_sink
::
_thread_loop
,
this
)
_back_thread
(
&
async_sink
::
_thread_loop
,
this
)
{}
{}
inline
c11log
::
sinks
::
async_sink
::~
async_sink
()
inline
c11log
::
sinks
::
async_sink
::~
async_sink
()
{
{
_shutdown
();
_shutdown
();
}
}
inline
void
c11log
::
sinks
::
async_sink
::
_sink_it
(
const
bufpair_t
&
msg
)
inline
void
c11log
::
sinks
::
async_sink
::
_sink_it
(
const
bufpair_t
&
msg
)
{
{
std
::
string
s
{
msg
.
first
,
msg
.
first
+
msg
.
second
};
std
::
string
s
{
msg
.
first
,
msg
.
first
+
msg
.
second
};
_q
.
push
(
s
);
_q
.
push
(
s
);
}
}
inline
void
c11log
::
sinks
::
async_sink
::
_thread_loop
()
inline
void
c11log
::
sinks
::
async_sink
::
_thread_loop
()
{
{
static
std
::
chrono
::
seconds
pop_timeout
{
1
};
static
std
::
chrono
::
seconds
pop_timeout
{
1
};
std
::
string
msg
;
std
::
string
msg
;
while
(
_active
)
while
(
_active
)
{
{
if
(
_q
.
pop
(
msg
,
pop_timeout
))
if
(
_q
.
pop
(
msg
,
pop_timeout
))
{
{
bufpair_t
buf
(
msg
.
data
(),
msg
.
size
());
bufpair_t
buf
(
msg
.
data
(),
msg
.
size
());
for
(
auto
&
sink
:
_sinks
)
for
(
auto
&
sink
:
_sinks
)
{
{
sink
->
log
(
buf
,
static_cast
<
level
::
level_enum
>
(
_level
.
load
()));
sink
->
log
(
buf
,
static_cast
<
level
::
level_enum
>
(
_level
.
load
()));
if
(
!
_active
)
if
(
!
_active
)
return
;
return
;
}
}
}
}
}
}
}
}
inline
void
c11log
::
sinks
::
async_sink
::
add_sink
(
logger
::
sink_ptr
sink
)
inline
void
c11log
::
sinks
::
async_sink
::
add_sink
(
logger
::
sink_ptr
sink
)
{
{
_sinks
.
push_back
(
sink
);
_sinks
.
push_back
(
sink
);
}
}
inline
void
c11log
::
sinks
::
async_sink
::
remove_sink
(
logger
::
sink_ptr
sink_ptr
)
inline
void
c11log
::
sinks
::
async_sink
::
remove_sink
(
logger
::
sink_ptr
sink_ptr
)
{
{
_sinks
.
erase
(
std
::
remove
(
_sinks
.
begin
(),
_sinks
.
end
(),
sink_ptr
),
_sinks
.
end
());
_sinks
.
erase
(
std
::
remove
(
_sinks
.
begin
(),
_sinks
.
end
(),
sink_ptr
),
_sinks
.
end
());
}
}
inline
void
c11log
::
sinks
::
async_sink
::
shutdown
(
const
std
::
chrono
::
seconds
&
timeout
)
inline
void
c11log
::
sinks
::
async_sink
::
shutdown
(
const
std
::
chrono
::
seconds
&
timeout
)
{
{
auto
until
=
std
::
chrono
::
system_clock
::
now
()
+
timeout
;
auto
until
=
std
::
chrono
::
system_clock
::
now
()
+
timeout
;
while
(
_q
.
size
()
>
0
&&
std
::
chrono
::
system_clock
::
now
()
<
until
)
while
(
_q
.
size
()
>
0
&&
std
::
chrono
::
system_clock
::
now
()
<
until
)
{
{
std
::
this_thread
::
sleep_for
(
std
::
chrono
::
milliseconds
(
200
));
std
::
this_thread
::
sleep_for
(
std
::
chrono
::
milliseconds
(
200
));
}
}
_shutdown
();
_shutdown
();
}
}
inline
void
c11log
::
sinks
::
async_sink
::
_shutdown
()
inline
void
c11log
::
sinks
::
async_sink
::
_shutdown
()
{
{
if
(
_active
)
if
(
_active
)
{
{
_active
=
false
;
_active
=
false
;
if
(
_back_thread
.
joinable
())
if
(
_back_thread
.
joinable
())
_back_thread
.
join
();
_back_thread
.
join
();
}
}
}
}
include/c11log/sinks/base_sink.h
View file @
8494590f
#pragma once
#pragma once
#include<string>
#include<string>
#include<atomic>
#include<atomic>
#include "../formatter.h"
#include "../formatter.h"
#include "../common_types.h"
#include "../common_types.h"
namespace
c11log
namespace
c11log
{
{
namespace
sinks
namespace
sinks
{
{
class
base_sink
class
base_sink
{
{
public
:
public
:
base_sink
()
=
default
;
base_sink
()
=
default
;
base_sink
(
level
::
level_enum
l
)
:
_level
(
l
)
base_sink
(
level
::
level_enum
l
)
:
_level
(
l
)
{
{
};
};
virtual
~
base_sink
()
=
default
;
virtual
~
base_sink
()
=
default
;
base_sink
(
const
base_sink
&
)
=
delete
;
base_sink
(
const
base_sink
&
)
=
delete
;
base_sink
&
operator
=
(
const
base_sink
&
)
=
delete
;
base_sink
&
operator
=
(
const
base_sink
&
)
=
delete
;
void
log
(
const
bufpair_t
&
msg
,
level
::
level_enum
level
)
void
log
(
const
bufpair_t
&
msg
,
level
::
level_enum
level
)
{
{
if
(
level
>=
_level
)
if
(
level
>=
_level
)
{
{
_sink_it
(
msg
);
_sink_it
(
msg
);
}
}
};
};
void
set_level
(
level
::
level_enum
level
)
void
set_level
(
level
::
level_enum
level
)
{
{
_level
=
level
;
_level
=
level
;
}
}
protected
:
protected
:
virtual
void
_sink_it
(
const
bufpair_t
&
msg
)
=
0
;
virtual
void
_sink_it
(
const
bufpair_t
&
msg
)
=
0
;
std
::
atomic
<
int
>
_level
{
level
::
INFO
};
std
::
atomic
<
int
>
_level
{
level
::
INFO
};
};
};
class
null_sink
:
public
base_sink
class
null_sink
:
public
base_sink
{
{
protected
:
protected
:
void
_sink_it
(
const
bufpair_t
&
)
override
void
_sink_it
(
const
bufpair_t
&
)
override
{
{
}
}
};
};
}
}
}
}
include/c11log/sinks/console_sinks.h
View file @
8494590f
#pragma once
#pragma once
#include <iostream>
#include <iostream>
#include <mutex>
#include <mutex>
#include <memory>
#include <memory>
#include "base_sink.h"
#include "base_sink.h"
namespace
c11log
namespace
c11log
{
{
namespace
sinks
namespace
sinks
{
{
class
console_sink
:
public
base_sink
class
console_sink
:
public
base_sink
{
{
public
:
public
:
explicit
console_sink
(
std
::
ostream
&
os
)
:
_ostream
(
os
)
{}
explicit
console_sink
(
std
::
ostream
&
os
)
:
_ostream
(
os
)
{}
console_sink
(
const
console_sink
&
)
=
delete
;
console_sink
(
const
console_sink
&
)
=
delete
;
console_sink
&
operator
=
(
const
console_sink
&
)
=
delete
;
console_sink
&
operator
=
(
const
console_sink
&
)
=
delete
;
virtual
~
console_sink
()
=
default
;
virtual
~
console_sink
()
=
default
;
protected
:
protected
:
virtual
void
_sink_it
(
const
bufpair_t
&
msg
)
override
virtual
void
_sink_it
(
const
bufpair_t
&
msg
)
override
{
{
std
::
lock_guard
<
std
::
mutex
>
lock
(
_mutex
);
std
::
lock_guard
<
std
::
mutex
>
lock
(
_mutex
);
_ostream
.
write
(
msg
.
first
,
msg
.
second
);
_ostream
.
write
(
msg
.
first
,
msg
.
second
);
}
}
std
::
ostream
&
_ostream
;
std
::
ostream
&
_ostream
;
std
::
mutex
_mutex
;
std
::
mutex
_mutex
;
};
};
inline
std
::
shared_ptr
<
console_sink
>&
stdout_sink
()
inline
std
::
shared_ptr
<
console_sink
>&
stdout_sink
()
{
{
static
auto
inst
=
std
::
make_shared
<
console_sink
>
(
std
::
cout
);
static
auto
inst
=
std
::
make_shared
<
console_sink
>
(
std
::
cout
);
return
inst
;
return
inst
;
}
}
inline
std
::
shared_ptr
<
console_sink
>&
stderr_sink
()
inline
std
::
shared_ptr
<
console_sink
>&
stderr_sink
()
{
{
static
auto
inst
=
std
::
make_shared
<
console_sink
>
(
std
::
cerr
);
static
auto
inst
=
std
::
make_shared
<
console_sink
>
(
std
::
cerr
);
return
inst
;
return
inst
;
}
}
}
}
}
}
include/c11log/sinks/file_sinks.h
View file @
8494590f
This diff is collapsed.
Click to expand it.
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