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
6b527a50
Commit
6b527a50
authored
Aug 22, 2019
by
gabime
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
backtrace sink and refactoring
parent
74df115f
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
181 additions
and
49 deletions
+181
-49
bench/async_bench.cpp
bench/async_bench.cpp
+2
-0
include/spdlog/details/log_msg.h
include/spdlog/details/log_msg.h
+4
-2
include/spdlog/details/log_msg_buffer.h
include/spdlog/details/log_msg_buffer.h
+62
-0
include/spdlog/details/thread_pool-inl.h
include/spdlog/details/thread_pool-inl.h
+1
-2
include/spdlog/details/thread_pool.h
include/spdlog/details/thread_pool.h
+14
-45
include/spdlog/sinks/backtrace-sink.h
include/spdlog/sinks/backtrace-sink.h
+98
-0
No files found.
bench/async_bench.cpp
View file @
6b527a50
...
@@ -115,6 +115,8 @@ int main(int argc, char *argv[])
...
@@ -115,6 +115,8 @@ int main(int argc, char *argv[])
auto
file_sink
=
std
::
make_shared
<
spdlog
::
sinks
::
basic_file_sink_mt
>
(
filename
,
true
);
auto
file_sink
=
std
::
make_shared
<
spdlog
::
sinks
::
basic_file_sink_mt
>
(
filename
,
true
);
auto
logger
=
std
::
make_shared
<
async_logger
>
(
"async_logger"
,
std
::
move
(
file_sink
),
std
::
move
(
tp
),
async_overflow_policy
::
block
);
auto
logger
=
std
::
make_shared
<
async_logger
>
(
"async_logger"
,
std
::
move
(
file_sink
),
std
::
move
(
tp
),
async_overflow_policy
::
block
);
bench_mt
(
howmany
,
std
::
move
(
logger
),
threads
);
bench_mt
(
howmany
,
std
::
move
(
logger
),
threads
);
verify_file
(
filename
,
howmany
);
#ifdef SPDLOG_ASYNC_BENCH_VERIFY
#ifdef SPDLOG_ASYNC_BENCH_VERIFY
verify_file
(
filename
,
howmany
);
verify_file
(
filename
,
howmany
);
#endif // SPDLOG_ASYNC_BENCH_VERIFY
#endif // SPDLOG_ASYNC_BENCH_VERIFY
...
...
include/spdlog/details/log_msg.h
View file @
6b527a50
...
@@ -4,16 +4,18 @@
...
@@ -4,16 +4,18 @@
#pragma once
#pragma once
#include "spdlog/common.h"
#include "spdlog/common.h"
#include <string>
namespace
spdlog
{
namespace
spdlog
{
namespace
details
{
namespace
details
{
struct
log_msg
struct
log_msg
{
{
log_msg
()
=
default
;
log_msg
(
source_loc
loc
,
string_view_t
logger_name
,
level
::
level_enum
lvl
,
string_view_t
msg
);
log_msg
(
source_loc
loc
,
string_view_t
logger_name
,
level
::
level_enum
lvl
,
string_view_t
msg
);
log_msg
(
string_view_t
logger_name
,
level
::
level_enum
lvl
,
string_view_t
msg
);
log_msg
(
string_view_t
logger_name
,
level
::
level_enum
lvl
,
string_view_t
msg
);
log_msg
(
const
log_msg
&
other
)
=
default
;
log_msg
(
const
log_msg
&
other
)
=
default
;
const
string_view_t
logger_name
;
string_view_t
logger_name
;
level
::
level_enum
level
{
level
::
off
};
level
::
level_enum
level
{
level
::
off
};
log_clock
::
time_point
time
;
log_clock
::
time_point
time
;
size_t
thread_id
{
0
};
size_t
thread_id
{
0
};
...
@@ -23,7 +25,7 @@ struct log_msg
...
@@ -23,7 +25,7 @@ struct log_msg
mutable
size_t
color_range_end
{
0
};
mutable
size_t
color_range_end
{
0
};
source_loc
source
;
source_loc
source
;
const
string_view_t
payload
;
string_view_t
payload
;
};
};
}
// namespace details
}
// namespace details
}
// namespace spdlog
}
// namespace spdlog
...
...
include/spdlog/details/log_msg_buffer.h
0 → 100644
View file @
6b527a50
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
#pragma once
#include "spdlog/details/log_msg.h"
#include "spdlog/fmt/bundled/core.h"
namespace
spdlog
{
namespace
details
{
// regular log_msgs only holds string_views to stack data - so the cannot be stored for later use.
// this one can, since it contains and owns the payload buffer.
struct
log_msg_buffer
:
log_msg
{
fmt
::
basic_memory_buffer
<
char
,
40
>
loggername_buf
;
fmt
::
basic_memory_buffer
<
char
,
200
>
payload_buf
;
log_msg_buffer
()
=
default
;
log_msg_buffer
(
const
log_msg
&
orig_msg
)
:
log_msg
(
orig_msg
)
{
update_buffers
();
}
log_msg_buffer
(
const
log_msg_buffer
&
other
)
:
log_msg
(
other
)
{
update_buffers
();
}
log_msg_buffer
(
const
log_msg_buffer
&&
other
)
:
log_msg
(
std
::
move
(
other
))
{
update_buffers
();
}
log_msg_buffer
&
operator
=
(
log_msg_buffer
&
other
)
SPDLOG_NOEXCEPT
{
*
static_cast
<
log_msg
*>
(
this
)
=
other
;
update_buffers
();
return
*
this
;
}
log_msg_buffer
&
operator
=
(
log_msg_buffer
&&
other
)
SPDLOG_NOEXCEPT
{
*
static_cast
<
log_msg
*>
(
this
)
=
std
::
move
(
other
);
update_buffers
();
return
*
this
;
}
void
update_buffers
()
SPDLOG_NOEXCEPT
{
loggername_buf
.
clear
();
loggername_buf
.
append
(
logger_name
.
data
(),
logger_name
.
data
()
+
logger_name
.
size
());
logger_name
=
string_view_t
{
loggername_buf
.
data
(),
loggername_buf
.
size
()};
payload_buf
.
clear
();
payload_buf
.
append
(
payload
.
data
(),
payload
.
data
()
+
payload
.
size
());
payload
=
string_view_t
{
payload_buf
.
data
(),
payload_buf
.
size
()};
}
};
}
}
\ No newline at end of file
include/spdlog/details/thread_pool-inl.h
View file @
6b527a50
...
@@ -100,8 +100,7 @@ bool SPDLOG_INLINE thread_pool::process_next_msg_()
...
@@ -100,8 +100,7 @@ bool SPDLOG_INLINE thread_pool::process_next_msg_()
{
{
case
async_msg_type
:
:
log
:
case
async_msg_type
:
:
log
:
{
{
auto
msg
=
incoming_async_msg
.
to_log_msg
();
incoming_async_msg
.
worker_ptr
->
backend_log_
(
incoming_async_msg
);
incoming_async_msg
.
worker_ptr
->
backend_log_
(
msg
);
return
true
;
return
true
;
}
}
case
async_msg_type
:
:
flush
:
case
async_msg_type
:
:
flush
:
...
...
include/spdlog/details/thread_pool.h
View file @
6b527a50
...
@@ -3,10 +3,11 @@
...
@@ -3,10 +3,11 @@
#pragma once
#pragma once
#include "spdlog/details/log_msg.h"
#include "spdlog/details/log_msg
_buffer
.h"
#include "spdlog/details/mpmc_blocking_q.h"
#include "spdlog/details/mpmc_blocking_q.h"
#include "spdlog/details/os.h"
#include "spdlog/details/os.h"
#include <chrono>
#include <chrono>
#include <memory>
#include <memory>
#include <thread>
#include <thread>
...
@@ -27,17 +28,12 @@ enum class async_msg_type
...
@@ -27,17 +28,12 @@ enum class async_msg_type
terminate
terminate
};
};
#include "spdlog/details/log_msg_buffer.h"
// Async msg to move to/from the queue
// Async msg to move to/from the queue
// Movable only. should never be copied
// Movable only. should never be copied
struct
async_msg
struct
async_msg
:
log_msg_buffer
{
{
async_msg_type
msg_type
{
async_msg_type
::
log
};
async_msg_type
msg_type
{
async_msg_type
::
log
};
level
::
level_enum
level
{
level
::
info
};
log_clock
::
time_point
time
;
size_t
thread_id
{
0
};
fmt
::
basic_memory_buffer
<
char
,
176
>
raw
;
source_loc
source
;
async_logger_ptr
worker_ptr
;
async_logger_ptr
worker_ptr
;
async_msg
()
=
default
;
async_msg
()
=
default
;
...
@@ -49,51 +45,35 @@ struct async_msg
...
@@ -49,51 +45,35 @@ struct async_msg
// support for vs2013 move
// support for vs2013 move
#if defined(_MSC_VER) && _MSC_VER <= 1800
#if defined(_MSC_VER) && _MSC_VER <= 1800
async_msg
(
async_msg
&&
other
)
async_msg
(
async_msg
&&
other
)
:
msg_type
(
other
.
msg_type
)
:
log_msg_buffer
(
std
::
move
(
other
))
,
level
(
other
.
level
)
,
msg_type
(
other
.
msg_type
)
,
time
(
other
.
time
)
,
thread_id
(
other
.
thread_id
)
,
raw
(
move
(
other
.
raw
))
,
msg_id
(
other
.
msg_id
)
,
source
(
other
.
source
)
,
worker_ptr
(
std
::
move
(
other
.
worker_ptr
))
,
worker_ptr
(
std
::
move
(
other
.
worker_ptr
))
{}
{}
async_msg
&
operator
=
(
async_msg
&&
other
)
async_msg
&
operator
=
(
async_msg
&&
other
)
{
{
*
static_cast
<
log_msg_buffer
*>
(
this
)
=
std
::
move
(
other
);
msg_type
=
other
.
msg_type
;
msg_type
=
other
.
msg_type
;
level
=
other
.
level
;
time
=
other
.
time
;
thread_id
=
other
.
thread_id
;
raw
=
std
::
move
(
other
.
raw
);
msg_id
=
other
.
msg_id
;
source
=
other
.
source
;
worker_ptr
=
std
::
move
(
other
.
worker_ptr
);
worker_ptr
=
std
::
move
(
other
.
worker_ptr
);
return
*
this
;
return
*
this
;
}
}
#else // (_MSC_VER) && _MSC_VER <= 1800
#else // (_MSC_VER) && _MSC_VER <= 1800
async_msg
(
async_msg
&&
)
=
default
;
async_msg
(
async_msg
&&
)
SPDLOG_NOEXCEPT
=
default
;
async_msg
&
operator
=
(
async_msg
&&
)
=
default
;
async_msg
&
operator
=
(
async_msg
&&
)
SPDLOG_NOEXCEPT
=
default
;
#endif
#endif
// construct from log_msg with given type
// construct from log_msg with given type
async_msg
(
async_logger_ptr
&&
worker
,
async_msg_type
the_type
,
details
::
log_msg
&
m
)
async_msg
(
async_logger_ptr
&&
worker
,
async_msg_type
the_type
,
details
::
log_msg
&
m
)
:
msg_type
(
the_type
)
:
log_msg_buffer
(
m
)
,
level
(
m
.
level
)
,
msg_type
(
the_type
)
,
time
(
m
.
time
)
,
thread_id
(
m
.
thread_id
)
,
source
(
m
.
source
)
,
worker_ptr
(
std
::
move
(
worker
))
,
worker_ptr
(
std
::
move
(
worker
))
{
{
raw
.
append
(
m
.
payload
.
data
(),
m
.
payload
.
data
()
+
m
.
payload
.
size
());
}
}
async_msg
(
async_logger_ptr
&&
worker
,
async_msg_type
the_type
)
async_msg
(
async_logger_ptr
&&
worker
,
async_msg_type
the_type
)
:
msg_type
(
the_type
)
:
log_msg_buffer
()
,
level
(
level
::
off
)
,
msg_type
(
the_type
)
,
time
()
,
thread_id
(
0
)
,
source
()
,
worker_ptr
(
std
::
move
(
worker
))
,
worker_ptr
(
std
::
move
(
worker
))
{}
{}
...
@@ -101,17 +81,6 @@ struct async_msg
...
@@ -101,17 +81,6 @@ struct async_msg
:
async_msg
(
nullptr
,
the_type
)
:
async_msg
(
nullptr
,
the_type
)
{}
{}
// copy into log_msg
log_msg
to_log_msg
()
{
log_msg
msg
(
string_view_t
(
worker_ptr
->
name
()),
level
,
string_view_t
(
raw
.
data
(),
raw
.
size
()));
msg
.
time
=
time
;
msg
.
thread_id
=
thread_id
;
msg
.
source
=
source
;
msg
.
color_range_start
=
0
;
msg
.
color_range_end
=
0
;
return
msg
;
}
};
};
class
thread_pool
class
thread_pool
...
...
include/spdlog/sinks/backtrace-sink.h
0 → 100644
View file @
6b527a50
// Copyright(c) 2015-present, Gabi Melman & spdlog contributors.
// Distributed under the MIT License (http://opensource.org/licenses/MIT)
#pragma once
#include "dist_sink.h"
#include "spdlog/details/null_mutex.h"
#include "spdlog/details/log_msg.h"
#include "spdlog/details/log_msg_buffer.h"
#include "spdlog/details/circular_q.h"
#include <mutex>
#include <string>
#include <chrono>
// Store log messages in circular buffer
// If it encounters a message with high enough level, it will send all pervious message to its child sinks
// Useful for storing debug data in case of error/warning happens
//
// Example:
//
// #include "spdlog/spdlog.h"
// #include "spdlog/sinks/backtrace_sink.h
//
// int main() {
// auto backtrace_sink = std::make_shared<backtrace_sink>();
// backtrace_sink ->add_sink(std::make_shared<stdout_color_sink_mt>());
// spdlog::logger l("logger", backtrace_sink);
// logger.set_level(spdlog::level::trace);
// l.trace("Hello");
// l.debug("Hello");
// l.info("Hello");
// l.warn("This will trigger the log of all prev messages in the queue");
// }
namespace
spdlog
{
namespace
sinks
{
template
<
typename
Mutex
>
class
backtrace_sink
:
public
dist_sink
<
Mutex
>
{
public:
explicit
backtrace_sink
(
level
::
level_enum
trigger_level
=
spdlog
::
level
::
warn
,
size_t
n_messages
=
32
)
:
trigger_level_
{
trigger_level
},
traceback_msgs_
{
n_messages
}
{}
protected:
level
::
level_enum
trigger_level_
;
details
::
circular_q
<
details
::
log_msg_buffer
>
traceback_msgs_
;
// if current message is high enough, trigger a backtrace log,
// otherwise save the message in the queue for future trigger.
void
sink_it_
(
const
details
::
log_msg
&
msg
)
override
{
if
(
msg
.
level
<
trigger_level_
)
{
traceback_msgs_
.
push_back
(
details
::
log_msg_buffer
(
msg
));
}
if
(
msg
.
level
>
level
::
debug
)
{
dist_sink
<
Mutex
>::
sink_it_
(
msg
);
}
if
(
msg
.
level
>=
trigger_level_
)
{
log_backtrace_
(
msg
.
logger_name
);
}
}
void
log_backtrace_
(
const
string_view_t
&
logger_name
)
{
if
(
traceback_msgs_
.
empty
())
{
return
;
}
dist_sink
<
Mutex
>::
sink_it_
(
details
::
log_msg
{
logger_name
,
level
::
info
,
"********************* [Backtrace Start] *********************"
});
do
{
details
::
log_msg_buffer
popped
;
traceback_msgs_
.
pop_front
(
popped
);
dist_sink
<
Mutex
>::
sink_it_
(
popped
);
}
while
(
!
traceback_msgs_
.
empty
());
dist_sink
<
Mutex
>::
sink_it_
(
details
::
log_msg
{
logger_name
,
level
::
info
,
"********************* [Backtrace End] ***********************"
});
}
};
using
backtrace_sink_mt
=
backtrace_sink
<
std
::
mutex
>
;
using
backtrace_sink_st
=
backtrace_sink
<
details
::
null_mutex
>
;
}
// namespace sinks
}
// 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