userver
C++ Async Framework
Toggle main menu visibility
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
<
limits
>
7
8
#
include
<
fmt
/
format
.
h
>
9
#
include
<
google
/
protobuf
/
message
.
h
>
10
#
include
<
grpcpp
/
support
/
status
.
h
>
11
12
USERVER_NAMESPACE_BEGIN
13
14
namespace
ugrpc {
15
16
inline
constexpr
std::size_t kDefaultLoggingStringLimit = 1024;
17
18
/// @brief Convert protobuf message to a limited JSON string for logging.
19
///
20
/// The message is serialized to [ProtoJSON](https://protobuf.dev/programming-guides/json/) with the following
21
/// debugging tweaks:
22
/// - Fields marked with the `[debug_redact]` option are hidden: their value is replaced with a `[REDACTED]` marker.
23
/// - Serialization stops early once `limit` bytes have been produced instead of serializing the whole message and
24
/// only then truncating, which saves CPU on large messages. The already-open JSON containers are closed, so the
25
/// truncated part before the marker stays a well-formed JSON document.
26
/// - When truncated, the string ends with a `...(truncated)` marker to indicate that the output was cut off.
27
///
28
/// @param message The protobuf message to convert.
29
/// @param limit Maximum size of the resulting string (excluding the truncation marker).
30
/// Avoid setting this to very large values as it may cause OOM (Out of Memory) issues.
31
/// @returns JSON representation of the message, truncated if necessary.
32
///
33
/// @warning This is a debug representation of protobuf that is unstable and should only be used for diagnostics.
34
/// The order of keys in maps is unstable; the format itself can change even within a single run.
35
/// You CANNOT parse back from this (possibly truncated) representation.
36
/// You CANNOT use it for equality match with reference values in gtest.
37
///
38
/// @note This function is `noexcept` and is safe to call from logging code and other no-throw contexts. If @a message
39
/// cannot be serialized to ProtoJSON, the error is not propagated: the returned string instead has the form
40
/// `serialization failed: <error description>`.
41
std::string
ToLimitedLoggingString
(
42
const
google::protobuf::Message& message,
43
std::size_t limit = kDefaultLoggingStringLimit
44
)
noexcept
;
45
46
/// @brief Convert protobuf message to an unlimited JSON string for logging.
47
///
48
/// Convenience overload equivalent to calling @ref ToLimitedLoggingString with no effective size limit: the whole
49
/// message is serialized and the result never carries a `...(truncated)` marker. See @ref ToLimitedLoggingString for
50
/// the exact serialization behavior, the `noexcept` guarantee and the error-handling contract.
51
///
52
/// @param message The protobuf message to convert.
53
/// @returns JSON representation of the whole message.
54
///
55
/// @warning Serializes the entire message, so avoid this overload on unbounded input; prefer @ref
56
/// ToLimitedLoggingString for logging.
57
inline
std::string
ToUnlimitedLoggingString
(
const
google::protobuf::Message& message)
noexcept
{
58
return
ToLimitedLoggingString
(
message
,
/*limit*/
std::numeric_limits<std::size_t>::max()
)
;
59
}
60
61
/// @brief Get error details from `grpc::Status` for logging with size limit.
62
/// @param status The `grpc::Status` to extract details from.
63
/// @param limit Maximum size of the `"details"` part: forwarded as-is to the nested @ref ToLimitedLoggingString
64
/// call for the attached `google.rpc.Status`. `code`/`message` are not size-limited.
65
/// Avoid setting this to very large values as it may cause OOM (Out of Memory) issues.
66
/// @returns JSON object with a `"code"` key (always present, e.g. `{"code":"OK"}`), plus a `"message"` key when
67
/// `status.error_message()` is non-empty, plus a `"details"` key when `status` carries a parseable
68
/// `google.rpc.Status`, holding the JSON produced by
69
/// @ref ToLimitedLoggingString(const google::protobuf::Message&, std::size_t) for that attached status. For an OK
70
/// status both `message` and `details` are normally absent, so the result is just `{"code":"OK"}`.
71
///
72
/// @warning This is a debug representation of protobuf that is unstable and should only be used for diagnostics.
73
/// The order of keys in maps is unstable; the format itself can change even within a single run.
74
/// You CANNOT parse back from this representation.
75
/// You CANNOT use it for equality match with reference values in gtest.
76
/// @warning If `<details>` ends up truncated (or its own serialization fails), the `...(truncated)` marker (or a
77
/// `serialization failed: ...` message) is embedded as raw, unquoted text in place of the `"details"` value, which
78
/// makes the overall result invalid JSON in that case. `code` and `message` are always properly JSON-escaped and
79
/// cannot break the surrounding JSON.
80
///
81
/// @note This function does not itself catch exceptions; its `noexcept` guarantee relies on
82
/// `formats::json::StringBuilder` and the nested
83
/// @ref ToLimitedLoggingString(const google::protobuf::Message&, std::size_t) call (used to produce `<details>`)
84
/// never throwing.
85
std::string
ToLimitedLoggingString
(
const
grpc::Status& status, std::size_t limit = kDefaultLoggingStringLimit)
noexcept
;
86
87
/// @brief Get error details from `grpc::Status` for logging without size limit.
88
///
89
/// Convenience overload equivalent to calling @ref ToLimitedLoggingString with no effective size limit: the whole
90
/// details part is serialized and never carries a `...(truncated)` marker. See @ref ToLimitedLoggingString for the
91
/// output format, the `noexcept` guarantee and the error-handling contract.
92
///
93
/// @param status The `grpc::Status` to extract details from.
94
/// @returns JSON representation of the status with its full details.
95
///
96
/// @warning Serializes the entire details part, so avoid this overload on unbounded input; prefer @ref
97
/// ToLimitedLoggingString for logging.
98
inline
std::string
ToUnlimitedLoggingString
(
const
grpc::Status& status)
noexcept
{
99
return
ToLimitedLoggingString
(
status
,
/*limit=*/
std::numeric_limits<std::size_t>::max()
)
;
100
}
101
102
}
// namespace ugrpc
103
104
USERVER_NAMESPACE_END
105
106
namespace
fmt {
107
108
/// @brief `fmt::format` support for protobuf messages
109
template
<
typename
T>
110
requires
std::is_base_of_v<google::protobuf::Message, std::decay_t<T>>
111
struct
formatter
<T> {
112
constexpr
auto
parse(format_parse_context& ctx) {
return
ctx.begin(); }
113
114
template
<
typename
FormatContext>
115
auto
format(
const
T& message, FormatContext& ctx)
const
{
116
return
fmt::format_to(ctx.out(),
"{}"
, USERVER_NAMESPACE::ugrpc::ToLimitedLoggingString(message));
117
}
118
};
119
120
}
// namespace fmt
userver
ugrpc
protobuf_logging.hpp
Generated on
for userver by
Doxygen
1.17.0