microfmt
Zero-allocation C++ formatting for constrained environments
Loading...
Searching...
No Matches
default_log_sink.template.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2026 Jarosław Pelczar <jarek@jpelczar.com>
2//
3// SPDX-License-Identifier: BSD-2-Clause
4
5#pragma once
6
48#include <sys/syslog.h>
49#include <sys/systm.h>
50
51namespace microfmt::log {
52
53// Forward-declared so log_sink_traits<kernel_log_sink_tag> below can name
54// it as context_type before it is complete. Unlike microfmt::sinks::
55// syslog_sink's own tag/traits (a class *template*, whose as_sink() body
56// is only instantiated -- and therefore only needs the traits visible --
57// at first use, by which point the whole translation unit has been
58// parsed), kernel_log_sink is a concrete class: its as_sink() body below
59// is compiled immediately, in declaration order, and its call to
60// log_sink(kernel_log_sink_tag{}, *this) needs log_sink_traits<
61// kernel_log_sink_tag>::context_type visible right there (kernel_log_sink_
62// tag is not a dependent type, so nothing defers that lookup the way it
63// does for syslog_sink). Declaring the traits specialization (with only
64// context_type, an incomplete pointer target, and a not-yet-defined log())
65// ahead of the class, then defining log() out-of-line afterward, breaks
66// that cycle.
67class kernel_log_sink;
68
71
74
75 static void log(value_ref<context_type> ctx, const log_msg &msg) noexcept;
76};
77
80public:
81 [[nodiscard]] log_sink as_sink() noexcept RELOCO_LIFETIMEBOUND { return log_sink(kernel_log_sink_tag{}, *this); }
82
83 void log_impl(const log_msg &msg) noexcept {
84 if (msg.lvl == level::off) {
85 return;
86 }
87
88 buffer_sink<256> buffer;
89 const auto out = buffer.as_sink();
90 if (!msg.logger_name.empty()) {
91 microfmt::format_to(out, "[{}] ", msg.logger_name);
92 }
93 microfmt::format_to(out, "{}", msg.payload);
94
95 // log(9) does its own printf(9)-style formatting; %.*s keeps this a
96 // single, allocation-free call regardless of the record's length.
97 log(priority_for(msg.lvl), "%.*s\n", static_cast<int>(buffer.view().size()), buffer.view().data());
98 }
99
100private:
101 static int priority_for(level lvl) noexcept {
102 switch (lvl) {
103 case level::trace:
104 case level::debug:
105 return LOG_DEBUG;
106 case level::info:
107 return LOG_INFO;
108 case level::warn:
109 return LOG_WARNING;
110 case level::err:
111 return LOG_ERR;
112 case level::critical:
113 return LOG_CRIT;
114 case level::off:
115 return LOG_DEBUG;
116 }
117 return LOG_DEBUG;
118 }
119};
120
121inline void log_sink_traits<kernel_log_sink_tag>::log(value_ref<context_type> ctx, const log_msg &msg) noexcept {
122 ctx->log_impl(msg);
123}
124
125namespace detail {
126
128inline logger &built_in_default_logger() noexcept {
129 static kernel_log_sink sink_instance;
130 static logger instance("kernel", sink_instance.as_sink());
131 return instance;
132}
133
134} // namespace detail
135
136} // namespace microfmt::log
Output sink that stores formatted characters in an internal fixed-size stack/inline buffer.
Definition microfmt.hpp:185
constexpr microfmt::string_view view() const &noexcept RELOCO_LIFETIMEBOUND
Returns a string view over the characters written so far.
Definition microfmt.hpp:245
RELOCO_END_UNSAFE_BUFFER_USAGE RELOCO_CONSTEXPR20 sink as_sink() &noexcept RELOCO_LIFETIMEBOUND
Creates a type-erased sink adapter pointing to this instance.
Definition microfmt.hpp:236
Definition logger.hpp:56
Adapter that writes structured records to the FreeBSD kernel's log(9).
Definition default_log_sink.template.hpp:79
void log_impl(const log_msg &msg) noexcept
Definition default_log_sink.template.hpp:83
log_sink as_sink() noexcept RELOCO_LIFETIMEBOUND
Definition default_log_sink.template.hpp:81
Type-erased, two-word handle to a log sink backend, plus the severity threshold below which records a...
Definition sink.hpp:73
Definition default_log_sink.template.hpp:51
level
Shared log severity levels in ascending order.
Definition log_msg.hpp:22
RELOCO_CONSTEXPR20 void format_to(const sink &out, microfmt::string_view fmt, const Args &...args) noexcept
Definition microfmt.hpp:1766
Tag selecting kernel_log_sink as a log_sink backend.
Definition default_log_sink.template.hpp:70
Structured log record forwarded by a logger to each sink.
Definition log_msg.hpp:69
Static customization point describing a log sink backend.
Definition sink.hpp:46