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
f795297e
Commit
f795297e
authored
Sep 04, 2019
by
gabime
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
try different apprach to backtracer object
parent
3fd3c47e
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
188 additions
and
106 deletions
+188
-106
backtracer.h
include/spdlog/details/backtracer.h
+76
-34
circular_q.h
include/spdlog/details/circular_q.h
+96
-57
log_msg_buffer.h
include/spdlog/details/log_msg_buffer.h
+8
-0
logger-inl.h
include/spdlog/logger-inl.h
+6
-10
logger.h
include/spdlog/logger.h
+2
-5
No files found.
include/spdlog/details/backtracer.h
View file @
f795297e
...
@@ -13,39 +13,80 @@
...
@@ -13,39 +13,80 @@
// Useful for storing debug data in case of error/warning happens.
// Useful for storing debug data in case of error/warning happens.
namespace
spdlog
{
namespace
spdlog
{
namespace
details
{
namespace
details
{
class
backtracer
class
backtracer
{
std
::
mutex
mutex_
;
size_t
n_messages_
;
circular_q
<
log_msg_buffer
>
messages_
;
public
:
explicit
backtracer
(
size_t
n_messages
)
:
n_messages_
{
n_messages
},
messages_
{
n_messages
}
{}
size_t
n_messages
()
const
{
return
n_messages_
;
}
void
add
(
const
log_msg
&
msg
)
{
std
::
lock_guard
<
std
::
mutex
>
lock
{
mutex_
};
messages_
.
push_back
(
log_msg_buffer
{
msg
});
}
// pop all items in the q and apply the given fun on each of them.
void
foreach_pop
(
std
::
function
<
void
(
const
details
::
log_msg
&
)
>
fun
)
{
std
::
lock_guard
<
std
::
mutex
>
lock
{
mutex_
};
while
(
!
messages_
.
empty
())
{
{
log_msg_buffer
popped
;
mutable
std
::
mutex
mutex_
;
messages_
.
pop_front
(
popped
);
std
::
atomic
<
bool
>
enabled_
{
false
};
fun
(
popped
);
circular_q
<
log_msg_buffer
>
messages_
;
}
}
public
:
};
backtracer
()
=
default
;
}
// namespace details
backtracer
(
const
backtracer
&
other
)
{
std
::
lock_guard
<
std
::
mutex
>
lock
(
other
.
mutex_
);
enabled_
=
other
.
enabled
();
messages_
=
other
.
messages_
;
}
backtracer
(
backtracer
&&
other
)
SPDLOG_NOEXCEPT
{
std
::
lock_guard
<
std
::
mutex
>
lock
(
other
.
mutex_
);
enabled_
=
other
.
enabled
();
messages_
=
std
::
move
(
other
.
messages_
);
}
backtracer
&
operator
=
(
backtracer
other
)
{
std
::
lock_guard
<
std
::
mutex
>
lock
(
mutex_
);
enabled_
=
other
.
enabled
();
messages_
=
other
.
messages_
;
return
*
this
;
}
void
enable
(
size_t
size
)
{
std
::
lock_guard
<
std
::
mutex
>
lock
{
mutex_
};
enabled_
.
store
(
true
,
std
::
memory_order_relaxed
);
messages_
=
circular_q
<
log_msg_buffer
>
{
size
};
}
void
disable
()
{
std
::
lock_guard
<
std
::
mutex
>
lock
{
mutex_
};
enabled_
.
store
(
false
,
std
::
memory_order_relaxed
);
}
bool
enabled
()
const
{
return
enabled_
.
load
(
std
::
memory_order_relaxed
);
}
operator
bool
()
const
{
return
enabled
();
}
void
push_back
(
const
log_msg
&
msg
)
{
std
::
lock_guard
<
std
::
mutex
>
lock
{
mutex_
};
messages_
.
push_back
(
log_msg_buffer
{
msg
});
}
// pop all items in the q and apply the given fun on each of them.
void
foreach_pop
(
std
::
function
<
void
(
const
details
::
log_msg
&
)
>
fun
)
{
std
::
lock_guard
<
std
::
mutex
>
lock
{
mutex_
};
while
(
!
messages_
.
empty
())
{
log_msg_buffer
popped
;
messages_
.
pop_front
(
popped
);
fun
(
popped
);
}
}
};
}
// namespace details
}
// namespace spdlog
}
// namespace spdlog
\ No newline at end of file
include/spdlog/details/circular_q.h
View file @
f795297e
...
@@ -7,62 +7,101 @@
...
@@ -7,62 +7,101 @@
#include <vector>
#include <vector>
namespace
spdlog
{
namespace
spdlog
{
namespace
details
{
namespace
details
{
template
<
typename
T
>
template
<
typename
T
>
class
circular_q
class
circular_q
{
public
:
using
item_type
=
T
;
explicit
circular_q
(
size_t
max_items
)
:
max_items_
(
max_items
+
1
)
// one item is reserved as marker for full q
,
v_
(
max_items_
)
{}
// push back, overrun (oldest) item if no room left
void
push_back
(
T
&&
item
)
{
v_
[
tail_
]
=
std
::
move
(
item
);
tail_
=
(
tail_
+
1
)
%
max_items_
;
if
(
tail_
==
head_
)
// overrun last item if full
{
{
head_
=
(
head_
+
1
)
%
max_items_
;
public
:
++
overrun_counter_
;
using
item_type
=
T
;
}
}
// empty cir
circular_q
()
=
default
;
// Pop item from front.
// If there are no elements in the container, the behavior is undefined.
explicit
circular_q
(
size_t
max_items
)
void
pop_front
(
T
&
popped_item
)
:
max_items_
(
max_items
+
1
)
// one item is reserved as marker for full q
{
,
v_
(
max_items_
)
popped_item
=
std
::
move
(
v_
[
head_
]);
{}
head_
=
(
head_
+
1
)
%
max_items_
;
}
bool
empty
()
circular_q
(
const
circular_q
&
)
=
default
;
{
circular_q
&
operator
=
(
const
circular_q
&
)
=
default
;
return
tail_
==
head_
;
}
// move cannot be default,
// since we need to reset head_, tail_, etc to zero in the moved object
bool
full
()
circular_q
(
circular_q
&&
other
)
SPDLOG_NOEXCEPT
:
{
{
// head is ahead of the tail by 1
copy_moveable
(
std
::
move
(
other
));
return
((
tail_
+
1
)
%
max_items_
)
==
head_
;
}
}
circular_q
&
operator
=
(
circular_q
&&
other
)
SPDLOG_NOEXCEPT
size_t
overrun_counter
()
const
{
{
copy_moveable
(
std
::
move
(
other
));
return
overrun_counter_
;
return
*
this
;
}
}
private
:
size_t
max_items_
;
// push back, overrun (oldest) item if no room left
typename
std
::
vector
<
T
>::
size_type
head_
=
0
;
void
push_back
(
T
&&
item
)
typename
std
::
vector
<
T
>::
size_type
tail_
=
0
;
{
size_t
overrun_counter_
=
0
;
if
(
max_items_
>
0
)
std
::
vector
<
T
>
v_
;
{
v_
[
tail_
]
=
std
::
move
(
item
);
};
tail_
=
(
tail_
+
1
)
%
max_items_
;
}
// namespace details
if
(
tail_
==
head_
)
// overrun last item if full
{
head_
=
(
head_
+
1
)
%
max_items_
;
++
overrun_counter_
;
}
}
}
// Pop item from front.
// If there are no elements in the container, the behavior is undefined.
void
pop_front
(
T
&
popped_item
)
{
if
(
max_items_
>
0
)
{
popped_item
=
std
::
move
(
v_
[
head_
]);
head_
=
(
head_
+
1
)
%
max_items_
;
}
}
bool
empty
()
{
return
tail_
==
head_
;
}
bool
full
()
{
// head is ahead of the tail by 1
return
((
tail_
+
1
)
%
max_items_
)
==
head_
;
}
size_t
overrun_counter
()
const
{
return
overrun_counter_
;
}
private
:
size_t
max_items_
=
0
;
typename
std
::
vector
<
T
>::
size_type
head_
=
0
;
typename
std
::
vector
<
T
>::
size_type
tail_
=
0
;
size_t
overrun_counter_
=
0
;
std
::
vector
<
T
>
v_
;
void
copy_moveable
(
circular_q
&&
other
)
SPDLOG_NOEXCEPT
{
max_items_
=
other
.
max_items_
;
head_
=
other
.
head_
;
tail_
=
other
.
tail_
;
overrun_counter_
=
other
.
overrun_counter_
,
v_
=
std
::
move
(
other
.
v_
);
other
.
max_items_
=
0
;
// disable other
}
};
}
// namespace details
}
// namespace spdlog
}
// namespace spdlog
include/spdlog/details/log_msg_buffer.h
View file @
f795297e
...
@@ -47,6 +47,14 @@ public:
...
@@ -47,6 +47,14 @@ public:
update_string_views
();
update_string_views
();
}
}
log_msg_buffer
&
operator
=
(
log_msg_buffer
&
other
)
{
log_msg
::
operator
=
(
other
);
buffer
.
append
(
other
.
buffer
.
begin
(),
other
.
buffer
.
end
());
update_string_views
();
return
*
this
;
}
log_msg_buffer
&
operator
=
(
log_msg_buffer
&&
other
)
log_msg_buffer
&
operator
=
(
log_msg_buffer
&&
other
)
{
{
log_msg
::
operator
=
(
std
::
move
(
other
));
log_msg
::
operator
=
(
std
::
move
(
other
));
...
...
include/spdlog/logger-inl.h
View file @
f795297e
...
@@ -23,11 +23,7 @@ SPDLOG_INLINE logger::logger(const logger &other)
...
@@ -23,11 +23,7 @@ SPDLOG_INLINE logger::logger(const logger &other)
,
flush_level_
(
other
.
flush_level_
.
load
(
std
::
memory_order_relaxed
))
,
flush_level_
(
other
.
flush_level_
.
load
(
std
::
memory_order_relaxed
))
,
custom_err_handler_
(
other
.
custom_err_handler_
)
,
custom_err_handler_
(
other
.
custom_err_handler_
)
,
tracer_
(
other
.
tracer_
)
,
tracer_
(
other
.
tracer_
)
{
{
if
(
tracer_
)
{
enable_backtrace
(
tracer_
->
n_messages
());
}
}
}
SPDLOG_INLINE
logger
::
logger
(
logger
&&
other
)
SPDLOG_NOEXCEPT
:
name_
(
std
::
move
(
other
.
name_
)),
SPDLOG_INLINE
logger
::
logger
(
logger
&&
other
)
SPDLOG_NOEXCEPT
:
name_
(
std
::
move
(
other
.
name_
)),
...
@@ -61,7 +57,7 @@ SPDLOG_INLINE void logger::swap(spdlog::logger &other) SPDLOG_NOEXCEPT
...
@@ -61,7 +57,7 @@ SPDLOG_INLINE void logger::swap(spdlog::logger &other) SPDLOG_NOEXCEPT
other
.
flush_level_
.
store
(
tmp
);
other
.
flush_level_
.
store
(
tmp
);
custom_err_handler_
.
swap
(
other
.
custom_err_handler_
);
custom_err_handler_
.
swap
(
other
.
custom_err_handler_
);
tracer_
.
swap
(
other
.
tracer_
);
std
::
swap
(
tracer_
,
other
.
tracer_
);
}
}
SPDLOG_INLINE
void
swap
(
logger
&
a
,
logger
&
b
)
SPDLOG_INLINE
void
swap
(
logger
&
a
,
logger
&
b
)
...
@@ -116,13 +112,13 @@ SPDLOG_INLINE void logger::set_pattern(std::string pattern, pattern_time_type ti
...
@@ -116,13 +112,13 @@ SPDLOG_INLINE void logger::set_pattern(std::string pattern, pattern_time_type ti
// create new backtrace sink and move to it all our child sinks
// create new backtrace sink and move to it all our child sinks
SPDLOG_INLINE
void
logger
::
enable_backtrace
(
size_t
n_messages
)
SPDLOG_INLINE
void
logger
::
enable_backtrace
(
size_t
n_messages
)
{
{
tracer_
=
std
::
make_shared
<
details
::
backtracer
>
(
n_messages
);
tracer_
.
enable
(
n_messages
);
}
}
// restore orig sinks and level and delete the backtrace sink
// restore orig sinks and level and delete the backtrace sink
SPDLOG_INLINE
void
logger
::
disable_backtrace
()
SPDLOG_INLINE
void
logger
::
disable_backtrace
()
{
{
tracer_
.
reset
();
tracer_
.
disable
();
}
}
SPDLOG_INLINE
void
logger
::
dump_backtrace
()
SPDLOG_INLINE
void
logger
::
dump_backtrace
()
...
@@ -206,7 +202,7 @@ SPDLOG_INLINE void logger::flush_()
...
@@ -206,7 +202,7 @@ SPDLOG_INLINE void logger::flush_()
SPDLOG_INLINE
void
logger
::
backtrace_add_
(
const
details
::
log_msg
&
msg
)
SPDLOG_INLINE
void
logger
::
backtrace_add_
(
const
details
::
log_msg
&
msg
)
{
{
tracer_
->
add
(
msg
);
tracer_
.
push_back
(
msg
);
}
}
SPDLOG_INLINE
void
logger
::
dump_backtrace_
()
SPDLOG_INLINE
void
logger
::
dump_backtrace_
()
...
@@ -215,7 +211,7 @@ SPDLOG_INLINE void logger::dump_backtrace_()
...
@@ -215,7 +211,7 @@ SPDLOG_INLINE void logger::dump_backtrace_()
if
(
tracer_
)
if
(
tracer_
)
{
{
sink_it_
(
log_msg
{
name
(),
level
::
info
,
"****************** Backtrace Start ******************"
});
sink_it_
(
log_msg
{
name
(),
level
::
info
,
"****************** Backtrace Start ******************"
});
tracer_
->
foreach_pop
([
this
](
const
details
::
log_msg
&
msg
)
{
this
->
sink_it_
(
msg
);
});
tracer_
.
foreach_pop
([
this
](
const
details
::
log_msg
&
msg
)
{
this
->
sink_it_
(
msg
);
});
sink_it_
(
log_msg
{
name
(),
level
::
info
,
"****************** Backtrace End ********************"
});
sink_it_
(
log_msg
{
name
(),
level
::
info
,
"****************** Backtrace End ********************"
});
}
}
}
}
...
...
include/spdlog/logger.h
View file @
f795297e
...
@@ -17,6 +17,7 @@
...
@@ -17,6 +17,7 @@
#include "spdlog/common.h"
#include "spdlog/common.h"
#include "spdlog/details/log_msg.h"
#include "spdlog/details/log_msg.h"
#include "spdlog/details/backtracer.h"
#ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT
#ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT
#include "spdlog/details/os.h"
#include "spdlog/details/os.h"
...
@@ -39,10 +40,6 @@
...
@@ -39,10 +40,6 @@
namespace
spdlog
{
namespace
spdlog
{
namespace
details
{
class
backtracer
;
}
class
logger
class
logger
{
{
public
:
public
:
...
@@ -365,7 +362,7 @@ protected:
...
@@ -365,7 +362,7 @@ protected:
spdlog
::
level_t
level_
{
level
::
info
};
spdlog
::
level_t
level_
{
level
::
info
};
spdlog
::
level_t
flush_level_
{
level
::
off
};
spdlog
::
level_t
flush_level_
{
level
::
off
};
err_handler
custom_err_handler_
{
nullptr
};
err_handler
custom_err_handler_
{
nullptr
};
std
::
shared_ptr
<
details
::
backtracer
>
tracer_
;
details
::
backtracer
tracer_
;
virtual
void
sink_it_
(
const
details
::
log_msg
&
msg
);
virtual
void
sink_it_
(
const
details
::
log_msg
&
msg
);
virtual
void
flush_
();
virtual
void
flush_
();
...
...
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