Go to the documentation of this file.
    9 #ifndef EAGINE_LOGGING_OSTREAM_BACKEND_HPP 
   10 #define EAGINE_LOGGING_OSTREAM_BACKEND_HPP 
   12 #include "../base64dump.hpp" 
   13 #include "../memory/aligned_block.hpp" 
   14 #include "../memory/stack_alloc.hpp" 
   21 template <
typename Lockable = std::mutex>
 
   22 class ostream_log_backend : 
public logger_backend {
 
   27     const std::chrono::steady_clock::time_point _start;
 
   28     memory::aligned_block<63 * 1024> _alloc_block{};
 
   31     virtual void flush() noexcept {}
 
   38       , _min_severity{min_severity}
 
   39       , _start{std::chrono::steady_clock::now()} {
 
   41             std::unique_lock lock{_lockable};
 
   42             _out << 
"<?xml version='1.0' encoding='UTF-8'?>\n";
 
   43             _out << 
"<log start='" << _start.time_since_epoch().count()
 
   49     ostream_log_backend(ostream_log_backend&&) = 
delete;
 
   50     ostream_log_backend(
const ostream_log_backend&) = 
delete;
 
   51     auto operator=(ostream_log_backend&&) = 
delete;
 
   52     auto operator=(
const ostream_log_backend&) = 
delete;
 
   54     auto allocator() noexcept -> memory::shared_byte_allocator final {
 
   55         return memory::default_byte_allocator();
 
   65       -> logger_backend* 
final {
 
   66         if(severity >= _min_severity) {
 
   72     void enter_scope(
identifier scope) noexcept 
final {
 
   75             _out << 
"<s name='" << scope.name() << 
"'>\n";
 
   94             std::unique_lock lock{_lockable};
 
   96             _out << 
" src='" << source.name() << 
"'";
 
   97             _out << 
" iid='" << instance << 
"'";
 
   98             _out << 
" dn='" << display_name << 
"'";
 
   99             _out << 
" desc='" << description << 
"'";
 
  113             const auto now = std::chrono::steady_clock::now();
 
  114             const auto sec = std::chrono::duration<float>(now - _start);
 
  117             _out << 
" lvl='" << enumerator_name(severity) << 
"'";
 
  118             _out << 
" src='" << source.name() << 
"'";
 
  120                 _out << 
" tag='" << tag.name() << 
"'";
 
  122             _out << 
" iid='" << instance << 
"'";
 
  123             _out << 
" ts='" << sec.count() << 
"'";
 
  125             _out << 
"<f>" << 
format << 
"</f>";
 
  133             _out << 
"<a n='" << arg.name() << 
"' t='" << tag.name() << 
"'/>";
 
  143             _out << 
"<a n='" << arg.name() << 
"' t='" << tag.name() << 
"'>" 
  144                  << value.name() << 
"</a>";
 
  152       message_id msg_id) noexcept 
final {
 
  154             _out << 
"<a n='" << arg.name() << 
"' t='" << tag.name() << 
"'>" 
  155                  << msg_id.class_().name() << 
"." << msg_id.method().name()
 
  163             _out << 
"<a n='" << arg.name() << 
"' t='" << tag.name() << 
"'>" 
  164                  << (value ? 
"true" : 
"false") << 
"</a>";
 
  172       std::intmax_t value) noexcept 
final {
 
  174             _out << 
"<a n='" << arg.name() << 
"' t='" << tag.name() << 
"'>" 
  183       std::uintmax_t value) noexcept 
final {
 
  185             _out << 
"<a n='" << arg.name() << 
"' t='" << tag.name() << 
"'>" 
  193             _out << 
"<a n='" << arg.name() << 
"' t='" << tag.name() << 
"'>" 
  204       float max) noexcept 
final {
 
  206             _out << 
"<a n='" << arg.name() << 
"' t='" << tag.name() << 
"' min='" 
  207                  << min << 
"' max='" << max << 
"'>" << value << 
"</a>";
 
  215       std::chrono::duration<float> value) noexcept 
final {
 
  217             _out << 
"<a n='" << arg.name() << 
"' t='" << tag.name()
 
  218                  << 
"' u='s'>" << value.count() << 
"</a>";
 
  228             _out << 
"<a n='" << arg.name() << 
"' t='" << tag.name()
 
  229                  << 
"' blob='true'>" << base64dump(value) << 
"</a>";
 
  237             _out << 
"<a n='" << arg.name() << 
"' t='" << tag.name() << 
"'>" 
  243     void finish_message() noexcept final {
 
  252     void finish_log() noexcept final {
 
  254             std::unique_lock lock{_lockable};
 
  255             _out << 
"</log>\n" << std::flush;
 
  261     void log_chart_sample(
 
  265       float value) noexcept 
final {
 
  267             const auto now = std::chrono::steady_clock::now();
 
  268             const auto sec = std::chrono::duration<float>(now - _start);
 
  269             std::unique_lock lock{_lockable};
 
  271             _out << 
" src='" << source.name() << 
"'";
 
  272             _out << 
" iid='" << instance << 
"'";
 
  273             _out << 
" ser='" << series.name() << 
"'";
 
  274             _out << 
" ts='" << sec.count() << 
"'";
 
  275             _out << 
" v='" << value << 
"'";
 
  281     ~ostream_log_backend() noexcept
 override {
 
  288 #endif // EAGINE_LOGGING_OSTREAM_BACKEND_HPP 
  
basic_string_span< const char > string_view
Alias for const string views.
Definition: string_span.hpp:116
 
#define EAGINE_ID(NAME)
Macro for constructing instances of eagine::identifier.
Definition: identifier.hpp:353
 
Common code is placed in this namespace.
Definition: eagine.hpp:21
 
std::uintptr_t logger_instance_id
Logger object instance id type.
Definition: backend.hpp:56
 
basic_block< true > const_block
Alias for const byte memory span.
Definition: block.hpp:32
 
static auto format(std::string &&fmt_str) noexcept -> format_string_and_list< 0 >
Function taking a format string, returning an object for variable specification.
Definition: str_format.hpp:118
 
log_event_severity
Log event severity enumeration.
Definition: severity.hpp:18
 
auto operator=(interface &&)=delete
Not move assignable.
 
basic_identifier< 10, 6, default_identifier_char_set, identifier_t > identifier
Default identifier type used throughout the project.
Definition: identifier.hpp:346