9#include "../formatters/ansi.hpp"
10#include "../formatters/reloco.hpp"
11#include "../sinks/stdio.hpp"
52template <
typename Tag>
54 std::declval<value_ref<typename log_sink_traits<Tag>::context_type>>()))>>
59template <
typename Tag>
80 void (*log)(
void *ctx,
const log_msg &msg)
noexcept =
nullptr;
85 void (*flush)(
void *ctx)
noexcept =
nullptr;
100 std::enable_if_t<std::is_void_v<typename Traits::context_type>,
int> = 0>
101 constexpr explicit
log_sink(Tag,
level lvl =
level::trace) noexcept : vtbl_(&s_vtbl<Tag>), lvl_(lvl) {}
112 template <
typename Tag,
typename Context,
typename Traits = log_sink_traits<Tag>,
113 std::enable_if_t<!std::is_
void_v<
typename Traits::context_type> &&
114 std::is_convertible_v<Context *,
typename Traits::context_type *>,
116 constexpr log_sink(Tag, Context &ctx RELOCO_LIFETIMEBOUND RELOCO_LIFETIME_CAPTURE_BY_THIS,
117 level lvl = level::trace) noexcept
118 : ctx_(&ctx), vtbl_(&s_vtbl<Tag>), lvl_(lvl) {}
122 template <
typename Tag,
typename Context, std::enable_if_t<!std::is_lvalue_reference_v<Context>,
int> = 0>
130 if (vtbl_ !=
nullptr && msg.lvl >= lvl_) {
131 vtbl_->log(ctx_.get(), msg);
138 [[nodiscard]]
constexpr bool can_flush() const noexcept {
return vtbl_ !=
nullptr && vtbl_->flush !=
nullptr; }
145 vtbl_->flush(ctx_.get());
155 [[nodiscard]]
constexpr explicit operator bool() const noexcept {
return vtbl_ !=
nullptr; }
158 template <
typename Tag>
static void log_entry(
void *ctx,
const log_msg &msg)
noexcept {
160 if constexpr (std::is_void_v<context_type>) {
164 auto &typed = *
static_cast<context_type *
>(ctx);
165 log_sink_traits<Tag>::log(value_ref<context_type>(typed), msg);
169 template <
typename Tag> [[nodiscard]]
static constexpr auto flush_entry() noexcept {
170 using context_type =
typename log_sink_traits<Tag>::context_type;
171 if constexpr (std::is_void_v<context_type>) {
172 if constexpr (detail::has_stateless_log_sink_flush<Tag>::value) {
173 return +[](
void *)
noexcept { log_sink_traits<Tag>::flush(); };
175 return static_cast<void (*)(
void *) noexcept
>(
nullptr);
177 }
else if constexpr (detail::has_log_sink_flush<Tag>::value) {
178 return +[](
void *ctx)
noexcept {
179 auto &typed = *
static_cast<context_type *
>(ctx);
180 log_sink_traits<Tag>::flush(value_ref<context_type>(typed));
183 return static_cast<void (*)(
void *) noexcept
>(
nullptr);
187 template <
typename Tag>
static constexpr vtable s_vtbl{&log_entry<Tag>, flush_entry<Tag>()};
189 value_ptr<void> ctx_{};
190 const vtable *vtbl_{
nullptr};
191 level lvl_{level::trace};
220 if (!msg.logger_name.empty()) {
256 term.write(buf.
view());
263 static void log(value_ref<context_type> ctx,
const log_msg &msg)
noexcept { ctx->log_impl(msg); }
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
Type-erased, two-word handle to a log sink backend, plus the severity threshold below which records a...
Definition sink.hpp:73
void log(const log_msg &msg) noexcept
Emits msg to the underlying backend, honoring both the record's own level check and this sink's confi...
Definition sink.hpp:129
constexpr bool can_flush() const noexcept
Reports whether the bound backend supports flush.
Definition sink.hpp:138
constexpr log_sink(Tag, Context &&, level=level::trace)=delete
constexpr log_sink() noexcept=default
Constructs an empty (invalid) handle.
void set_level(level l) noexcept
Definition sink.hpp:149
void flush() noexcept
Flushes buffered output. A no-op when can_flush is false.
Definition sink.hpp:143
constexpr log_sink(Tag, Context &ctx RELOCO_LIFETIMEBOUND RELOCO_LIFETIME_CAPTURE_BY_THIS, level lvl=level::trace) noexcept
Constructs a handle for a stateful log sink tag.
Definition sink.hpp:116
constexpr bool should_log(level l) const noexcept
Definition sink.hpp:150
ANSI-colorized stdout adapter for structured log records.
Definition sink.hpp:204
stdout_color_sink() noexcept=default
log_sink as_sink() &noexcept RELOCO_LIFETIMEBOUND
Definition sink.hpp:208
void log_impl(const log_msg &msg) noexcept
Definition sink.hpp:212
#define MICROFMT_API_CLASS
Definition compat.hpp:181
Structured log-record types and severity levels.
constexpr styled_view< T > gray(const T &val) noexcept
Definition ansi.hpp:185
constexpr styled_view< T > styled(const T &val, style st) noexcept
Definition ansi.hpp:153
Definition default_log_sink.template.hpp:51
level
Shared log severity levels in ascending order.
Definition log_msg.hpp:22
RELOCO_END_UNSAFE_CODE sink stdout_sink() noexcept
Definition stdio.hpp:36
RELOCO_CONSTEXPR20 void format_to(const sink &out, microfmt::string_view fmt, const Args &...args) noexcept
Definition microfmt.hpp:1766
Structured log record forwarded by a logger to each sink.
Definition log_msg.hpp:69
Virtual table of log sink operations.
Definition sink.hpp:78
static void log(value_ref< context_type > ctx, const log_msg &msg) noexcept
Definition sink.hpp:263
Static customization point describing a log sink backend.
Definition sink.hpp:46
Tag selecting stdout_color_sink<LineBufCap> as a log_sink backend.
Definition sink.hpp:201