PcapPlusPlus  Next
Logger.h
Go to the documentation of this file.
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 "DeprecationUtils.h"
11 #include "ObjectPool.h"
12 
13 #ifndef LOG_MODULE
14 # define LOG_MODULE UndefinedLogModule
15 #endif
16 
17 // Use __FILE_NAME__ to avoid leaking complete full path
18 #ifdef __FILE_NAME__
19 # define PCAPPP_FILENAME __FILE_NAME__
20 #else
21 # define PCAPPP_FILENAME __FILE__
22 #endif
23 
25 
26 // Compile time log levels.
27 // Allows for conditional removal of unwanted log calls at compile time.
28 #define PCPP_LOG_LEVEL_OFF 0
29 #define PCPP_LOG_LEVEL_ERROR 1
30 #define PCPP_LOG_LEVEL_INFO 2
31 #define PCPP_LOG_LEVEL_DEBUG 3
32 
33 // All log messages built via a PCPP_LOG_* macro below the PCPP_ACTIVE_LOG_LEVEL will be removed at compile time.
34 // Uses the PCPP_ACTIVE_LOG_LEVEL if it is defined, otherwise defaults to PCAP_LOG_LEVEL_DEBUG
35 #ifndef PCPP_ACTIVE_LOG_LEVEL
36 # define PCPP_ACTIVE_LOG_LEVEL PCPP_LOG_LEVEL_DEBUG
37 #endif // !PCPP_ACTIVE_LOG_LEVEL
38 
41 namespace pcpp
42 {
46  std::string getErrorString(int errnum);
47 
49  enum LogModule : uint8_t
50  {
51  UndefinedLogModule,
112  NumOfLogModules
113  };
114 
118  struct LogSource
119  {
121  constexpr LogSource() = default;
122 
126  {}
127 
133  constexpr LogSource(LogModule logModule, const char* file, const char* function, int line)
135  {}
136 
137  const char* file = nullptr;
138  const char* function = nullptr;
139  int line = 0;
140  LogModule logModule = UndefinedLogModule;
141  };
142 
145  enum class LogLevel
146  {
147  Off = PCPP_LOG_LEVEL_OFF,
148  Error = PCPP_LOG_LEVEL_ERROR,
149  Info = PCPP_LOG_LEVEL_INFO,
150  Debug = PCPP_LOG_LEVEL_DEBUG
151  };
152 
153  inline std::ostream& operator<<(std::ostream& s, LogLevel v)
154  {
155  return s << static_cast<std::underlying_type<LogLevel>::type>(v);
156  }
157 
158  // Forward declaration
159  class Logger;
160 
161  namespace internal
162  {
166  {
167  public:
168  friend class pcpp::Logger;
169 
171  LogContext() = default;
172 
176  explicit LogContext(LogLevel level, LogSource const& source = {}) : m_Source(source), m_Level(level)
177  {}
178 
182  void init(LogLevel level, LogSource const& source)
183  {
184  m_Source = source;
185  m_Level = level;
186  m_Stream.clear();
187  m_Stream.str({});
188  }
189 
193  template <class T> inline LogContext& operator<<(T const& value)
194  {
195  m_Stream << value;
196  return *this;
197  }
198 
199  private:
200  std::ostringstream m_Stream;
201  LogSource m_Source;
202  LogLevel m_Level = LogLevel::Info;
203  };
204  } // namespace internal
205 
223  class Logger
224  {
225  public:
226  Logger(const Logger&) = delete;
227  Logger& operator=(const Logger&) = delete;
228 
229  // Deprecated, Use the LogLevel in the pcpp namespace instead.
230  using LogLevel = pcpp::LogLevel;
231  PCPP_DEPRECATED("Use the LogLevel in the pcpp namespace instead.")
232  static const LogLevel Error = LogLevel::Error;
233  PCPP_DEPRECATED("Use the LogLevel in the pcpp namespace instead.")
234  static const LogLevel Info = LogLevel::Info;
235  PCPP_DEPRECATED("Use the LogLevel in the pcpp namespace instead.")
236  static const LogLevel Debug = LogLevel::Debug;
237 
246  using LogPrinter =
247  std::add_pointer<void(LogLevel logLevel, const std::string& logMessage, const std::string& file,
248  const std::string& method, const int line)>::type;
249 
253  static std::string logLevelAsString(LogLevel logLevel);
254 
259  {
260  return m_LogModulesArray[module];
261  }
262 
266  void setLogLevel(LogModule module, LogLevel level)
267  {
268  m_LogModulesArray[module] = level;
269  }
270 
274  bool isDebugEnabled(LogModule module) const
275  {
276  return m_LogModulesArray[module] == LogLevel::Debug;
277  }
278 
283  bool shouldLog(LogLevel level, LogModule module) const
284  {
285  return level != LogLevel::Off && m_LogModulesArray[module] >= level;
286  }
287 
291  {
292  for (int i = 1; i < NumOfLogModules; i++)
293  {
294  m_LogModulesArray[i] = level;
295  }
296  }
297 
300  void setLogPrinter(LogPrinter printer)
301  {
302  m_LogPrinter = printer;
303  }
304 
307  {
308  m_LogPrinter = &defaultLogPrinter;
309  }
310 
312  std::string getLastError() const
313  {
314  std::lock_guard<std::mutex> lock(m_LastErrorMtx);
315  return m_LastError;
316  }
317 
320  {
321  m_LogsEnabled = false;
322  }
323 
325  void enableLogs()
326  {
327  m_LogsEnabled = true;
328  }
329 
332  bool logsEnabled() const
333  {
334  return m_LogsEnabled;
335  }
336 
344  void useContextPooling(bool enabled, std::size_t preallocate = 2, std::size_t maxPoolSize = 10)
345  {
346  m_UseContextPooling = enabled;
347 
348  if (m_UseContextPooling)
349  {
350  m_LogContextPool.setMaxSize(maxPoolSize);
351 
352  if (preallocate > 0)
353  {
354  m_LogContextPool.preallocate(preallocate);
355  }
356  }
357  else
358  {
359  // Clear the pool if we're disabling pooling.
360  m_LogContextPool.clear();
361  }
362  }
363 
367  static Logger& getInstance()
368  {
369  static Logger instance;
370  return instance;
371  }
372 
375  std::unique_ptr<internal::LogContext> createLogContext();
376 
381  std::unique_ptr<internal::LogContext> createLogContext(LogLevel level, LogSource const& source = {});
382 
387  void emit(LogSource const& source, LogLevel level, std::string const& message);
388 
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  static void defaultLogPrinter(LogLevel logLevel, const std::string& logMessage, const std::string& file,
409  const std::string& method, int line);
410  };
411 
412 } // namespace pcpp
413 
414 #define PCPP_LOG(level, message) \
415  do \
416  { \
417  auto& logger = pcpp::Logger::getInstance(); \
418  if (logger.shouldLog(level, LOG_MODULE)) \
419  { \
420  auto ctx = \
421  logger.createLogContext(level, pcpp::LogSource(LOG_MODULE, PCAPPP_FILENAME, __FUNCTION__, __LINE__)); \
422  (*ctx) << message; \
423  logger.emit(std::move(ctx)); \
424  } \
425  } while (0)
426 
427 #if PCPP_ACTIVE_LOG_LEVEL >= PCPP_LOG_LEVEL_DEBUG
428 # define PCPP_LOG_DEBUG(message) PCPP_LOG(pcpp::LogLevel::Debug, message)
429 #else
430 # define PCPP_LOG_DEBUG(message) (void)0
431 #endif
432 
433 #if PCPP_ACTIVE_LOG_LEVEL >= PCPP_LOG_LEVEL_INFO
434 # define PCPP_LOG_INFO(message) PCPP_LOG(pcpp::LogLevel::Info, message)
435 #else
436 # define PCPP_LOG_INFO(message) (void)0
437 #endif
438 
439 #if PCPP_ACTIVE_LOG_LEVEL >= PCPP_LOG_LEVEL_ERROR
440 # define PCPP_LOG_ERROR(message) PCPP_LOG(pcpp::LogLevel::Error, message)
441 #else
442 # define PCPP_LOG_ERROR(message) (void)0
443 #endif
Definition: Logger.h:224
void setLogPrinter(LogPrinter printer)
Definition: Logger.h:300
void enableLogs()
Enable logs in all PcapPlusPlus modules.
Definition: Logger.h:325
void emit(LogSource const &source, LogLevel level, std::string const &message)
Directly emits a log message bypassing all level checks.
void setLogLevel(LogModule module, LogLevel level)
Definition: Logger.h:266
std::string getLastError() const
Definition: Logger.h:312
LogLevel getLogLevel(LogModule module)
Definition: Logger.h:258
void useContextPooling(bool enabled, std::size_t preallocate=2, std::size_t maxPoolSize=10)
Controls if the logger should use a pool of LogContext objects.
Definition: Logger.h:344
bool shouldLog(LogLevel level, LogModule module) const
Check whether a log level should be emitted by the logger.
Definition: Logger.h:283
bool logsEnabled() const
Definition: Logger.h:332
void resetLogPrinter()
Set the log printer back to the default printer.
Definition: Logger.h:306
static Logger & getInstance()
Definition: Logger.h:367
std::unique_ptr< internal::LogContext > createLogContext()
Creates a new LogContext with Info level and no source.
void emit(std::unique_ptr< internal::LogContext > message)
Directly emits a log message bypassing all level checks.
void suppressLogs()
Suppress logs in all PcapPlusPlus modules.
Definition: Logger.h:319
static std::string logLevelAsString(LogLevel logLevel)
std::unique_ptr< internal::LogContext > createLogContext(LogLevel level, LogSource const &source={})
Creates a new LogContext with the given level and source.
std::add_pointer< void(LogLevel logLevel, const std::string &logMessage, const std::string &file, const std::string &method, const int line)>::type LogPrinter
Definition: Logger.h:248
bool isDebugEnabled(LogModule module) const
Definition: Logger.h:274
void setAllModulesToLogLevel(LogLevel level)
Definition: Logger.h:290
A generic object pool implementation.
Definition: ObjectPool.h:23
A context encapsulating the details of a single log message to be passed to the Logger.
Definition: Logger.h:166
LogContext()=default
Creates a context with an empty message with Info level and no source.
LogContext(LogLevel level, LogSource const &source={})
Creates a context with an empty message with the given level and source.
Definition: Logger.h:176
void init(LogLevel level, LogSource const &source)
Initializes the context with an empty message and the given level and source.
Definition: Logger.h:182
LogContext & operator<<(T const &value)
Appends to the message.
Definition: Logger.h:193
The main namespace for the PcapPlusPlus lib.
LogLevel
Definition: Logger.h:146
@ Info
Info level logs and above are emitted.
@ Error
Error level logs are emitted.
@ Debug
Debug level logs and above are emitted.
@ Off
No log messages are emitted.
std::string getErrorString(int errnum)
LogModule
An enum representing all PcapPlusPlus modules.
Definition: Logger.h:50
@ PacketLogModuleRawPacket
RawPacket module (Packet++)
Definition: Logger.h:55
@ PacketLogModulePayloadLayer
PayloadLayer module (Packet++)
Definition: Logger.h:63
@ PcapLogModuleXdpDevice
XdpDevice module (Pcap++)
Definition: Logger.h:110
@ PacketLogModuleUdpLayer
UdpLayer module (Packet++)
Definition: Logger.h:65
@ PacketLogModuleTelnetLayer
TelnetLayer module (Packet++)
Definition: Logger.h:92
@ CommonLogModuleTablePrinter
Table printer module (Common++)
Definition: Logger.h:53
@ PacketLogModuleFtpLayer
FtpLayer module (Packet++)
Definition: Logger.h:96
@ PacketLogModuleGreLayer
GreLayer module (Packet++)
Definition: Logger.h:73
@ PacketLogModuleLLCLayer
LLCLayer module (Packet++)
Definition: Logger.h:94
@ PacketLogModuleVlanLayer
VlanLayer module (Packet++)
Definition: Logger.h:66
@ PcapLogModuleKniDevice
KniDevice module (Pcap++)
Definition: Logger.h:109
@ PacketLogModuleSomeIpLayer
SomeIpLayer module (Packet++)
Definition: Logger.h:97
@ PacketLogModuleEthLayer
EthLayer module (Packet++)
Definition: Logger.h:60
@ PacketLogModuleSll2Layer
Sll2Layer module (Packet++)
Definition: Logger.h:76
@ PacketLogModuleSdpLayer
SdpLayer module (Packet++)
Definition: Logger.h:82
@ PacketLogModuleIPv4Layer
IPv4Layer module (Packet++)
Definition: Logger.h:61
@ PacketLogModuleArpLayer
ArpLayer module (Packet++)
Definition: Logger.h:59
@ PacketLogModuleRadiusLayer
RadiusLayer module (Packet++)
Definition: Logger.h:83
@ PacketLogModuleDhcpV6Layer
DhcpV6Layer module (Packet++)
Definition: Logger.h:79
@ PacketLogModuleSipLayer
SipLayer module (Packet++)
Definition: Logger.h:81
@ PacketLogModuleNflogLayer
NflogLayer module (Packet++)
Definition: Logger.h:77
@ PcapLogModuleRemoteDevice
WinPcapRemoteDevice module (Pcap++)
Definition: Logger.h:103
@ PacketLogModuleNdpLayer
NdpLayer module (Packet++)
Definition: Logger.h:95
@ CommonLogModuleIpUtils
IP Utils module (Common++)
Definition: Logger.h:52
@ PacketLogModuleIcmpLayer
IcmpLayer module (Packet++)
Definition: Logger.h:71
@ PacketLogModuleNtpLayer
NtpLayer module (Packet++)
Definition: Logger.h:91
@ PacketLogModuleVrrpLayer
Vrrp Record module (Packet++)
Definition: Logger.h:87
@ PcapLogModuleFileDevice
FileDevice module (Pcap++)
Definition: Logger.h:105
@ PacketLogModuleGtpLayer
GtpLayer module (Packet++)
Definition: Logger.h:84
@ PacketLogModuleSSHLayer
SSHLayer module (Packet++)
Definition: Logger.h:86
@ PacketLogModuleDhcpLayer
DhcpLayer module (Packet++)
Definition: Logger.h:78
@ PcapLogModuleDpdkDevice
DpdkDevice module (Pcap++)
Definition: Logger.h:108
@ PacketLogModuleWakeOnLanLayer
WakeOnLanLayer module (Packet++)
Definition: Logger.h:99
@ PacketLogModulePPPoELayer
PPPoELayer module (Packet++)
Definition: Logger.h:68
@ PacketLogModuleIPReassembly
IPReassembly module (Packet++)
Definition: Logger.h:89
@ PacketLogModuleTcpReassembly
TcpReassembly module (Packet++)
Definition: Logger.h:88
@ PacketLogModuleHttpLayer
HttpLayer module (Packet++)
Definition: Logger.h:67
@ PacketLogModuleWireGuardLayer
WireGuardLayer module (Packet++)
Definition: Logger.h:101
@ PacketLogModuleBgpLayer
GtpLayer module (Packet++)
Definition: Logger.h:85
@ PacketLogModuleSllLayer
SllLayer module (Packet++)
Definition: Logger.h:75
@ CommonLogModuleGenericUtils
Generic Utils (Common++)
Definition: Logger.h:54
@ PacketLogModuleIgmpLayer
IgmpLayer module (Packet++)
Definition: Logger.h:80
@ PacketLogModuleStpLayer
StpLayer module (Packet++)
Definition: Logger.h:93
@ PcapLogModuleWinPcapLiveDevice
WinPcapLiveDevice module (Pcap++)
Definition: Logger.h:102
@ PacketLogModuleIPv6Layer
IPv6Layer module (Packet++)
Definition: Logger.h:62
@ PacketLogModuleMplsLayer
MplsLayer module (Packet++)
Definition: Logger.h:70
@ PacketLogModuleAsn1Codec
Asn1Codec module (Packet++)
Definition: Logger.h:58
@ PcapLogModuleNetworkUtils
Network Utils module (Pcap++)
Definition: Logger.h:111
@ PacketLogModuleDnsLayer
DnsLayer module (Packet++)
Definition: Logger.h:69
@ PcapLogModulePfRingDevice
PfRingDevice module (Pcap++)
Definition: Logger.h:106
@ PacketLogModuleSSLLayer
SSLLayer module (Packet++)
Definition: Logger.h:74
@ PacketLogModulePacket
Packet module (Packet++)
Definition: Logger.h:56
@ PacketLogModuleSomeIpSdLayer
SomeIpSdLayer module (Packet++)
Definition: Logger.h:98
@ PcapLogModuleMBufRawPacket
MBufRawPacket module (Pcap++)
Definition: Logger.h:107
@ PacketLogModuleLayer
Layer module (Packet++)
Definition: Logger.h:57
@ PacketLogModuleTcpLayer
TcpLayer module (Packet++)
Definition: Logger.h:64
@ PacketLogModuleIcmpV6Layer
IcmpV6Layer module (Packet++)
Definition: Logger.h:72
@ PcapLogModuleLiveDevice
PcapLiveDevice module (Pcap++)
Definition: Logger.h:104
@ PacketLogModuleSmtpLayer
SmtpLayer module (Packet++)
Definition: Logger.h:100
@ PacketLogModuleIPSecLayer
IPSecLayers module (Packet++)
Definition: Logger.h:90
Definition: Logger.h:119
const char * function
Definition: Logger.h:138
LogModule logModule
Definition: Logger.h:140
constexpr LogSource()=default
Default constructor for LogSource.
constexpr LogSource(LogModule logModule)
Definition: Logger.h:125
constexpr LogSource(LogModule logModule, const char *file, const char *function, int line)
Definition: Logger.h:133
const char * file
Definition: Logger.h:137
int line
Definition: Logger.h:139