userver: userver/utest/log_capture_fixture.hpp Source File
Loading...
Searching...
No Matches
log_capture_fixture.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/utest/log_capture_fixture.hpp
4/// @brief @copybrief utest::LogCaptureFixture
5
6#include <iosfwd>
7#include <optional>
8#include <string>
9#include <string_view>
10#include <utility>
11#include <vector>
12
13#include <gtest/gtest.h>
14
15#include <userver/logging/impl/logger_base.hpp>
16#include <userver/logging/level.hpp>
17#include <userver/logging/log.hpp>
18#include <userver/utest/default_logger_fixture.hpp>
19#include <userver/utils/function_ref.hpp>
20#include <userver/utils/impl/internal_tag.hpp>
21#include <userver/utils/impl/source_location.hpp>
22#include <userver/utils/not_null.hpp>
23#include <userver/utils/span.hpp>
24
25USERVER_NAMESPACE_BEGIN
26
27namespace utest {
28
29namespace impl {
30class ToStringLogger;
31} // namespace impl
32
33/// @brief Represents single log record, typically written via `LOG_*` macros.
34/// @see @ref utest::LogCaptureLogger
35/// @see @ref utest::LogCaptureFixture
36class LogRecord final {
37public:
38 /// @returns decoded text of the log record
39 /// @throws if no 'text' tag in the log
40 const std::string& GetText() const;
41
42 /// @returns decoded value of the tag in the log record
43 /// @throws if no such tag in the log
44 const std::string& GetTag(std::string_view key) const;
45
46 /// @returns decoded value of the tag in the log record, or `std::nullopt`
47 std::optional<std::string> GetTagOptional(std::string_view key) const;
48
49 /// @returns decoded value of the tag in the log record, or `nullptr`
50 const std::string* GetTagOrNullptr(std::string_view key) const;
51
52 /// @returns serialized log record
53 const std::string& GetLogRaw() const;
54
55 /// @returns the log level of the record
57
58 /// @cond
59 // For internal use only.
60 LogRecord(utils::impl::InternalTag, logging::Level level, std::string&& log_raw);
61 /// @endcond
62
63private:
64 logging::Level level_;
65 std::string log_raw_;
66 std::vector<std::pair<std::string, std::string>> tags_;
67};
68
69std::ostream& operator<<(std::ostream&, const LogRecord& data);
70
71std::ostream& operator<<(std::ostream&, const std::vector<LogRecord>& data);
72
73/// Thrown by @ref GetSingleLog.
74class NotSingleLogError final : public std::runtime_error {
75public:
76 using std::runtime_error::runtime_error;
77};
78
79/// @returns the only log record from `log`.
80/// @throws NotSingleLogError if there are zero or multiple log records.
81LogRecord GetSingleLog(
82 utils::span<const LogRecord> log,
83 const utils::impl::SourceLocation& source_location = utils::impl::SourceLocation::Current()
84);
85
86/// @brief A mocked logger that stores the log records in memory.
87/// @see @ref utest::LogCaptureFixture
88class LogCaptureLogger final {
89public:
90 explicit LogCaptureLogger(logging::Format format = logging::Format::kRaw);
91
92 /// @returns the mocked logger.
93 logging::LoggerPtr GetLogger() const;
94
95 /// @returns all collected logs.
96 /// @see @ref GetSingleLog
98
99 /// @returns logs filtered by (optional) text substring and (optional) tags
100 /// substrings.
101 /// @see @ref GetSingleLog
105 ) const;
106
107 /// @returns logs filtered by an arbitrary predicate.
108 /// @see @ref GetSingleLog
110
111 /// @brief Discards the collected logs.
112 void Clear() noexcept;
113
114 /// @brief Logs @a value as-if using `LOG_*`, then extracts the log text.
115 template <typename T>
116 std::string ToStringViaLogging(const T& value) {
117 Clear();
118 LOG_CRITICAL() << value;
119 auto text = GetSingleLog(GetAll()).GetText();
120 Clear();
121 return text;
122 }
123
124private:
125 utils::SharedRef<impl::ToStringLogger> logger_;
126};
127
128/// @brief Fixture that allows to capture and extract log written into the
129/// default logger.
130/// @see @ref utest::LogCaptureLogger
131template <typename Base = ::testing::Test>
133protected:
134 LogCaptureFixture() { DefaultLoggerFixture<Base>::SetDefaultLogger(logger_.GetLogger()); }
135
136 LogCaptureLogger& GetLogCapture() { return logger_; }
137
138private:
139 LogCaptureLogger logger_;
140};
141
142} // namespace utest
143
144USERVER_NAMESPACE_END