userver: userver/ugrpc/protobuf_logging.hpp Source File
Loading...
Searching...
No Matches
protobuf_logging.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file
4/// @brief Public API for protobuf logging utilities.
5
6#include <fmt/format.h>
7#include <google/protobuf/message.h>
8#include <grpcpp/support/status.h>
9
10USERVER_NAMESPACE_BEGIN
11
12namespace ugrpc {
13
14inline constexpr std::size_t kDefaultDebugStringLimit = 1024;
15
16/// @brief Convert protobuf message to limited debug string for logging.
17///
18/// Differences from built-in `DebugString`:
19/// - Fields marked with `[debug_redact]` option are hidden (`DebugString` only does so since Protobuf v30).
20/// - When the character limit is reached, serialization stops immediately (`DebugString` still wastes CPU on
21/// serializing the entire message regardless).
22///
23/// @param message The protobuf message to convert.
24/// @param limit Maximum size of the resulting string.
25/// Avoid setting this to very large values as it may cause OOM (Out of Memory) issues.
26/// @returns String representation of the message, truncated if necessary.
27///
28/// @warning This is a debug representation of protobuf that is unstable and should only be used for diagnostics.
29/// The order of keys in maps is unstable; the format itself can change even within a single run.
30/// You CANNOT parse back from this debug text representation.
31/// You CANNOT use it for equality match with reference values in gtest.
32std::string ToLimitedDebugString(const google::protobuf::Message& message, std::size_t limit);
33
34/// @brief Convert protobuf message to unlimited debug string for logging.
35///
36/// Differences from built-in `DebugString`:
37/// - Fields marked with `[debug_redact]` option are hidden (`DebugString` only does so since Protobuf v30).
38///
39/// @param message The protobuf message to convert.
40/// @returns String representation of the message.
41///
42/// @warning This is a debug representation of protobuf that is unstable and should only be used for diagnostics.
43/// The order of keys in maps is unstable; the format itself can change even within a single run.
44/// You CANNOT parse back from this debug text representation.
45/// You CANNOT use it for equality match with reference values in gtest.
46std::string ToUnlimitedDebugString(const google::protobuf::Message& message);
47
48/// @brief Get error details from `grpc::Status` for logging with size limit.
49/// @param status The `grpc::Status` to extract details from.
50/// @param max_size Maximum size of the resulting string.
51/// Avoid setting this to very large values as it may cause OOM (Out of Memory) issues.
52/// @returns String representation of error details, truncated if necessary.
53///
54/// @warning This is a debug representation of protobuf that is unstable and should only be used for diagnostics.
55/// The order of keys in maps is unstable; the format itself can change even within a single run.
56/// You CANNOT parse back from this debug text representation.
57/// You CANNOT use it for equality match with reference values in gtest.
58std::string ToLimitedDebugString(const grpc::Status& status, std::size_t max_size = kDefaultDebugStringLimit);
59
60/// @brief Get error details from `grpc::Status` for logging without size limit.
61/// @param status The `grpc::Status` to extract details from.
62/// @returns String representation of error details.
63///
64/// @warning This is a debug representation of protobuf that is unstable and should only be used for diagnostics.
65/// The order of keys in maps is unstable; the format itself can change even within a single run.
66/// You CANNOT parse back from this debug text representation.
67/// You CANNOT use it for equality match with reference values in gtest.
68std::string ToUnlimitedDebugString(const grpc::Status& status);
69
70} // namespace ugrpc
71
72USERVER_NAMESPACE_END
73
74namespace fmt {
75
76/// @brief `fmt::format` support for protobuf messages
77template <typename T>
78struct formatter<T, typename std::enable_if_t<std::is_base_of_v<google::protobuf::Message, std::decay_t<T>>, char>> {
79 constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
80
81 template <typename FormatContext>
82 auto format(const T& message, FormatContext& ctx) const {
83 return fmt::format_to(
84 ctx.out(),
85 "{}",
86 USERVER_NAMESPACE::ugrpc::ToLimitedDebugString(message, USERVER_NAMESPACE::ugrpc::kDefaultDebugStringLimit)
87 );
88 }
89};
90
91} // namespace fmt