Coverage Report

Created: 2025-08-26 06:53

/src/PcapPlusPlus/Common++/header/Logger.h
Line
Count
Source (jump to first uncovered line)
1
#pragma once
2
3
#include <cstdio>
4
#include <cstdint>
5
#include <memory>
6
#include <array>
7
#include <mutex>
8
#include <ostream>
9
#include <sstream>
10
#include <functional>
11
#include "DeprecationUtils.h"
12
#include "ObjectPool.h"
13
14
#ifndef LOG_MODULE
15
0
# define LOG_MODULE UndefinedLogModule
16
#endif
17
18
// Use __FILE_NAME__ to avoid leaking complete full path
19
#ifdef __FILE_NAME__
20
774
# define PCAPPP_FILENAME __FILE_NAME__
21
#else
22
# define PCAPPP_FILENAME __FILE__
23
#endif
24
25
/// @file
26
27
// Compile time log levels.
28
// Allows for conditional removal of unwanted log calls at compile time.
29
#define PCPP_LOG_LEVEL_OFF 0
30
#define PCPP_LOG_LEVEL_ERROR 1
31
#define PCPP_LOG_LEVEL_WARN 2
32
#define PCPP_LOG_LEVEL_INFO 3
33
#define PCPP_LOG_LEVEL_DEBUG 4
34
35
// All log messages built via a PCPP_LOG_* macro below the PCPP_ACTIVE_LOG_LEVEL will be removed at compile time.
36
// Uses the PCPP_ACTIVE_LOG_LEVEL if it is defined, otherwise defaults to PCAP_LOG_LEVEL_DEBUG
37
#ifndef PCPP_ACTIVE_LOG_LEVEL
38
# define PCPP_ACTIVE_LOG_LEVEL PCPP_LOG_LEVEL_DEBUG
39
#endif  // !PCPP_ACTIVE_LOG_LEVEL
40
41
/// @namespace pcpp
42
/// @brief The main namespace for the PcapPlusPlus lib
43
namespace pcpp
44
{
45
  /// Cross-platform and thread-safe version of strerror
46
  /// @param errnum Value of errno
47
  /// @return String representation of the error number
48
  std::string getErrorString(int errnum);
49
50
  /// An enum representing all PcapPlusPlus modules
51
  enum LogModule : uint8_t
52
  {
53
    UndefinedLogModule,
54
    CommonLogModuleIpUtils,          ///< IP Utils module (Common++)
55
    CommonLogModuleTablePrinter,     ///< Table printer module (Common++)
56
    CommonLogModuleGenericUtils,     ///< Generic Utils (Common++)
57
    PacketLogModuleRawPacket,        ///< RawPacket module (Packet++)
58
    PacketLogModulePacket,           ///< Packet module (Packet++)
59
    PacketLogModuleLayer,            ///< Layer module (Packet++)
60
    PacketLogModuleAsn1Codec,        ///< Asn1Codec module (Packet++)
61
    PacketLogModuleArpLayer,         ///< ArpLayer module (Packet++)
62
    PacketLogModuleEthLayer,         ///< EthLayer module (Packet++)
63
    PacketLogModuleIPv4Layer,        ///< IPv4Layer module (Packet++)
64
    PacketLogModuleIPv6Layer,        ///< IPv6Layer module (Packet++)
65
    PacketLogModulePayloadLayer,     ///< PayloadLayer module (Packet++)
66
    PacketLogModuleTcpLayer,         ///< TcpLayer module (Packet++)
67
    PacketLogModuleUdpLayer,         ///< UdpLayer module (Packet++)
68
    PacketLogModuleVlanLayer,        ///< VlanLayer module (Packet++)
69
    PacketLogModuleHttpLayer,        ///< HttpLayer module (Packet++)
70
    PacketLogModulePPPoELayer,       ///< PPPoELayer module (Packet++)
71
    PacketLogModuleDnsLayer,         ///< DnsLayer module (Packet++)
72
    PacketLogModuleMplsLayer,        ///< MplsLayer module (Packet++)
73
    PacketLogModuleIcmpLayer,        ///< IcmpLayer module (Packet++)
74
    PacketLogModuleIcmpV6Layer,      ///< IcmpV6Layer module (Packet++)
75
    PacketLogModuleGreLayer,         ///< GreLayer module (Packet++)
76
    PacketLogModuleSSLLayer,         ///< SSLLayer module (Packet++)
77
    PacketLogModuleSllLayer,         ///< SllLayer module (Packet++)
78
    PacketLogModuleSll2Layer,        ///< Sll2Layer module (Packet++)
79
    PacketLogModuleNflogLayer,       ///< NflogLayer module (Packet++)
80
    PacketLogModuleDhcpLayer,        ///< DhcpLayer module (Packet++)
81
    PacketLogModuleDhcpV6Layer,      ///< DhcpV6Layer module (Packet++)
82
    PacketLogModuleIgmpLayer,        ///< IgmpLayer module (Packet++)
83
    PacketLogModuleSipLayer,         ///< SipLayer module (Packet++)
84
    PacketLogModuleSdpLayer,         ///< SdpLayer module (Packet++)
85
    PacketLogModuleRadiusLayer,      ///< RadiusLayer module (Packet++)
86
    PacketLogModuleGtpLayer,         ///< GtpLayer module (Packet++)
87
    PacketLogModuleBgpLayer,         ///< GtpLayer module (Packet++)
88
    PacketLogModuleSSHLayer,         ///< SSHLayer module (Packet++)
89
    PacketLogModuleVrrpLayer,        ///< Vrrp Record module (Packet++)
90
    PacketLogModuleTcpReassembly,    ///< TcpReassembly module (Packet++)
91
    PacketLogModuleIPReassembly,     ///< IPReassembly module (Packet++)
92
    PacketLogModuleIPSecLayer,       ///< IPSecLayers module (Packet++)
93
    PacketLogModuleNtpLayer,         ///< NtpLayer module (Packet++)
94
    PacketLogModuleTelnetLayer,      ///< TelnetLayer module (Packet++)
95
    PacketLogModuleStpLayer,         ///< StpLayer module (Packet++)
96
    PacketLogModuleLLCLayer,         ///< LLCLayer module (Packet++)
97
    PacketLogModuleNdpLayer,         ///< NdpLayer module (Packet++)
98
    PacketLogModuleFtpLayer,         ///< FtpLayer module (Packet++)
99
    PacketLogModuleSomeIpLayer,      ///< SomeIpLayer module (Packet++)
100
    PacketLogModuleSomeIpSdLayer,    ///< SomeIpSdLayer module (Packet++)
101
    PacketLogModuleWakeOnLanLayer,   ///< WakeOnLanLayer module (Packet++)
102
    PacketLogModuleSmtpLayer,        ///< SmtpLayer module (Packet++)
103
    PacketLogModuleWireGuardLayer,   ///< WireGuardLayer module (Packet++)
104
    PacketLogModuleDoIpLayer,        ///< DoipLayer module (Packet++)
105
    PcapLogModuleWinPcapLiveDevice,  ///< WinPcapLiveDevice module (Pcap++)
106
    PcapLogModuleRemoteDevice,       ///< WinPcapRemoteDevice module (Pcap++)
107
    PcapLogModuleLiveDevice,         ///< PcapLiveDevice module (Pcap++)
108
    PcapLogModuleFileDevice,         ///< FileDevice module (Pcap++)
109
    PcapLogModulePfRingDevice,       ///< PfRingDevice module (Pcap++)
110
    PcapLogModuleMBufRawPacket,      ///< MBufRawPacket module (Pcap++)
111
    PcapLogModuleDpdkDevice,         ///< DpdkDevice module (Pcap++)
112
    PcapLogModuleKniDevice,          ///< KniDevice module (Pcap++)
113
    PcapLogModuleXdpDevice,          ///< XdpDevice module (Pcap++)
114
    PcapLogModuleNetworkUtils,       ///< Network Utils module (Pcap++)
115
    NumOfLogModules
116
  };
117
118
  /// @struct LogSource
119
  /// Represents the source of a log message.
120
  /// Contains information about the source file, function, line number, and the log module.
121
  struct LogSource
122
  {
123
    /// Default constructor for LogSource.
124
2
    constexpr LogSource() = default;
125
126
    /// Constructor for LogSource with only the log module.
127
    /// @param logModule The log module.
128
    explicit constexpr LogSource(LogModule logModule) : logModule(logModule)
129
0
    {}
130
131
    /// Constructor for LogSource with all parameters.
132
    /// @param logModule The log module.
133
    /// @param file The source file.
134
    /// @param function The source function.
135
    /// @param line The line number.
136
    constexpr LogSource(LogModule logModule, const char* file, const char* function, int line)
137
774
        : file(file), function(function), line(line), logModule(logModule)
138
774
    {}
139
140
    const char* file = nullptr;               /**< The source file. */
141
    const char* function = nullptr;           /**< The source function. */
142
    int line = 0;                             /**< The line number. */
143
    LogModule logModule = UndefinedLogModule; /**< The log module. */
144
  };
145
146
  /// An enum representing the log level. Currently 4 log levels are supported: Off, Error, Info and Debug. Info is
147
  /// the default log level
148
  enum class LogLevel : uint8_t
149
  {
150
    Off = PCPP_LOG_LEVEL_OFF,      ///< No log messages are emitted.
151
    Error = PCPP_LOG_LEVEL_ERROR,  ///< Error level logs are emitted.
152
    Warn = PCPP_LOG_LEVEL_WARN,    ///< Warning level logs and above are emitted.
153
    Info = PCPP_LOG_LEVEL_INFO,    ///< Info level logs and above are emitted.
154
    Debug = PCPP_LOG_LEVEL_DEBUG   ///< Debug level logs and above are emitted.
155
  };
156
157
  inline std::ostream& operator<<(std::ostream& ostr, LogLevel lvl)
158
0
  {
159
0
    return ostr << static_cast<std::underlying_type_t<LogLevel>>(lvl);
160
0
  }
161
162
  // Forward declaration
163
  class Logger;
164
165
  namespace internal
166
  {
167
    /// @class LogContext
168
    /// @brief A context encapsulating the details of a single log message to be passed to the Logger.
169
    class LogContext
170
    {
171
    public:
172
      friend class pcpp::Logger;
173
174
      /// @brief Creates a context with an empty message with Info level and no source.
175
2
      LogContext() = default;
176
177
      /// @brief Creates a context with an empty message with the given level and source.
178
      /// @param level The log level for this message.
179
      /// @param source The log source.
180
0
      explicit LogContext(LogLevel level, LogSource const& source = {}) : m_Source(source), m_Level(level)
181
0
      {}
182
183
      /// @brief Initializes the context with an empty message and the given level and source.
184
      /// @param level The log level for this message.
185
      /// @param source The log source.
186
      void init(LogLevel level, LogSource const& source)
187
774
      {
188
774
        m_Source = source;
189
774
        m_Level = level;
190
774
        m_Stream.clear();
191
774
        m_Stream.str({});
192
774
      }
193
194
      /// @brief Appends to the message.
195
      /// @param value The value to append.
196
      /// @return A reference to this context.
197
      template <class T> LogContext& operator<<(T const& value)
198
3.15k
      {
199
3.15k
        m_Stream << value;
200
3.15k
        return *this;
201
3.15k
      }
Unexecuted instantiation: pcpp::internal::LogContext& pcpp::internal::LogContext::operator<< <char [54]>(char const (&) [54])
pcpp::internal::LogContext& pcpp::internal::LogContext::operator<< <std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
Line
Count
Source
198
774
      {
199
774
        m_Stream << value;
200
774
        return *this;
201
774
      }
pcpp::internal::LogContext& pcpp::internal::LogContext::operator<< <char [2]>(char const (&) [2])
Line
Count
Source
198
61
      {
199
61
        m_Stream << value;
200
61
        return *this;
201
61
      }
pcpp::internal::LogContext& pcpp::internal::LogContext::operator<< <char [46]>(char const (&) [46])
Line
Count
Source
198
713
      {
199
713
        m_Stream << value;
200
713
        return *this;
201
713
      }
pcpp::internal::LogContext& pcpp::internal::LogContext::operator<< <char [4]>(char const (&) [4])
Line
Count
Source
198
713
      {
199
713
        m_Stream << value;
200
713
        return *this;
201
713
      }
pcpp::internal::LogContext& pcpp::internal::LogContext::operator<< <char [256]>(char const (&) [256])
Line
Count
Source
198
713
      {
199
713
        m_Stream << value;
200
713
        return *this;
201
713
      }
pcpp::internal::LogContext& pcpp::internal::LogContext::operator<< <char [21]>(char const (&) [21])
Line
Count
Source
198
61
      {
199
61
        m_Stream << value;
200
61
        return *this;
201
61
      }
pcpp::internal::LogContext& pcpp::internal::LogContext::operator<< <int>(int const&)
Line
Count
Source
198
61
      {
199
61
        m_Stream << value;
200
61
        return *this;
201
61
      }
pcpp::internal::LogContext& pcpp::internal::LogContext::operator<< <char [31]>(char const (&) [31])
Line
Count
Source
198
61
      {
199
61
        m_Stream << value;
200
61
        return *this;
201
61
      }
Unexecuted instantiation: pcpp::internal::LogContext& pcpp::internal::LogContext::operator<< <char [18]>(char const (&) [18])
Unexecuted instantiation: pcpp::internal::LogContext& pcpp::internal::LogContext::operator<< <char [53]>(char const (&) [53])
Unexecuted instantiation: pcpp::internal::LogContext& pcpp::internal::LogContext::operator<< <char [14]>(char const (&) [14])
Unexecuted instantiation: pcpp::internal::LogContext& pcpp::internal::LogContext::operator<< <char [13]>(char const (&) [13])
Unexecuted instantiation: pcpp::internal::LogContext& pcpp::internal::LogContext::operator<< <char [47]>(char const (&) [47])
Unexecuted instantiation: pcpp::internal::LogContext& pcpp::internal::LogContext::operator<< <char [32]>(char const (&) [32])
Unexecuted instantiation: pcpp::internal::LogContext& pcpp::internal::LogContext::operator<< <char [36]>(char const (&) [36])
Unexecuted instantiation: pcpp::internal::LogContext& pcpp::internal::LogContext::operator<< <char [33]>(char const (&) [33])
Unexecuted instantiation: pcpp::internal::LogContext& pcpp::internal::LogContext::operator<< <char [30]>(char const (&) [30])
Unexecuted instantiation: pcpp::internal::LogContext& pcpp::internal::LogContext::operator<< <char [48]>(char const (&) [48])
Unexecuted instantiation: pcpp::internal::LogContext& pcpp::internal::LogContext::operator<< <char [56]>(char const (&) [56])
Unexecuted instantiation: pcpp::internal::LogContext& pcpp::internal::LogContext::operator<< <char [60]>(char const (&) [60])
Unexecuted instantiation: pcpp::internal::LogContext& pcpp::internal::LogContext::operator<< <char [55]>(char const (&) [55])
Unexecuted instantiation: pcpp::internal::LogContext& pcpp::internal::LogContext::operator<< <char [107]>(char const (&) [107])
Unexecuted instantiation: pcpp::internal::LogContext& pcpp::internal::LogContext::operator<< <char [44]>(char const (&) [44])
Unexecuted instantiation: pcpp::internal::LogContext& pcpp::internal::LogContext::operator<< <char [35]>(char const (&) [35])
Unexecuted instantiation: pcpp::internal::LogContext& pcpp::internal::LogContext::operator<< <char [49]>(char const (&) [49])
Unexecuted instantiation: pcpp::internal::LogContext& pcpp::internal::LogContext::operator<< <char const*>(char const* const&)
Unexecuted instantiation: pcpp::internal::LogContext& pcpp::internal::LogContext::operator<< <char [22]>(char const (&) [22])
Unexecuted instantiation: pcpp::internal::LogContext& pcpp::internal::LogContext::operator<< <char [26]>(char const (&) [26])
Unexecuted instantiation: pcpp::internal::LogContext& pcpp::internal::LogContext::operator<< <char [15]>(char const (&) [15])
Unexecuted instantiation: pcpp::internal::LogContext& pcpp::internal::LogContext::operator<< <char [17]>(char const (&) [17])
Unexecuted instantiation: pcpp::internal::LogContext& pcpp::internal::LogContext::operator<< <char [94]>(char const (&) [94])
Unexecuted instantiation: pcpp::internal::LogContext& pcpp::internal::LogContext::operator<< <pcpp::LinkLayerType>(pcpp::LinkLayerType const&)
Unexecuted instantiation: pcpp::internal::LogContext& pcpp::internal::LogContext::operator<< <char [3]>(char const (&) [3])
Unexecuted instantiation: pcpp::internal::LogContext& pcpp::internal::LogContext::operator<< <char [24]>(char const (&) [24])
Unexecuted instantiation: pcpp::internal::LogContext& pcpp::internal::LogContext::operator<< <char [27]>(char const (&) [27])
Unexecuted instantiation: pcpp::internal::LogContext& pcpp::internal::LogContext::operator<< <char [37]>(char const (&) [37])
Unexecuted instantiation: pcpp::internal::LogContext& pcpp::internal::LogContext::operator<< <char [41]>(char const (&) [41])
Unexecuted instantiation: pcpp::internal::LogContext& pcpp::internal::LogContext::operator<< <char [59]>(char const (&) [59])
Unexecuted instantiation: pcpp::internal::LogContext& pcpp::internal::LogContext::operator<< <char [45]>(char const (&) [45])
Unexecuted instantiation: pcpp::internal::LogContext& pcpp::internal::LogContext::operator<< <char [61]>(char const (&) [61])
Unexecuted instantiation: pcpp::internal::LogContext& pcpp::internal::LogContext::operator<< <char [23]>(char const (&) [23])
Unexecuted instantiation: pcpp::internal::LogContext& pcpp::internal::LogContext::operator<< <char [43]>(char const (&) [43])
Unexecuted instantiation: pcpp::internal::LogContext& pcpp::internal::LogContext::operator<< <char [28]>(char const (&) [28])
Unexecuted instantiation: pcpp::internal::LogContext& pcpp::internal::LogContext::operator<< <char [52]>(char const (&) [52])
Unexecuted instantiation: pcpp::internal::LogContext& pcpp::internal::LogContext::operator<< <char [40]>(char const (&) [40])
Unexecuted instantiation: pcpp::internal::LogContext& pcpp::internal::LogContext::operator<< <char [20]>(char const (&) [20])
Unexecuted instantiation: pcpp::internal::LogContext& pcpp::internal::LogContext::operator<< <char [38]>(char const (&) [38])
Unexecuted instantiation: pcpp::internal::LogContext& pcpp::internal::LogContext::operator<< <char [70]>(char const (&) [70])
Unexecuted instantiation: pcpp::internal::LogContext& pcpp::internal::LogContext::operator<< <unsigned long>(unsigned long const&)
Unexecuted instantiation: pcpp::internal::LogContext& pcpp::internal::LogContext::operator<< <char [42]>(char const (&) [42])
202
203
    private:
204
      std::ostringstream m_Stream;
205
      LogSource m_Source;
206
      LogLevel m_Level = LogLevel::Info;
207
    };
208
  }  // namespace internal
209
210
  /// @class Logger
211
  /// PcapPlusPlus logger manager.
212
  /// PcapPlusPlus uses this logger to output both error and debug logs.
213
  /// There are currently 3 log levels: Logger#Error, Logger#Info and Logger#Debug.
214
  ///
215
  /// PcapPlusPlus is divided into modules (described in #LogModule enum). The user can set the log level got each
216
  /// module or to all modules at once. The default is Logger#Info which outputs only error messages. Changing log
217
  /// level for modules can be done dynamically while the application is running.
218
  ///
219
  /// The logger also exposes a method to retrieve the last error log message.
220
  ///
221
  /// Logs are printed to console by default in a certain format. The user can set a different print function to
222
  /// change the format or to print to other media (such as files, etc.).
223
  ///
224
  /// PcapPlusPlus logger is a singleton which can be reached from anywhere in the code.
225
  ///
226
  /// Note: Logger#Info level logs are currently only used in DPDK devices to set DPDK log level to RTE_LOG_NOTICE.
227
  class Logger
228
  {
229
  public:
230
    Logger(const Logger&) = delete;
231
    Logger& operator=(const Logger&) = delete;
232
233
    // Deprecated, Use the LogLevel in the pcpp namespace instead.
234
    using LogLevel = pcpp::LogLevel;
235
    PCPP_DEPRECATED("Use the LogLevel in the pcpp namespace instead.")
236
    static const LogLevel Error = LogLevel::Error;
237
    PCPP_DEPRECATED("Use the LogLevel in the pcpp namespace instead.")
238
    static const LogLevel Info = LogLevel::Info;
239
    PCPP_DEPRECATED("Use the LogLevel in the pcpp namespace instead.")
240
    static const LogLevel Debug = LogLevel::Debug;
241
242
    /// @typedef LogPrinter
243
    /// Log printer callback. Used for printing the logs in a custom way.
244
    /// @param[in] logLevel The log level for this log message
245
    /// @param[in] logMessage The log message
246
    /// @param[in] file The source file in PcapPlusPlus code the log message is coming from
247
    /// @param[in] method The method in PcapPlusPlus code the log message is coming from
248
    /// @param[in] line The line in PcapPlusPlus code the log message is coming from
249
    /// @remarks The printer callback should support being called from multiple threads simultaneously.
250
    using LogPrinter = std::function<void(LogLevel logLevel, const std::string& logMessage, const std::string& file,
251
                                          const std::string& method, const int line)>;
252
253
    /// A static method for converting the log level enum to a string.
254
    /// @param[in] logLevel A log level enum
255
    /// @return The log level as a string
256
    static std::string logLevelAsString(LogLevel logLevel);
257
258
    /// Get the log level for a certain module
259
    /// @param[in] module PcapPlusPlus module
260
    /// @return The log level set for this module
261
    LogLevel getLogLevel(LogModule module)
262
0
    {
263
0
      return m_LogModulesArray[module];
264
0
    }
265
266
    /// Set the log level for a certain PcapPlusPlus module
267
    /// @param[in] module PcapPlusPlus module
268
    /// @param[in] level The log level to set the module to
269
    void setLogLevel(LogModule module, LogLevel level)
270
0
    {
271
0
      m_LogModulesArray[module] = level;
272
0
    }
273
274
    /// Check whether a certain module is set to debug log level
275
    /// @param[in] module PcapPlusPlus module
276
    /// @return True if this module log level is "debug". False otherwise
277
    bool isDebugEnabled(LogModule module) const
278
0
    {
279
0
      return m_LogModulesArray[module] == LogLevel::Debug;
280
0
    }
281
282
    /// @brief Check whether a log level should be emitted by the logger.
283
    /// @param level The level of the log message.
284
    /// @param module PcapPlusPlus module
285
    /// @return True if the message should be emitted. False otherwise.
286
    bool shouldLog(LogLevel level, LogModule module) const
287
23.5k
    {
288
23.5k
      return level != LogLevel::Off && m_LogModulesArray[module] >= level;
289
23.5k
    }
290
291
    /// Set all PcapPlusPlus modules to a certain log level
292
    /// @param[in] level The log level to set all modules to
293
    void setAllModulesToLogLevel(LogLevel level)
294
0
    {
295
0
      for (int i = 1; i < NumOfLogModules; i++)
296
0
      {
297
0
        m_LogModulesArray[i] = level;
298
0
      }
299
0
    }
300
301
    /// Set a custom log printer.
302
    /// @param[in] printer A log printer function that will be called for every log message
303
    void setLogPrinter(LogPrinter printer)
304
0
    {
305
0
      m_LogPrinter = printer;
306
0
    }
307
308
    /// Set the log printer back to the default printer
309
    void resetLogPrinter();
310
311
    /// @return Get the last error message
312
    std::string getLastError() const
313
0
    {
314
0
      std::lock_guard<std::mutex> const lock(m_LastErrorMtx);
315
0
      return m_LastError;
316
0
    }
317
318
    /// Suppress logs in all PcapPlusPlus modules
319
    void suppressLogs()
320
4.79k
    {
321
4.79k
      m_LogsEnabled = false;
322
4.79k
    }
323
324
    /// Enable logs in all PcapPlusPlus modules
325
    void enableLogs()
326
0
    {
327
0
      m_LogsEnabled = true;
328
0
    }
329
330
    /// Get an indication if logs are currently enabled.
331
    /// @return True if logs are currently enabled, false otherwise
332
    bool logsEnabled() const
333
0
    {
334
0
      return m_LogsEnabled;
335
0
    }
336
337
    /// @brief Controls if the logger should use a pool of LogContext objects.
338
    ///
339
    /// If enabled is set to false, preallocate and maxPoolSize are ignored.
340
    /// @param enabled True to enable context pooling, false to disable.
341
    /// @param preallocate The number of LogContext objects to preallocate in the pool.
342
    /// @param maxPoolSize The maximum number of LogContext objects to keep in the pool.
343
    /// @remarks Disabling the pooling clears the pool.
344
    void useContextPooling(bool enabled, std::size_t preallocate = 2, std::size_t maxPoolSize = 10)
345
0
    {
346
0
      m_UseContextPooling = enabled;
347
0
348
0
      if (m_UseContextPooling)
349
0
      {
350
0
        m_LogContextPool.setMaxSize(maxPoolSize);
351
0
352
0
        if (preallocate > 0)
353
0
        {
354
0
          m_LogContextPool.preallocate(preallocate);
355
0
        }
356
0
      }
357
0
      else
358
0
      {
359
0
        // Clear the pool if we're disabling pooling.
360
0
        m_LogContextPool.clear();
361
0
      }
362
0
    }
363
364
    /// Get access to Logger singleton
365
    /// @todo: make this singleton thread-safe/
366
    /// @return a pointer to the Logger singleton
367
    static Logger& getInstance()
368
28.3k
    {
369
28.3k
      static Logger instance;
370
28.3k
      return instance;
371
28.3k
    }
372
373
    /// @brief Creates a new LogContext with Info level and no source.
374
    /// @return A new LogContext.
375
    std::unique_ptr<internal::LogContext> createLogContext();
376
377
    /// @brief Creates a new LogContext with the given level and source.
378
    /// @param level The log level for this message.
379
    /// @param source The log source.
380
    /// @return A new LogContext.
381
    std::unique_ptr<internal::LogContext> createLogContext(LogLevel level, LogSource const& source = {});
382
383
    /// @brief Directly emits a log message bypassing all level checks.
384
    /// @param source The log source.
385
    /// @param level The log level for this message. This is only used for the log printer.
386
    /// @param message The log message.
387
    void emit(LogSource const& source, LogLevel level, std::string const& message);
388
389
    /// @brief Directly emits a log message bypassing all level checks.
390
    /// @param message The log message.
391
    void emit(std::unique_ptr<internal::LogContext> message);
392
393
  private:
394
    bool m_LogsEnabled;
395
    std::array<LogLevel, NumOfLogModules> m_LogModulesArray{};
396
    LogPrinter m_LogPrinter;
397
398
    mutable std::mutex m_LastErrorMtx;
399
    std::string m_LastError;
400
401
    bool m_UseContextPooling = true;
402
    // Keep a maximum of 10 LogContext objects in the pool.
403
    internal::DynamicObjectPool<internal::LogContext> m_LogContextPool{ 10, 2 };
404
405
    // private c'tor - this class is a singleton
406
    Logger();
407
  };
408
409
}  // namespace pcpp
410
411
#define PCPP_LOG(level, message)                                                                                       \
412
23.5k
  do                                                                                                                 \
413
23.5k
  {                                                                                                                  \
414
23.5k
    auto& logger = pcpp::Logger::getInstance();                                                                    \
415
23.5k
    if (logger.shouldLog(level, LOG_MODULE))                                                                       \
416
23.5k
    {                                                                                                              \
417
774
      auto ctx =                                                                                                 \
418
774
          logger.createLogContext(level, pcpp::LogSource(LOG_MODULE, PCAPPP_FILENAME, __FUNCTION__, __LINE__));  \
419
774
      (*ctx) << message;                                                                                         \
420
774
      logger.emit(std::move(ctx));                                                                               \
421
774
    }                                                                                                              \
422
23.5k
  } while (0)
423
424
#if PCPP_ACTIVE_LOG_LEVEL >= PCPP_LOG_LEVEL_DEBUG
425
22.7k
# define PCPP_LOG_DEBUG(message) PCPP_LOG(pcpp::LogLevel::Debug, message)
426
#else
427
# define PCPP_LOG_DEBUG(message) (void)0
428
#endif
429
430
#if PCPP_ACTIVE_LOG_LEVEL >= PCPP_LOG_LEVEL_WARN
431
# define PCPP_LOG_WARN(message) PCPP_LOG(pcpp::LogLevel::Warn, message)
432
#else
433
# define PCPP_LOG_WARN(message) (void)0
434
#endif
435
436
#if PCPP_ACTIVE_LOG_LEVEL >= PCPP_LOG_LEVEL_INFO
437
# define PCPP_LOG_INFO(message) PCPP_LOG(pcpp::LogLevel::Info, message)
438
#else
439
# define PCPP_LOG_INFO(message) (void)0
440
#endif
441
442
#if PCPP_ACTIVE_LOG_LEVEL >= PCPP_LOG_LEVEL_ERROR
443
774
# define PCPP_LOG_ERROR(message) PCPP_LOG(pcpp::LogLevel::Error, message)
444
#else
445
# define PCPP_LOG_ERROR(message) (void)0
446
#endif