23 #include <seastar/core/sstring.hh>
24 #include <seastar/util/concepts.hh>
25 #include <seastar/util/log-impl.hh>
26 #include <seastar/core/lowres_clock.hh>
27 #include <seastar/util/std-compat.hh>
28 #include <seastar/util/modules.hh>
30 #ifndef SEASTAR_MODULE
31 #include <unordered_map>
36 #include <boost/lexical_cast.hpp>
37 #include <fmt/format.h>
45 SEASTAR_MODULE_EXPORT_BEGIN
60 std::ostream& operator<<(std::ostream& out,
log_level level);
61 std::istream& operator>>(std::istream& in,
log_level& level);
63 SEASTAR_MODULE_EXPORT_END
75 SEASTAR_MODULE_EXPORT_BEGIN
77 class logger_registry;
92 std::atomic<log_level> _level = { log_level::info };
93 static std::ostream* _out;
94 static std::atomic<bool> _ostream;
95 static std::atomic<bool> _syslog;
96 static unsigned _shard_field_width;
97 #ifdef SEASTAR_BUILD_SHARED_LIBS
98 static thread_local
bool silent;
100 static inline thread_local
bool silent =
false;
107 virtual internal::log_buf::inserter_iterator operator()(internal::log_buf::inserter_iterator) = 0;
109 template <
typename Func>
110 SEASTAR_CONCEPT(requires requires (Func fn, internal::log_buf::inserter_iterator it) {
118 virtual internal::log_buf::inserter_iterator operator()(internal::log_buf::inserter_iterator it)
override {
return _func(it); }
126 format_info(
const char*
format, compat::source_location loc = compat::source_location::current()) noexcept
132 format_info(std::string_view
format, compat::source_location loc = compat::source_location::current()) noexcept
137 format_info(compat::source_location loc = compat::source_location::current()) noexcept
142 compat::source_location loc;
149 void failed_to_log(std::exception_ptr ex, format_info fmt) noexcept;
153 silencer() noexcept {
187 using clock = lowres_clock;
190 clock::duration _interval;
191 clock::time_point _next;
192 uint64_t _dropped_messages = 0;
196 bool has_dropped_messages()
const {
return bool(_dropped_messages); }
197 uint64_t get_and_reset_dropped_messages() {
198 return std::exchange(_dropped_messages, 0);
202 explicit rate_limit(std::chrono::milliseconds interval);
206 explicit logger(sstring
name);
210 bool is_shard_zero() noexcept;
217 return __builtin_expect(
level <= _level.load(std::memory_order_relaxed),
false) && !silent;
226 template <
typename... Args>
227 void log(
log_level level, format_info fmt, Args&&... args) noexcept {
228 if (is_enabled(
level)) {
230 lambda_log_writer writer([&] (internal::log_buf::inserter_iterator it) {
231 #if FMT_VERSION >= 80000
232 return fmt::format_to(it, fmt::runtime(fmt.format), std::forward<Args>(args)...);
234 return fmt::format_to(it, fmt.format, std::forward<Args>(args)...);
237 do_log(
level, writer);
239 failed_to_log(std::current_exception(), std::move(fmt));
258 template <
typename... Args>
259 void log(
log_level level, rate_limit& rl, format_info fmt, Args&&... args) noexcept {
260 if (is_enabled(
level) && rl.check()) {
262 lambda_log_writer writer([&] (internal::log_buf::inserter_iterator it) {
263 if (rl.has_dropped_messages()) {
264 it = fmt::format_to(it,
"(rate limiting dropped {} similar messages) ", rl.get_and_reset_dropped_messages());
266 #
if FMT_VERSION >= 80000
267 return fmt::format_to(it, fmt::runtime(fmt.format), std::forward<Args>(args)...);
269 return fmt::format_to(it, fmt.format, std::forward<Args>(args)...);
272 do_log(
level, writer);
274 failed_to_log(std::current_exception(), std::move(fmt));
289 void log(
log_level level, log_writer& writer, format_info fmt = {}) noexcept {
290 if (is_enabled(
level)) {
292 do_log(
level, writer);
294 failed_to_log(std::current_exception(), std::move(fmt));
308 void log(
log_level level, rate_limit& rl, log_writer& writer, format_info fmt = {}) noexcept {
309 if (is_enabled(
level) && rl.check()) {
311 lambda_log_writer writer_wrapper([&] (internal::log_buf::inserter_iterator it) {
312 if (rl.has_dropped_messages()) {
313 it = fmt::format_to(it,
"(rate limiting dropped {} similar messages) ", rl.get_and_reset_dropped_messages());
317 do_log(
level, writer_wrapper);
319 failed_to_log(std::current_exception(), std::move(fmt));
332 template <
typename... Args>
333 void error(format_info fmt, Args&&... args) noexcept {
334 log(log_level::error, std::move(fmt), std::forward<Args>(args)...);
343 template <
typename... Args>
344 void warn(format_info fmt, Args&&... args) noexcept {
345 log(log_level::warn, std::move(fmt), std::forward<Args>(args)...);
354 template <
typename... Args>
355 void info(format_info fmt, Args&&... args) noexcept {
356 log(log_level::info, std::move(fmt), std::forward<Args>(args)...);
365 template <
typename... Args>
366 void info0(format_info fmt, Args&&... args) noexcept {
367 if (is_shard_zero()) {
368 log(log_level::info, std::move(fmt), std::forward<Args>(args)...);
378 template <
typename... Args>
379 void debug(format_info fmt, Args&&... args) noexcept {
380 log(log_level::debug, std::move(fmt), std::forward<Args>(args)...);
389 template <
typename... Args>
390 void trace(format_info fmt, Args&&... args) noexcept {
391 log(log_level::trace, std::move(fmt), std::forward<Args>(args)...);
396 const sstring&
name() const noexcept {
403 return _level.load(std::memory_order_relaxed);
409 _level.store(
level, std::memory_order_relaxed);
419 [[deprecated(
"Use set_ostream_enabled instead")]]
453 mutable std::mutex _mutex;
454 std::unordered_map<sstring, logger*> _loggers;
507 #ifdef SEASTAR_LOGGER_TYPE_STDOUT
508 stdout __attribute__ ((deprecated (
"use cout instead"))) = 1,
509 stderr __attribute__ ((deprecated (
"use cerr instead"))) = 2,
516 std::unordered_map<sstring, log_level> logger_levels;
529 SEASTAR_MODULE_EXPORT_END
533 extern thread_local uint64_t logging_failures;
535 sstring pretty_type_name(
const std::type_info&);
539 template <
typename T>
540 class logger_for :
public logger {
542 logger_for() :
logger(pretty_type_name(typeid(T))) {}
550 std::ostream& operator<<(std::ostream&,
const std::exception_ptr&);
551 std::ostream& operator<<(std::ostream&,
const std::exception&);
552 std::ostream& operator<<(std::ostream&,
const std::system_error&);
555 #if FMT_VERSION >= 90000
556 template <>
struct fmt::formatter<std::exception_ptr> : fmt::ostream_formatter {};
557 template <>
struct fmt::formatter<std::exception> : fmt::ostream_formatter {};
558 template <>
struct fmt::formatter<std::system_error> : fmt::ostream_formatter {};
used to keep a static registry of loggers since the typical use case is to do:
Definition: log.hh:452
std::vector< sstring > get_all_logger_names()
void set_logger_level(sstring name, log_level level)
void register_logger(logger *l)
void set_all_loggers_level(log_level level)
void moved(logger *from, logger *to)
log_level get_logger_level(sstring name) const
void unregister_logger(logger *l)
Logger class for ostream or syslog.
Definition: log.hh:90
static void set_syslog_enabled(bool enabled) noexcept
void error(format_info fmt, Args &&... args) noexcept
Definition: log.hh:333
void set_level(log_level level) noexcept
Definition: log.hh:408
void debug(format_info fmt, Args &&... args) noexcept
Definition: log.hh:379
void info0(format_info fmt, Args &&... args) noexcept
Definition: log.hh:366
log_level level() const noexcept
Definition: log.hh:402
static void set_shard_field_width(unsigned width) noexcept
void trace(format_info fmt, Args &&... args) noexcept
Definition: log.hh:390
static void set_with_color(bool enabled) noexcept
static void set_ostream(std::ostream &out) noexcept
Set output stream, default is std::cerr.
const sstring & name() const noexcept
Definition: log.hh:396
static void set_stdout_enabled(bool enabled) noexcept
Also output to stdout. default is true.
static void set_ostream_enabled(bool enabled) noexcept
Also output to ostream. default is true.
void info(format_info fmt, Args &&... args) noexcept
Definition: log.hh:355
void warn(format_info fmt, Args &&... args) noexcept
Definition: log.hh:344
Seastar API namespace.
Definition: abort_on_ebadf.hh:26
logger_timestamp_style
Timestamp style.
Definition: log.hh:498
logger_ostream_type
Output stream to use for logging.
Definition: log.hh:505
sstring format(const char *fmt, A &&... a)
Definition: print.hh:142
log_level
log level used with
Definition: log.hh:52
void apply_logging_settings(const logging_settings &)