6#include <userver/compiler/impl/constexpr.hpp>
7#include <userver/logging/log_extra.hpp>
8#include <userver/logging/log_helper.hpp>
9#include <userver/utils/encoding/tskv.hpp>
11USERVER_NAMESPACE_BEGIN
15[[noreturn]]
void ThrowInvalidEscapedTagKey(std::string_view key);
19 template <
typename StringType,
typename Enabled = std::enable_if_t<
20 !std::is_same_v<StringType, TagKey>>>
23 std::string_view GetEscapedKey()
const noexcept;
26 std::string_view escaped_key_;
29class RuntimeTagKey
final {
31 explicit RuntimeTagKey(std::string_view unescaped_key);
33 std::string_view GetUnescapedKey()
const noexcept;
36 std::string_view unescaped_key_;
43 void PutTag(TagKey key,
const T& value);
46 void PutTag(RuntimeTagKey key,
const T& value);
49 void PutLogExtra(
const LogExtra& extra);
53 void ExtendLogExtra(
const LogExtra& extra);
56 friend class logging::LogHelper;
58 explicit TagWriter(LogHelper& lh)
noexcept;
60 void PutKey(TagKey key);
61 void PutKey(RuntimeTagKey key);
63 void MarkValueEnd()
noexcept;
68constexpr bool DoesTagNeedEscaping(std::string_view key)
noexcept {
69 for (
const char c : key) {
70 const bool needs_no_escaping_in_all_formats =
71 (c >=
'a' && c <=
'z') || (c >=
'A' && c <=
'Z') ||
72 (c >=
'0' && c <=
'9') || c ==
'_' || c ==
'-' || c ==
'/';
73 if (!needs_no_escaping_in_all_formats) {
80template <
typename StringType,
typename Enabled>
82 : escaped_key_(escaped_key) {
83 if (DoesTagNeedEscaping(escaped_key_)) {
84 ThrowInvalidEscapedTagKey(escaped_key_);
89void TagWriter::PutTag(TagKey key,
const T& value) {
96void TagWriter::PutTag(RuntimeTagKey key,
const T& value) {