-
Notifications
You must be signed in to change notification settings - Fork 110
[k2] refactor logs #1548
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
[k2] refactor logs #1548
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| // Compiler for PHP (aka KPHP) | ||
| // Copyright (c) 2025 LLC «V Kontakte» | ||
| // Distributed under the GPL v3 License, see LICENSE.notice.txt | ||
|
|
||
| #include "runtime-light/stdlib/diagnostics/contextual-tags.h" | ||
|
|
||
| #include <cstddef> | ||
| #include <functional> | ||
| #include <optional> | ||
|
|
||
| #include "runtime-light/k2-platform/k2-api.h" | ||
| #include "runtime-light/state/instance-state.h" | ||
|
|
||
| namespace kphp::log { | ||
|
|
||
| std::optional<std::reference_wrapper<contextual_tags>> contextual_tags::try_get() noexcept { | ||
| if (auto* instance_state_ptr{k2::instance_state()}; instance_state_ptr != nullptr) [[likely]] { | ||
| return instance_state_ptr->instance_tags; | ||
| } | ||
| return std::nullopt; | ||
| } | ||
|
|
||
| } // namespace kphp::log |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,18 +8,15 @@ | |
| #include <format> | ||
| #include <functional> | ||
| #include <optional> | ||
| #include <span> | ||
| #include <string_view> | ||
| #include <utility> | ||
|
|
||
| #include "common/mixin/not_copyable.h" | ||
| #include "runtime-common/core/allocator/script-allocator.h" | ||
| #include "runtime-common/core/std/containers.h" | ||
| #include "runtime-light/stdlib/diagnostics/detail/logs.h" | ||
|
|
||
| namespace kphp::log { | ||
|
|
||
| class contextual_logger final : vk::not_copyable { | ||
| class contextual_tags final : vk::not_copyable { | ||
| using tag_key_t = kphp::stl::string<kphp::memory::script_allocator>; | ||
| using tag_value_t = kphp::stl::string<kphp::memory::script_allocator>; | ||
|
|
||
|
|
@@ -59,45 +56,27 @@ class contextual_logger final : vk::not_copyable { | |
|
|
||
| kphp::stl::unordered_map<tag_key_t, tag_value_t, kphp::memory::script_allocator, extra_tags_hash, extra_tags_equal> extra_tags; | ||
|
|
||
| void log_with_tags(kphp::log::level level, std::optional<std::span<void* const>> trace, std::string_view message) const noexcept; | ||
|
|
||
| public: | ||
| template<typename... Args> | ||
| void log(kphp::log::level level, std::optional<std::span<void* const>> trace, std::format_string<impl::wrapped_arg_t<Args>...> fmt, | ||
| Args&&... args) const noexcept; | ||
| size_t size() const noexcept { | ||
| return extra_tags.size(); | ||
| } | ||
|
|
||
| auto begin() const noexcept { | ||
| return extra_tags.begin(); | ||
| } | ||
|
|
||
| auto end() const noexcept { | ||
| return extra_tags.end(); | ||
| } | ||
|
|
||
| void add_extra_tag(std::string_view key, std::string_view value) noexcept; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems like this methods aren't implemented |
||
| void remove_extra_tag(std::string_view key) noexcept; | ||
| void clear_extra_tags() noexcept; | ||
|
|
||
| static std::optional<std::reference_wrapper<contextual_logger>> try_get() noexcept; | ||
| static std::optional<std::reference_wrapper<contextual_tags>> try_get() noexcept; | ||
| }; | ||
|
|
||
| template<typename... Args> | ||
| void contextual_logger::log(kphp::log::level level, std::optional<std::span<void* const>> trace, std::format_string<impl::wrapped_arg_t<Args>...> fmt, | ||
| Args&&... args) const noexcept { | ||
| static constexpr size_t LOG_BUFFER_SIZE = 2048UZ; | ||
| std::array<char, LOG_BUFFER_SIZE> log_buffer; // NOLINT | ||
| size_t message_size{impl::format_log_message(log_buffer, fmt, std::forward<Args>(args)...)}; | ||
| auto message{std::string_view{log_buffer.data(), static_cast<std::string_view::size_type>(message_size)}}; | ||
| log_with_tags(level, trace, message); | ||
| } | ||
|
|
||
| inline void contextual_logger::add_extra_tag(std::string_view key, std::string_view value) noexcept { | ||
| if (auto it{extra_tags.find(key)}; it == extra_tags.end()) { | ||
| extra_tags.emplace(key, value); | ||
| } else { | ||
| it->second = value; | ||
| } | ||
| } | ||
|
|
||
| inline void contextual_logger::remove_extra_tag(std::string_view key) noexcept { | ||
| if (auto it{extra_tags.find(key)}; it != extra_tags.end()) { | ||
| extra_tags.erase(it); | ||
| } | ||
| } | ||
|
|
||
| inline void contextual_logger::clear_extra_tags() noexcept { | ||
| inline void contextual_tags::clear_extra_tags() noexcept { | ||
| extra_tags.clear(); | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -13,22 +13,50 @@ | |
|
|
||
| #include "runtime-light/k2-platform/k2-api.h" | ||
| #include "runtime-light/stdlib/diagnostics/backtrace.h" | ||
| #include "runtime-light/stdlib/diagnostics/contextual-logger.h" | ||
| #include "runtime-light/stdlib/diagnostics/contextual-tags.h" | ||
| #include "runtime-light/stdlib/diagnostics/detail/logs.h" | ||
| #include "runtime-light/stdlib/diagnostics/error-handling-state.h" | ||
| #include "runtime-light/stdlib/diagnostics/raw-logger.h" | ||
|
|
||
| namespace kphp::log { | ||
|
|
||
| namespace impl { | ||
|
|
||
| template<typename... Args> | ||
| void select_logger_and_log(level level, std::optional<std::span<void* const>> trace, std::format_string<impl::wrapped_arg_t<Args>...> fmt, | ||
| Args&&... args) noexcept { | ||
| if (auto logger{contextual_logger::try_get()}; logger.has_value()) [[likely]] { | ||
| (*logger).get().log(level, trace, fmt, std::forward<Args>(args)...); | ||
| } else { | ||
| raw_logger::log(level, trace, fmt, std::forward<Args>(args)...); | ||
| void log(level level, std::optional<std::span<void* const>> trace, std::format_string<impl::wrapped_arg_t<Args>...> fmt, Args&&... args) noexcept { | ||
| static constexpr size_t LOG_BUFFER_SIZE = 2048UZ; | ||
| std::array<char, LOG_BUFFER_SIZE> log_buffer; // NOLINT | ||
| size_t message_size{impl::format_log_message(log_buffer, fmt, std::forward<Args>(args)...)}; | ||
| auto message{std::string_view{log_buffer.data(), static_cast<std::string_view::size_type>(message_size)}}; | ||
|
|
||
| auto opt_tags{ | ||
| contextual_tags::try_get().and_then([level](contextual_tags& tags) noexcept -> std::optional<std::reference_wrapper<kphp::log::contextual_tags>> { | ||
| if (level == level::warn || level == level::error) { | ||
| return std::make_optional(std::ref(tags)); | ||
| } | ||
| return std::nullopt; | ||
| })}; | ||
|
|
||
| const size_t tagged_entries_size{ | ||
| static_cast<size_t>((trace.has_value() ? 1 : 0) + opt_tags.transform([](contextual_tags& tags) noexcept { return tags.size(); }).value_or(0))}; | ||
| kphp::stl::vector<k2::LogTaggedEntry, kphp::memory::script_allocator> tagged_entries{}; | ||
| tagged_entries.reserve(tagged_entries_size); | ||
|
|
||
| opt_tags.transform([&tagged_entries](contextual_tags& tags) noexcept { | ||
| for (const auto& [key, value] : tags) { | ||
| tagged_entries.push_back(k2::LogTaggedEntry{.key = key.data(), .value = value.data(), .key_len = key.size(), .value_len = value.size()}); | ||
| } | ||
| return 0; | ||
| }); | ||
| if (trace.has_value()) { | ||
| static constexpr size_t BACKTRACE_BUFFER_SIZE = 1024UZ * 4UZ; | ||
| static constexpr std::string_view BACKTRACE_KEY = "trace"; | ||
| std::array<char, BACKTRACE_BUFFER_SIZE> backtrace_buffer; // NOLINT | ||
| size_t backtrace_size{impl::resolve_log_trace(backtrace_buffer, *trace)}; | ||
| tagged_entries.push_back( | ||
| k2::LogTaggedEntry{.key = BACKTRACE_KEY.data(), .value = backtrace_buffer.data(), .key_len = BACKTRACE_KEY.size(), .value_len = backtrace_size}); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here you get pointer to backtrace_buffer witch lifetime expires after if scope ends |
||
| } | ||
|
|
||
| k2::log(std::to_underlying(level), message, tagged_entries); | ||
| } | ||
|
|
||
| } // namespace impl | ||
|
|
@@ -37,7 +65,7 @@ void select_logger_and_log(level level, std::optional<std::span<void* const>> tr | |
| // If assertion is modified, the backtrace algorithm should be updated accordingly | ||
| inline void assertion(bool condition, const std::source_location& location = std::source_location::current()) noexcept { | ||
| if (!condition) [[unlikely]] { | ||
| impl::select_logger_and_log(level::error, std::nullopt, "assertion failed at {}:{}", location.file_name(), location.line()); | ||
| impl::log(level::error, std::nullopt, "assertion failed at {}:{}", location.file_name(), location.line()); | ||
| k2::exit(1); | ||
| } | ||
| } | ||
|
|
@@ -50,7 +78,7 @@ template<typename... Args> | |
| std::array<void*, kphp::diagnostic::DEFAULT_BACKTRACE_MAX_SIZE> backtrace{}; | ||
| const size_t num_frames{kphp::diagnostic::backtrace(backtrace)}; | ||
| const std::span<void* const> backtrace_view{backtrace.data(), num_frames}; | ||
| impl::select_logger_and_log(level::error, backtrace_view, fmt, std::forward<Args>(args)...); | ||
| impl::log(level::error, backtrace_view, fmt, std::forward<Args>(args)...); | ||
| } | ||
| k2::exit(1); | ||
| } | ||
|
|
@@ -65,7 +93,7 @@ void warning(std::format_string<impl::wrapped_arg_t<Args>...> fmt, Args&&... arg | |
| std::array<void*, kphp::diagnostic::DEFAULT_BACKTRACE_MAX_SIZE> backtrace{}; | ||
| const size_t num_frames{kphp::diagnostic::backtrace(backtrace)}; | ||
| const std::span<void* const> backtrace_view{backtrace.data(), num_frames}; | ||
| impl::select_logger_and_log(level::warn, backtrace_view, fmt, std::forward<Args>(args)...); | ||
| impl::log(level::warn, backtrace_view, fmt, std::forward<Args>(args)...); | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -76,21 +104,21 @@ void info(std::format_string<impl::wrapped_arg_t<Args>...> fmt, Args&&... args) | |
| return; | ||
| } | ||
| if (std::to_underlying(level::info) <= k2::log_level_enabled()) { | ||
| impl::select_logger_and_log(level::info, std::nullopt, fmt, std::forward<Args>(args)...); | ||
| impl::log(level::info, std::nullopt, fmt, std::forward<Args>(args)...); | ||
| } | ||
| } | ||
|
|
||
| template<typename... Args> | ||
| void debug(std::format_string<impl::wrapped_arg_t<Args>...> fmt, Args&&... args) noexcept { | ||
| if (std::to_underlying(level::debug) <= k2::log_level_enabled()) { | ||
| impl::select_logger_and_log(level::debug, std::nullopt, fmt, std::forward<Args>(args)...); | ||
| impl::log(level::debug, std::nullopt, fmt, std::forward<Args>(args)...); | ||
| } | ||
| } | ||
|
|
||
| template<typename... Args> | ||
| void trace(std::format_string<impl::wrapped_arg_t<Args>...> fmt, Args&&... args) noexcept { | ||
| if (std::to_underlying(level::trace) <= k2::log_level_enabled()) { | ||
| impl::select_logger_and_log(level::trace, std::nullopt, fmt, std::forward<Args>(args)...); | ||
| impl::log(level::trace, std::nullopt, fmt, std::forward<Args>(args)...); | ||
| } | ||
| } | ||
|
|
||
|
|
||
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe to it like? Instead of pair
begin/end