/src/PcapPlusPlus/Common++/src/Logger.cpp
Line | Count | Source |
1 | | #include "Logger.h" |
2 | | |
3 | | #include <iostream> |
4 | | #include <iomanip> |
5 | | #include <sstream> |
6 | | #include <cstring> |
7 | | #include <mutex> |
8 | | |
9 | | namespace pcpp |
10 | | { |
11 | | |
12 | | namespace |
13 | | { |
14 | | /// Default log printer function that prints to std::cerr. |
15 | | void printToCerr(LogLevel logLevel, const std::string& logMessage, const std::string& file, |
16 | | const std::string& method, const int line) |
17 | 0 | { |
18 | | // This mutex is used to prevent multiple threads from writing to the console at the same time. |
19 | 0 | static std::mutex logMutex; |
20 | |
|
21 | 0 | std::ostringstream sstream; |
22 | 0 | sstream << file << ": " << method << ":" << line; |
23 | |
|
24 | 0 | std::unique_lock<std::mutex> const lock(logMutex); |
25 | 0 | std::cerr << std::left << "[" << std::setw(5) << Logger::logLevelAsString(logLevel) << ": " << std::setw(45) |
26 | 0 | << sstream.str() << "] " << logMessage << std::endl; |
27 | 0 | } |
28 | | } // namespace |
29 | | |
30 | | // Alpine Linux incorrectly declares strerror_r |
31 | | // https://stackoverflow.com/questions/41953104/strerror-r-is-incorrectly-declared-on-alpine-linux |
32 | | char* checkError(int /*unused*/, char* buffer, int /*unused*/) |
33 | 0 | { |
34 | 0 | return buffer; |
35 | 0 | } |
36 | | |
37 | | char* checkError(char* result, const char* /*unused*/, int /*unused*/) |
38 | 0 | { |
39 | 0 | return result; |
40 | 0 | } |
41 | | |
42 | | std::string getErrorString(int errnum) |
43 | 0 | { |
44 | 0 | std::array<char, BUFSIZ> buffer{}; |
45 | | #if defined(_WIN32) |
46 | | strerror_s(buffer.data(), buffer.size(), errnum); |
47 | | return buffer.data(); |
48 | | #else |
49 | 0 | return checkError(strerror_r(errnum, buffer.data(), BUFSIZ), buffer.data(), errnum); |
50 | 0 | #endif |
51 | 0 | } |
52 | | |
53 | 1 | Logger::Logger() : m_LogsEnabled(true), m_LogPrinter(&printToCerr) |
54 | 1 | { |
55 | 1 | m_LastError.reserve(200); |
56 | 1 | m_LogModulesArray.fill(LogLevel::Info); |
57 | 1 | } |
58 | | |
59 | | std::string Logger::logLevelAsString(LogLevel logLevel) |
60 | 0 | { |
61 | 0 | switch (logLevel) |
62 | 0 | { |
63 | 0 | case LogLevel::Off: |
64 | 0 | return "OFF"; |
65 | 0 | case LogLevel::Error: |
66 | 0 | return "ERROR"; |
67 | 0 | case LogLevel::Warn: |
68 | 0 | return "WARN"; |
69 | 0 | case LogLevel::Info: |
70 | 0 | return "INFO"; |
71 | 0 | case LogLevel::Debug: |
72 | 0 | return "DEBUG"; |
73 | 0 | default: |
74 | 0 | return "UNKNOWN"; |
75 | 0 | } |
76 | 0 | } |
77 | | |
78 | | void Logger::resetLogPrinter() |
79 | 0 | { |
80 | 0 | m_LogPrinter = &printToCerr; // Reset to the default log printer |
81 | 0 | } |
82 | | |
83 | | std::unique_ptr<internal::LogContext> Logger::createLogContext() |
84 | 0 | { |
85 | 0 | return createLogContext(LogLevel::Info, {}); // call the other createLogContext method |
86 | 0 | } |
87 | | std::unique_ptr<internal::LogContext> Logger::createLogContext(LogLevel level, LogSource const& source) |
88 | 785 | { |
89 | 785 | if (m_UseContextPooling) |
90 | 785 | { |
91 | 785 | auto ctx = m_LogContextPool.acquireObject(); |
92 | 785 | ctx->init(level, source); |
93 | 785 | return ctx; |
94 | 785 | } |
95 | 0 | return std::make_unique<internal::LogContext>(level, source); |
96 | 785 | } |
97 | | |
98 | | void Logger::emit(std::unique_ptr<internal::LogContext> message) |
99 | 785 | { |
100 | 785 | emit(message->m_Source, message->m_Level, message->m_Stream.str()); |
101 | | // Pushes the message back to the pool if pooling is enabled. Otherwise, the message is deleted. |
102 | 785 | if (m_UseContextPooling) |
103 | 785 | { |
104 | 785 | m_LogContextPool.releaseObject(std::move(message)); |
105 | 785 | } |
106 | 785 | } |
107 | | |
108 | | void Logger::emit(LogSource const& source, LogLevel logLevel, std::string const& message) |
109 | 785 | { |
110 | | // If the log level is an error, save the error to the last error message variable. |
111 | 785 | if (logLevel == LogLevel::Error) |
112 | 785 | { |
113 | 785 | std::lock_guard<std::mutex> const lock(m_LastErrorMtx); |
114 | 785 | m_LastError = message; |
115 | 785 | } |
116 | 785 | if (m_LogsEnabled) |
117 | 0 | { |
118 | 0 | m_LogPrinter(logLevel, message, source.file, source.function, source.line); |
119 | 0 | } |
120 | 785 | } |
121 | | } // namespace pcpp |