summaryrefslogtreecommitdiffstats
path: root/server/src/log.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'server/src/log.cpp')
-rw-r--r--server/src/log.cpp99
1 files changed, 99 insertions, 0 deletions
diff --git a/server/src/log.cpp b/server/src/log.cpp
new file mode 100644
index 0000000..7fe725f
--- /dev/null
+++ b/server/src/log.cpp
@@ -0,0 +1,99 @@
1module routemon:log$impl;
2
3import :log;
4
5namespace routemon::log {
6
7auto operator<<(std::ostream& os, level lvl) -> std::ostream&
8{
9 switch (lvl)
10 {
11 case level::debug:
12 os << "dbg";
13 break;
14 case level::info:
15 os << "inf";
16 break;
17 case level::warn:
18 os << "wrn";
19 break;
20 case level::error:
21 os << "err";
22 break;
23 }
24 return os;
25}
26
27sink::sink(enum level lvl) : lvl_{lvl} {}
28
29auto sink::level() const -> enum level { return lvl_; }
30
31auto sink::set_level(enum level lvl) -> void { lvl_ = lvl; }
32
33auto sink::write(tmp_message msg) -> void
34{
35 auto sos = std::osyncstream{os_};
36 sos << "[" << msg.lvl;
37 if (!msg.component.empty())
38 sos << " " << msg.component;
39 sos << "] " << msg.txt;
40 for (auto const& [k, v] : msg.attrs)
41 sos << " " << k << "=" << std::quoted(v);
42 sos << '\n';
43}
44
45auto make_sink(level lvl) -> std::shared_ptr<sink>
46{
47 return std::shared_ptr<sink>{new sink{lvl}};
48}
49
50auto logger::log_at(log::level lvl, std::string_view fmt, std::format_args args)
51 -> logger&
52{
53 if (sink_->level() <= lvl)
54 sink_->write(
55 sink::tmp_message{
56 .lvl = lvl,
57 .component = component_,
58 .txt = std::vformat(fmt, args),
59 .attrs = attrs_,
60 });
61 return *this;
62}
63
64logger::logger(std::shared_ptr<sink> const& sink) : sink_{sink}
65{
66 if (!sink)
67 {
68 throw std::invalid_argument{"logger sink may not be null"};
69 }
70}
71
72auto logger::sub(std::string_view component) const -> logger
73{
74 auto l = *this;
75 if (l.component_.empty())
76 {
77 l.component_ = component;
78 }
79 else
80 {
81 l.component_ += ".";
82 l.component_ += component;
83 }
84 return l;
85}
86
87auto logger::with(std::string const& k, std::string&& v) const -> logger
88{
89 auto l = *this;
90 l.attrs_[k] = std::move(v);
91 return l;
92}
93
94auto logger::with(std::string const& k, std::string_view v) const -> logger
95{
96 return with(k, std::string{v});
97}
98
99} // namespace routemon::log