Easy Navigation
Loading...
Searching...
No Matches
LogCapture.hpp
Go to the documentation of this file.
1// Copyright 2026 Intelligent Robotics Lab
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
17
18#ifndef EASYNAV_COMMON__TESTING__LOGCAPTURE_HPP_
19#define EASYNAV_COMMON__TESTING__LOGCAPTURE_HPP_
20
21#include <cstdarg>
22#include <cstdio>
23#include <mutex>
24#include <string>
25#include <vector>
26
27#include "rcutils/logging.h"
28
29namespace easynav
30{
31namespace testing
32{
33
36{
37public:
38 struct Message
39 {
41 std::string text;
42 };
43
45 {
46 previous_ = rcutils_logging_get_output_handler();
47 std::lock_guard<std::mutex> lock(mutex());
48 messages().clear();
49 rcutils_logging_set_output_handler(&LogCapture::handler);
50 }
51
52 ~LogCapture() {rcutils_logging_set_output_handler(previous_);}
53
54 LogCapture(const LogCapture &) = delete;
55 LogCapture & operator=(const LogCapture &) = delete;
56
58 std::vector<std::string> find(
59 const std::vector<std::string> & parts, int severity = RCUTILS_LOG_SEVERITY_WARN) const
60 {
61 std::lock_guard<std::mutex> lock(mutex());
62 std::vector<std::string> found;
63 for (const auto & message : messages()) {
64 if (severity != -1 && message.severity != severity) {
65 continue;
66 }
67 bool all = true;
68 for (const auto & part : parts) {
69 all = all && message.text.find(part) != std::string::npos;
70 }
71 if (all) {
72 found.push_back(message.text);
73 }
74 }
75 return found;
76 }
77
79 size_t count(
80 const std::vector<std::string> & parts, int severity = RCUTILS_LOG_SEVERITY_WARN) const
81 {
82 return find(parts, severity).size();
83 }
84
85private:
86 static void handler(
87 const rcutils_log_location_t *, int severity, const char *, rcutils_time_point_value_t,
88 const char * format, va_list * args)
89 {
90 va_list copy;
91 va_copy(copy, *args);
92 char buffer[2048];
93 vsnprintf(buffer, sizeof(buffer), format, copy);
94 va_end(copy);
95 std::lock_guard<std::mutex> lock(mutex());
96 messages().push_back({severity, buffer});
97 }
98
99 static std::mutex & mutex()
100 {
101 static std::mutex m;
102 return m;
103 }
104
105 static std::vector<Message> & messages()
106 {
107 static std::vector<Message> m;
108 return m;
109 }
110
111 rcutils_logging_output_handler_t previous_;
112};
113
114} // namespace testing
115} // namespace easynav
116
117#endif // EASYNAV_COMMON__TESTING__LOGCAPTURE_HPP_
~LogCapture()
Definition LogCapture.hpp:52
LogCapture()
Definition LogCapture.hpp:44
size_t count(const std::vector< std::string > &parts, int severity=RCUTILS_LOG_SEVERITY_WARN) const
Number of messages containing every one of parts (warnings by default).
Definition LogCapture.hpp:79
LogCapture(const LogCapture &)=delete
LogCapture & operator=(const LogCapture &)=delete
std::vector< std::string > find(const std::vector< std::string > &parts, int severity=RCUTILS_LOG_SEVERITY_WARN) const
Messages containing every one of parts, with severity severity (-1: any).
Definition LogCapture.hpp:58
Definition LogCapture.hpp:32
Definition CircularBuffer.hpp:24
Definition LogCapture.hpp:39
int severity
Definition LogCapture.hpp:40
std::string text
Definition LogCapture.hpp:41