Coverage Report

Created: 2024-02-25 06:29

/src/PcapPlusPlus/Common++/header/Logger.h
Line
Count
Source (jump to first uncovered line)
1
#pragma once
2
3
#include <stdio.h>
4
#include <iostream>
5
#include <sstream>
6
#include <iomanip>
7
#include <stdint.h>
8
9
#ifndef LOG_MODULE
10
0
#define LOG_MODULE UndefinedLogModule
11
#endif
12
13
// Use __FILE_NAME__ to avoid leaking complete full path
14
#ifdef __FILE_NAME__
15
145k
#define PCAPPP_FILENAME __FILE_NAME__
16
#else
17
#define PCAPPP_FILENAME __FILE__
18
#endif
19
20
145k
#define PCPP_LOG(level, message) do \
21
145k
  { \
22
145k
    std::ostringstream* sstream = pcpp::Logger::getInstance().internalCreateLogStream(); \
23
145k
    (*sstream) << message; \
24
145k
    pcpp::Logger::getInstance().internalPrintLogMessage(sstream, level, PCAPPP_FILENAME, __FUNCTION__, __LINE__); \
25
145k
  } while(0)
26
27
28.3M
#define PCPP_LOG_DEBUG(message) do \
28
28.3M
  { \
29
28.3M
    if (pcpp::Logger::getInstance().logsEnabled() && pcpp::Logger::getInstance().isDebugEnabled(LOG_MODULE)) \
30
28.3M
    { \
31
0
      PCPP_LOG(pcpp::Logger::Debug, message); \
32
0
    } \
33
28.3M
  } while(0)
34
35
145k
#define PCPP_LOG_ERROR(message) do \
36
145k
  { \
37
145k
    PCPP_LOG(pcpp::Logger::Error, message); \
38
145k
  } while (0)
39
40
/// @file
41
42
/**
43
 * \namespace pcpp
44
 * \brief The main namespace for the PcapPlusPlus lib
45
 */
46
namespace pcpp
47
{
48
49
  /**
50
   * An enum representing all PcapPlusPlus modules
51
   */
52
  enum LogModule
53
  {
54
    UndefinedLogModule,
55
    CommonLogModuleIpUtils, ///< IP Utils module (Common++)
56
    CommonLogModuleTablePrinter, ///< Table printer module (Common++)
57
    CommonLogModuleGenericUtils, ///< Generic Utils (Common++)
58
    PacketLogModuleRawPacket, ///< RawPacket module (Packet++)
59
    PacketLogModulePacket, ///< Packet module (Packet++)
60
    PacketLogModuleLayer, ///< Layer 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
    PacketLogModuleNflogLayer, ///< NflogLayer module (Packet++)
79
    PacketLogModuleDhcpLayer, ///< DhcpLayer module (Packet++)
80
    PacketLogModuleDhcpV6Layer, ///< DhcpV6Layer module (Packet++)
81
    PacketLogModuleIgmpLayer, ///< IgmpLayer module (Packet++)
82
    PacketLogModuleSipLayer, ///< SipLayer module (Packet++)
83
    PacketLogModuleSdpLayer, ///< SdpLayer module (Packet++)
84
    PacketLogModuleRadiusLayer, ///< RadiusLayer module (Packet++)
85
    PacketLogModuleGtpLayer, ///< GtpLayer module (Packet++)
86
    PacketLogModuleBgpLayer, ///< GtpLayer module (Packet++)
87
    PacketLogModuleSSHLayer, ///< SSHLayer module (Packet++)
88
    PacketLogModuleVrrpLayer, ///< Vrrp Record module (Packet++)
89
    PacketLogModuleTcpReassembly, ///< TcpReassembly module (Packet++)
90
    PacketLogModuleIPReassembly, ///< IPReassembly module (Packet++)
91
    PacketLogModuleIPSecLayer, ///< IPSecLayers module (Packet++)
92
    PacketLogModuleNtpLayer, ///< NtpLayer module (Packet++)
93
    PacketLogModuleTelnetLayer, ///< TelnetLayer module (Packet++)
94
    PacketLogModuleStpLayer, ///< StpLayer module (Packet++)
95
    PacketLogModuleLLCLayer, ///< LLCLayer module (Packet++)
96
    PacketLogModuleSingleCommandTextProtocolLayer, ///< SingleCommandTextProtocol 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
    PcapLogModuleWinPcapLiveDevice, ///< WinPcapLiveDevice module (Pcap++)
104
    PcapLogModuleRemoteDevice, ///< WinPcapRemoteDevice module (Pcap++)
105
    PcapLogModuleLiveDevice, ///< PcapLiveDevice module (Pcap++)
106
    PcapLogModuleFileDevice, ///< FileDevice module (Pcap++)
107
    PcapLogModulePfRingDevice, ///< PfRingDevice module (Pcap++)
108
    PcapLogModuleMBufRawPacket, ///< MBufRawPacket module (Pcap++)
109
    PcapLogModuleDpdkDevice, ///< DpdkDevice module (Pcap++)
110
    PcapLogModuleKniDevice, ///< KniDevice module (Pcap++)
111
    PcapLogModuleXdpDevice, ///< XdpDevice module (Pcap++)
112
    NetworkUtils, ///< NetworkUtils module (Pcap++)
113
    NumOfLogModules
114
  };
115
116
  /**
117
   * @class Logger
118
   * PcapPlusPlus logger manager.
119
   * PcapPlusPlus uses this logger to output both error and debug logs.
120
   * There are currently 3 log levels: Logger#Error, Logger#Info and Logger#Debug.
121
   *
122
   * PcapPlusPlus is divided into modules (described in #LogModule enum). The user can set the log level got each module or to all modules at once.
123
   * The default is Logger#Info which outputs only error messages. Changing log level for modules can be done dynamically while the application is running.
124
   *
125
   * The logger also exposes a method to retrieve the last error log message.
126
   *
127
   * Logs are printed to console by default in a certain format. The user can set a different print function to change the format or to print to
128
   * other media (such as files, etc.).
129
   *
130
   * PcapPlusPlus logger is a singleton which can be reached from anywhere in the code.
131
   *
132
   * Note: Logger#Info level logs are currently only used in DPDK devices to set DPDK log level to RTE_LOG_NOTICE.
133
   */
134
  class Logger
135
  {
136
  public:
137
    /**
138
     * An enum representing the log level. Currently 3 log levels are supported: Error, Info and Debug. Info is the default log level
139
     */
140
    enum LogLevel
141
    {
142
      Error, ///< Error log level
143
      Info, ///< Info log level
144
      Debug ///< Debug log level
145
    };
146
147
    /**
148
     * @typedef LogPrinter
149
     * Log printer callback. Used for printing the logs in a custom way.
150
     * @param[in] logLevel The log level for this log message
151
     * @param[in] logMessage The log message
152
     * @param[in] file The source file in PcapPlusPlus code the log message is coming from
153
     * @param[in] method The method in PcapPlusPlus code the log message is coming from
154
     * @param[in] line The line in PcapPlusPlus code the log message is coming from
155
     */
156
    typedef void (*LogPrinter)(LogLevel logLevel, const std::string& logMessage, const std::string& file, const std::string& method, const int line);
157
158
    /**
159
     * A static method for converting the log level enum to a string.
160
     * @param[in] logLevel A log level enum
161
     * @return The log level as a string
162
     */
163
    static std::string logLevelAsString(LogLevel logLevel);
164
165
    /**
166
     * Get the log level for a certain module
167
     * @param[in] module PcapPlusPlus module
168
     * @return The log level set for this module
169
     */
170
0
    LogLevel getLogLevel(LogModule module) { return m_LogModulesArray[module]; }
171
172
    /**
173
     * Set the log level for a certain PcapPlusPlus module
174
     * @param[in] module PcapPlusPlus module
175
     * @param[in] level The log level to set the module to
176
     */
177
0
    void setLogLevel(LogModule module, LogLevel level) { m_LogModulesArray[module] = level; }
178
179
    /**
180
     * Check whether a certain module is set to debug log level
181
     * @param[in] module PcapPlusPlus module
182
     * @return True if this module log level is "debug". False otherwise
183
     */
184
90.1k
    bool isDebugEnabled(LogModule module) const { return m_LogModulesArray[module] == Debug; }
185
186
    /**
187
     * Set all PcapPlusPlus modules to a certain log level
188
     * @param[in] level The log level to set all modules to
189
     */
190
0
    void setAllModulesToLogLevel(LogLevel level) { for (int i=1; i<NumOfLogModules; i++) m_LogModulesArray[i] = level; }
191
192
    /**
193
     * Set a custom log printer.
194
     * @param[in] printer A log printer function that will be called for every log message
195
     */
196
0
    void setLogPrinter(LogPrinter printer) { m_LogPrinter = printer; }
197
198
    /**
199
     * Set the log printer back to the default printer
200
     */
201
0
    void resetLogPrinter() { m_LogPrinter = &defaultLogPrinter; }
202
203
    /**
204
     * @return Get the last error message
205
     */
206
0
    std::string getLastError() { return m_LastError; }
207
208
    /**
209
     * Suppress logs in all PcapPlusPlus modules
210
     */
211
10.6k
    void suppressLogs() { m_LogsEnabled = false; }
212
213
    /**
214
     * Enable logs in all PcapPlusPlus modules
215
     */
216
0
    void enableLogs() { m_LogsEnabled = true; }
217
218
    /**
219
     * Get an indication if logs are currently enabled.
220
     * @return True if logs are currently enabled, false otherwise
221
     */
222
28.3M
    bool logsEnabled() const { return m_LogsEnabled; }
223
224
    template<class T>
225
    Logger& operator<<(const T& msg)
226
    {
227
      (*m_LogStream) << msg;
228
      return *this;
229
    }
230
231
    std::ostringstream * internalCreateLogStream();
232
233
    /**
234
     * An internal method to print log messages. Shouldn't be used externally.
235
     */
236
    void internalPrintLogMessage(std::ostringstream* logStream, Logger::LogLevel logLevel, const char* file, const char* method, int line);
237
238
    /**
239
     * Get access to Logger singleton
240
     * @todo: make this singleton thread-safe/
241
     * @return a pointer to the Logger singleton
242
    **/
243
    static Logger& getInstance()
244
28.7M
    {
245
28.7M
      static Logger instance;
246
28.7M
      return instance;
247
28.7M
    }
248
  private:
249
    bool m_LogsEnabled;
250
    Logger::LogLevel m_LogModulesArray[NumOfLogModules];
251
    LogPrinter m_LogPrinter;
252
    std::string m_LastError;
253
    std::ostringstream* m_LogStream;
254
255
    // private c'tor - this class is a singleton
256
    Logger();
257
258
    static void defaultLogPrinter(LogLevel logLevel, const std::string& logMessage, const std::string& file, const std::string& method, const int line);
259
  };
260
} // namespace pcpp