-
Notifications
You must be signed in to change notification settings - Fork 45
/
filtered_logger.cpp
100 lines (74 loc) · 2.32 KB
/
filtered_logger.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#include "filtered_logger.h"
#include <algorithm>
#include <iostream>
extern "C" {
#include <libavutil/log.h>
}
FilteredLogger& FilteredLogger::instance() {
static FilteredLogger logger_instance;
return logger_instance;
}
FilteredLogger::FilteredLogger() {
reset();
}
void FilteredLogger::install(const std::string& pattern) {
set_regex_pattern(pattern);
av_log_set_callback(ffmpeg_log_callback);
}
void FilteredLogger::set_regex_pattern(const std::string& pattern) {
std::lock_guard<std::mutex> lock(mtx_);
try {
regex_ = std::regex(pattern);
} catch (const std::regex_error& e) {
std::cerr << "Error compiling regex: " << e.what() << std::endl;
throw;
}
}
bool FilteredLogger::log_callback(int level, const char* fmt, va_list vl) {
if (level == AV_LOG_INFO) {
std::string log_msg = format_message(fmt, vl);
std::lock_guard<std::mutex> lock(mtx_);
if (std::regex_search(log_msg, regex_)) {
log_to_buffer(log_msg);
return true;
}
}
return false;
}
std::string FilteredLogger::format_message(const char* fmt, va_list vl) {
va_list vl_copy;
va_copy(vl_copy, vl);
int needed_size = vsnprintf(nullptr, 0, fmt, vl_copy) + 1;
va_end(vl_copy);
if (needed_size <= 0) {
return "";
}
std::vector<char> temp_buffer(needed_size);
const int result = vsnprintf(temp_buffer.data(), temp_buffer.size(), fmt, vl);
if (result < 0 || result >= static_cast<int>(temp_buffer.size())) {
return "";
}
return std::string(temp_buffer.data());
}
void FilteredLogger::log_to_buffer(const std::string& msg) {
std::size_t remaining_space = log_buffer_.size() - log_buffer_index_;
std::size_t to_copy = std::min(msg.size(), remaining_space);
if (to_copy > 0) {
std::copy(msg.begin(), msg.begin() + to_copy, log_buffer_.begin() + log_buffer_index_);
log_buffer_index_ += to_copy;
}
}
std::string FilteredLogger::get_buffered_logs() {
std::lock_guard<std::mutex> lock(mtx_);
return std::string(log_buffer_.data(), log_buffer_index_);
}
void FilteredLogger::reset() {
std::lock_guard<std::mutex> lock(mtx_);
log_buffer_index_ = 0;
log_buffer_.front() = '\0';
}
void FilteredLogger::ffmpeg_log_callback(void* ptr, int level, const char* fmt, va_list vl) {
if (!instance().log_callback(level, fmt, vl)) {
av_log_default_callback(ptr, level, fmt, vl);
}
}