-
Notifications
You must be signed in to change notification settings - Fork 112
[k2] add metrics builder and k2_write_metric API #1639
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
Merged
Merged
Changes from 14 commits
Commits
Show all changes
49 commits
Select commit
Hold shift + click to select a range
694884f
first version
denisichh 2b7be26
added metric builder + write_serialized_metric to k2-api
denisichh 7bb602d
v1.0
denisichh f6af9d2
v1.1
denisichh 0608cf2
rename
denisichh 12b21ac
mask size 32bits to 8bits
denisichh 5bb69d9
fixes
denisichh f8f635f
fixes
denisichh 064d869
add comments
denisichh de690e2
added noexcept
denisichh 127f856
fixes
denisichh 537b967
minor fix
denisichh 22a6227
added metric type
denisichh 86f1de8
fixes
denisichh 22cdf85
timestamp u32 to u64 + fixes
denisichh 21e5bdb
fix
denisichh 88709e2
fix
denisichh 4590662
fix concept
denisichh 6f3052d
new metrics ctors
denisichh 57d6b2e
rename static method
denisichh a5f3057
funny fixes
denisichh 6c9137b
minor fix
denisichh 9c63912
minor fix
denisichh 713b47a
returned buffer.clear()
denisichh a7e392f
fix
denisichh b1d7add
added include
denisichh dfd5c0c
chrono to k2::system_time
denisichh 9c5b54e
format changed: my own to tl
denisichh 476e9cf
fixes
denisichh 9e23659
fixes
denisichh 3366cb6
minor rename
denisichh 0ca6ecd
minor fix
denisichh 3fc576a
added tl scheme fot metric type
denisichh 6c6e917
fix .tl
denisichh 67a07ff
added tl::span
denisichh 202accd
rule of 5 for tl::span
denisichh 292da38
added from_bytes for tl::span
denisichh bd72a56
fix tl scheme
denisichh 1fef69e
removed tl::span, moved metrics tl classes
denisichh 954d130
removed unused include
denisichh b3b2335
removed unused space
denisichh 8308d75
removed monitoring system enum
denisichh 787afac
fix metric tl classes
denisichh 54003fb
added {}
denisichh 0a1c7a4
added requires
denisichh 6b6b303
send && fixed
denisichh e4bd9e8
fixes
denisichh 28a2773
fixes
denisichh 2310872
minor update
denisichh File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,205 @@ | ||
| // Compiler for PHP (aka KPHP) | ||
| // Copyright (c) 2026 LLC «V Kontakte» | ||
| // Distributed under the GPL v3 License, see LICENSE.notice.txt | ||
|
|
||
| #pragma once | ||
|
|
||
| #include <chrono> | ||
| #include <cstddef> | ||
| #include <cstdint> | ||
| #include <expected> | ||
| #include <memory> | ||
| #include <ranges> | ||
| #include <span> | ||
| #include <string_view> | ||
| #include <utility> | ||
|
|
||
| #include "runtime-common/core/allocator/script-allocator.h" | ||
| #include "runtime-common/core/std/containers.h" | ||
| #include "runtime-light/k2-platform/k2-api.h" | ||
|
|
||
| namespace kphp::diagnostics { | ||
|
|
||
| namespace details { | ||
| inline size_t string_sizeof(const std::string_view& string) noexcept { | ||
| return sizeof(size_t) + string.size(); | ||
| } | ||
|
|
||
| template<typename T> | ||
| concept tag_range = std::ranges::range<T> && requires(const std::ranges::range_value_t<T>& tag) { | ||
|
apolyakov marked this conversation as resolved.
Outdated
|
||
| std::string_view{tag.first}; | ||
| std::string_view{tag.second}; | ||
| }; | ||
| } // namespace details | ||
|
|
||
| struct metric final { | ||
| private: | ||
| using bytes_vector = kphp::stl::vector<std::byte, kphp::memory::script_allocator>; | ||
|
|
||
| const bytes_vector buffer; | ||
| k2::MonitoringSystem ms; | ||
|
|
||
| explicit metric(bytes_vector buffer, k2::MonitoringSystem ms) noexcept | ||
|
apolyakov marked this conversation as resolved.
Outdated
|
||
| : buffer{std::move(buffer)}, | ||
| ms{ms} {} | ||
|
|
||
| template<typename T> | ||
| requires std::is_arithmetic_v<T> | ||
| static void store_number(bytes_vector& buf, const T& number) noexcept { | ||
| const auto* src{static_cast<const std::byte*>(static_cast<const void*>(std::addressof(number)))}; | ||
| buf.insert(buf.end(), src, src + sizeof(T)); | ||
| } | ||
|
|
||
| static void store_string(bytes_vector& buf, const std::string_view& string) noexcept { | ||
| metric::store_number(buf, string.size()); | ||
| buf.append_range(std::as_bytes(std::span{string.data(), string.size()})); | ||
| } | ||
|
|
||
| static void store_tag(bytes_vector& buf, std::string_view tag_name, std::string_view tag_value) noexcept { | ||
| metric::store_string(buf, tag_name); | ||
| metric::store_string(buf, tag_value); | ||
| } | ||
|
|
||
| template<details::tag_range TagRange> | ||
| static void store_msg(bytes_vector& buf, std::string_view metric_name, size_t msg_size, TagRange&& tags) noexcept { | ||
| metric::store_number(buf, msg_size); | ||
| metric::store_string(buf, metric_name); | ||
| for (const auto& [tag_name, tag_value] : tags) { | ||
| metric::store_tag(buf, std::string_view{tag_name}, std::string_view{tag_value}); | ||
| } | ||
| } | ||
|
|
||
| static uint32_t s_timestamp_now() noexcept { | ||
|
apolyakov marked this conversation as resolved.
Outdated
|
||
| return std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count(); | ||
| } | ||
|
|
||
| template<details::tag_range TagRange> | ||
| static size_t calc_msg_size(std::string_view metric_name, TagRange&& tags) noexcept { | ||
| size_t result{kphp::diagnostics::details::string_sizeof(metric_name)}; | ||
| for (const auto& [tag_name, tag_value] : tags) { | ||
| result += kphp::diagnostics::details::string_sizeof(std::string_view{tag_name}) + kphp::diagnostics::details::string_sizeof(std::string_view{tag_value}); | ||
| } | ||
| return result; | ||
| } | ||
|
|
||
| public: | ||
| template<details::tag_range TagRange> | ||
| static metric from_value(k2::MonitoringSystem ms, std::string_view metric_name, TagRange&& tags, double value, | ||
| std::optional<uint32_t> timestamp = std::nullopt) noexcept { | ||
| size_t msg_size{metric::calc_msg_size(metric_name, tags)}; | ||
|
|
||
| bytes_vector buf{}; | ||
| buf.reserve(sizeof(uint32_t) + sizeof(uint8_t) + sizeof(double) + sizeof(size_t) + | ||
| msg_size); // timestamp_u32 + value_kind_u8 + value_f64 + msg_size_usize + msg_len | ||
|
|
||
| uint32_t s_timestamp{timestamp.value_or(metric::s_timestamp_now())}; | ||
|
|
||
| metric::store_number(buf, s_timestamp); | ||
| metric::store_number(buf, static_cast<uint8_t>(k2::MetricValueKind::VALUE)); | ||
| metric::store_number(buf, value); | ||
| metric::store_msg(buf, metric_name, msg_size, tags); | ||
| return metric{std::move(buf), ms}; | ||
| } | ||
|
|
||
| template<details::tag_range TagRange> | ||
| static metric from_values_array(k2::MonitoringSystem ms, std::string_view metric_name, TagRange&& tags, std::span<const double> values, | ||
| std::optional<uint32_t> timestamp = std::nullopt) noexcept { | ||
| size_t msg_size{metric::calc_msg_size(metric_name, tags)}; | ||
|
|
||
| bytes_vector buf{}; | ||
| buf.reserve(sizeof(uint32_t) + sizeof(uint8_t) + sizeof(size_t) + sizeof(double) * values.size() + sizeof(size_t) + | ||
| msg_size); // timestamp_u32 + value_kind_u8 + array_len_usize + value_f64*array_len + msg_size_usize + msg_len | ||
|
|
||
| uint32_t s_timestamp{timestamp.value_or(metric::s_timestamp_now())}; | ||
|
|
||
| metric::store_number(buf, s_timestamp); | ||
| metric::store_number(buf, static_cast<uint8_t>(k2::MetricValueKind::VALUES_ARRAY)); | ||
| metric::store_number(buf, values.size()); | ||
| for (const auto& value : values) { | ||
| metric::store_number(buf, value); | ||
| } | ||
| metric::store_msg(buf, metric_name, msg_size, tags); | ||
| return metric{std::move(buf), ms}; | ||
| } | ||
|
|
||
| template<details::tag_range TagRange> | ||
| static metric from_count(k2::MonitoringSystem ms, std::string_view metric_name, TagRange&& tags, uint32_t count, | ||
| std::optional<uint32_t> timestamp = std::nullopt) noexcept { | ||
| size_t msg_size{metric::calc_msg_size(metric_name, tags)}; | ||
|
|
||
| bytes_vector buf{}; | ||
| buf.reserve(sizeof(uint32_t) + sizeof(uint8_t) + sizeof(uint32_t) + sizeof(size_t) + | ||
| msg_size); // timestamp_u32 + value_kind_u8 + count_u32 + msg_size_usize + msg_len | ||
|
|
||
| uint32_t s_timestamp{timestamp.value_or(metric::s_timestamp_now())}; | ||
|
|
||
| metric::store_number(buf, s_timestamp); | ||
| metric::store_number(buf, static_cast<uint8_t>(k2::MetricValueKind::COUNT)); | ||
| metric::store_number(buf, count); | ||
| metric::store_msg(buf, metric_name, msg_size, tags); | ||
|
|
||
| return metric{std::move(buf), ms}; | ||
| } | ||
|
|
||
| template<details::tag_range TagRange> | ||
| static metric from_increment(k2::MonitoringSystem ms, std::string_view metric_name, TagRange&& tags, | ||
| std::optional<uint32_t> timestamp = std::nullopt) noexcept { | ||
| size_t msg_size{metric::calc_msg_size(metric_name, tags)}; | ||
|
|
||
| bytes_vector buf{}; | ||
| buf.reserve(sizeof(uint32_t) + sizeof(uint8_t) + sizeof(size_t) + msg_size); // timestamp_u32 + value_kind_u8 + msg_size_usize + msg_len | ||
|
|
||
| uint32_t s_timestamp{timestamp.value_or(metric::s_timestamp_now())}; | ||
|
|
||
| metric::store_number(buf, s_timestamp); | ||
| metric::store_number(buf, static_cast<uint8_t>(k2::MetricValueKind::INC)); | ||
| metric::store_msg(buf, metric_name, msg_size, tags); | ||
| return metric{std::move(buf), ms}; | ||
| } | ||
|
|
||
| std::expected<void, int32_t> send() noexcept { | ||
|
apolyakov marked this conversation as resolved.
Outdated
|
||
| return k2::write_metric(this->buffer, this->ms); | ||
| } | ||
| }; | ||
|
|
||
| // --------------------------------------------------------------------------------------------------------- | ||
|
|
||
| struct metric_builder final { | ||
| private: | ||
| kphp::stl::string<kphp::memory::script_allocator> metric_name; | ||
| kphp::stl::vector<std::pair<kphp::stl::string<kphp::memory::script_allocator>, kphp::stl::string<kphp::memory::script_allocator>>, | ||
| kphp::memory::script_allocator> | ||
| tags; | ||
| k2::MonitoringSystem ms; | ||
|
|
||
| explicit metric_builder(std::string_view metric_name, k2::MonitoringSystem ms) noexcept | ||
|
apolyakov marked this conversation as resolved.
Outdated
|
||
| : metric_name{metric_name}, | ||
| ms{ms} {} | ||
|
|
||
| public: | ||
| static metric_builder metric(std::string_view metric_name, k2::MonitoringSystem ms) noexcept { | ||
| return metric_builder{metric_name, ms}; | ||
| } | ||
|
|
||
| metric_builder& tag(std::string_view tag_name, std::string_view tag_value) noexcept { | ||
| this->tags.emplace_back(tag_name, tag_value); | ||
| return *this; | ||
| } | ||
|
|
||
| kphp::diagnostics::metric build_value(double value, std::optional<uint32_t> timestamp = std::nullopt) const noexcept { | ||
| return metric::from_value(this->ms, this->metric_name, this->tags, value, timestamp); | ||
| } | ||
|
|
||
| kphp::diagnostics::metric build_values_array(std::span<const double> values, std::optional<uint32_t> timestamp = std::nullopt) const noexcept { | ||
| return metric::from_values_array(this->ms, this->metric_name, this->tags, values, timestamp); | ||
| } | ||
|
|
||
| kphp::diagnostics::metric build_count(uint32_t count, std::optional<uint32_t> timestamp = std::nullopt) const noexcept { | ||
| return metric::from_count(this->ms, this->metric_name, this->tags, count, timestamp); | ||
| } | ||
|
|
||
| kphp::diagnostics::metric build_increment(std::optional<uint32_t> timestamp = std::nullopt) const noexcept { | ||
| return metric::from_increment(this->ms, this->metric_name, this->tags, timestamp); | ||
| } | ||
| }; | ||
| } // namespace kphp::diagnostics | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.