-
Notifications
You must be signed in to change notification settings - Fork 54
/
Copy pathlogger.hpp
78 lines (64 loc) · 2.37 KB
/
logger.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#pragma once
#include <log/level.hpp>
#include <log/log.hpp>
#include <log/module.hpp>
#include <stdx/bit.hpp>
#include <stdx/ct_format.hpp>
#include <stdx/tuple_algorithms.hpp>
#include <stdx/type_traits.hpp>
#include <fmt/format.h>
#include <array>
#include <chrono>
#include <iterator>
#include <string_view>
#include <utility>
namespace logging {
template <auto> struct level_wrapper {};
namespace fmt_detail {
using namespace std::string_view_literals;
constexpr std::array level_text{"MAX"sv, "FATAL"sv, "ERROR"sv, "WARN"sv,
"INFO"sv, "USER1"sv, "USER2"sv, "TRACE"sv};
} // namespace fmt_detail
template <logging::level L>
constexpr std::string_view level_text =
fmt_detail::level_text[stdx::to_underlying(L)];
template <logging::level L>
[[nodiscard]] constexpr auto format_as(level_wrapper<L>) -> std::string_view {
return level_text<L>;
}
namespace fmt {
template <typename TDestinations> struct log_handler {
constexpr explicit log_handler(TDestinations &&ds) : dests{std::move(ds)} {}
template <typename Env, typename FilenameStringType,
typename LineNumberType, typename FmtResult>
auto log(FilenameStringType, LineNumberType, FmtResult const &fr) -> void {
auto const currentTime =
std::chrono::duration_cast<std::chrono::microseconds>(
std::chrono::steady_clock::now() - start_time)
.count();
stdx::for_each(
[&](auto &out) {
::fmt::format_to(out, "{:>8}us {} [{}]: ", currentTime,
level_wrapper<get_level(Env{})>{},
get_module(Env{}));
constexpr auto fmtstr =
std::string_view{decltype(fr.str)::value};
fr.args.apply([&](auto const &...args) {
::fmt::format_to(out, fmtstr, args...);
});
*out = '\n';
},
dests);
}
private:
static inline auto const start_time = std::chrono::steady_clock::now();
TDestinations dests;
};
template <typename... TDestinations> struct config {
using destinations_tuple_t = stdx::tuple<TDestinations...>;
constexpr explicit config(TDestinations... dests)
: logger{stdx::tuple{std::move(dests)...}} {}
log_handler<destinations_tuple_t> logger;
};
} // namespace fmt
} // namespace logging