Coverage Report

Created: 2023-01-17 06:15

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