Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions runtime-light/k2-platform/k2-api.h
Original file line number Diff line number Diff line change
Expand Up @@ -261,9 +261,9 @@ inline k2::UpdateStatus take_update(k2::descriptor* descriptor) noexcept {

using LogTaggedEntry = ::LogKeyValuePair;

inline void log(size_t level, std::string_view msg, std::optional<std::span<LogTaggedEntry>> tags) noexcept {
const auto tags_count{tags.value_or(std::span<LogTaggedEntry>{}).size()};
const auto* tags_data{tags.value_or(std::span<LogTaggedEntry>{}).data()};
inline void log(size_t level, std::string_view msg, std::span<LogTaggedEntry> tags) noexcept {
const auto tags_count{tags.size()};
const auto* tags_data{tags.data()};
k2_log(level, msg.size(), msg.data(), tags_count, tags_data);
}

Expand Down
4 changes: 2 additions & 2 deletions runtime-light/state/instance-state.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
#include "runtime-light/state/component-state.h"
#include "runtime-light/stdlib/confdata/confdata-state.h"
#include "runtime-light/stdlib/curl/curl-state.h"
#include "runtime-light/stdlib/diagnostics/contextual-logger.h"
#include "runtime-light/stdlib/diagnostics/contextual-tags.h"
#include "runtime-light/stdlib/diagnostics/error-handling-state.h"
#include "runtime-light/stdlib/fork/fork-state.h"
#include "runtime-light/stdlib/fork/wait-queue-state.h"
Expand Down Expand Up @@ -89,7 +89,7 @@ struct InstanceState final : vk::not_copyable {
}

AllocatorState instance_allocator_state{INIT_INSTANCE_ALLOCATOR_SIZE, 0};
kphp::log::contextual_logger instance_logger;
kphp::log::contextual_tags instance_tags;

kphp::coro::io_scheduler io_scheduler;
CoroutineInstanceState coroutine_instance_state;
Expand Down
51 changes: 0 additions & 51 deletions runtime-light/stdlib/diagnostics/contextual-logger.cpp

This file was deleted.

23 changes: 23 additions & 0 deletions runtime-light/stdlib/diagnostics/contextual-tags.cpp
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
Expand Up @@ -8,18 +8,16 @@
#include <format>
#include <functional>
#include <optional>
#include <span>
#include <ranges>
#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>;

Expand Down Expand Up @@ -55,49 +53,39 @@ class contextual_logger final : vk::not_copyable {
}
};

static constexpr std::string_view BACKTRACE_KEY = "trace";

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 values() const noexcept {
return std::views::all(extra_tags);
}

void add_extra_tag(std::string_view key, std::string_view value) noexcept;
Comment thread
astrophysik marked this conversation as resolved.
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 {
inline void contextual_tags::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 {
inline void contextual_tags::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();
}

Expand Down
56 changes: 42 additions & 14 deletions runtime-light/stdlib/diagnostics/logs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.values()) {
tagged_entries.push_back(k2::LogTaggedEntry{.key = key.data(), .value = value.data(), .key_len = key.size(), .value_len = value.size()});
}
return 0;
});
static constexpr size_t BACKTRACE_BUFFER_SIZE = 1024UZ * 4UZ;
std::array<char, BACKTRACE_BUFFER_SIZE> backtrace_buffer; // NOLINT
Comment thread
astrophysik marked this conversation as resolved.
Outdated
if (trace.has_value()) {
static constexpr std::string_view BACKTRACE_KEY = "trace";
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});
Comment thread
astrophysik marked this conversation as resolved.
}

k2::log(std::to_underlying(level), message, tagged_entries);
}

} // namespace impl
Expand All @@ -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);
}
}
Expand All @@ -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);
}
Expand All @@ -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)...);
}
}

Expand All @@ -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)...);
}
}

Expand Down
50 changes: 0 additions & 50 deletions runtime-light/stdlib/diagnostics/raw-logger.h

This file was deleted.

2 changes: 1 addition & 1 deletion runtime-light/stdlib/stdlib.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ prepend(
curl/curl-state.cpp
web-transfer-lib/web-state.cpp
diagnostics/backtrace.cpp
diagnostics/contextual-logger.cpp
diagnostics/contextual-tags.cpp
diagnostics/error-handling-state.cpp
diagnostics/php-assert.cpp
file/file-system-state.cpp
Expand Down
Loading
Loading