241 lines
8.7 KiB
C++
241 lines
8.7 KiB
C++
#ifndef PCAPPP_LOGGER
|
|
#define PCAPPP_LOGGER
|
|
|
|
#include <stdio.h>
|
|
#include <iostream>
|
|
#include <sstream>
|
|
#include <iomanip>
|
|
#include <stdint.h>
|
|
|
|
#ifndef LOG_MODULE
|
|
#define LOG_MODULE UndefinedLogModule
|
|
#endif
|
|
|
|
/// @file
|
|
|
|
/**
|
|
* \namespace pcpp
|
|
* \brief The main namespace for the PcapPlusPlus lib
|
|
*/
|
|
namespace pcpp
|
|
{
|
|
|
|
/**
|
|
* An enum representing all PcapPlusPlus modules
|
|
*/
|
|
enum LogModule
|
|
{
|
|
UndefinedLogModule,
|
|
CommonLogModuleIpUtils, ///< IP Utils module (Common++)
|
|
CommonLogModuleTablePrinter, ///< Table printer module (Common++)
|
|
CommonLogModuleGenericUtils, ///< Generic Utils (Common++)
|
|
PacketLogModuleRawPacket, ///< RawPacket module (Packet++)
|
|
PacketLogModulePacket, ///< Packet module (Packet++)
|
|
PacketLogModuleLayer, ///< Layer module (Packet++)
|
|
PacketLogModuleArpLayer, ///< ArpLayer module (Packet++)
|
|
PacketLogModuleEthLayer, ///< EthLayer module (Packet++)
|
|
PacketLogModuleIPv4Layer, ///< IPv4Layer module (Packet++)
|
|
PacketLogModuleIPv6Layer, ///< IPv6Layer module (Packet++)
|
|
PacketLogModulePayloadLayer, ///< PayloadLayer module (Packet++)
|
|
PacketLogModuleTcpLayer, ///< TcpLayer module (Packet++)
|
|
PacketLogModuleUdpLayer, ///< UdpLayer module (Packet++)
|
|
PacketLogModuleVlanLayer, ///< VlanLayer module (Packet++)
|
|
PacketLogModuleHttpLayer, ///< HttpLayer module (Packet++)
|
|
PacketLogModulePPPoELayer, ///< PPPoELayer module (Packet++)
|
|
PacketLogModuleDnsLayer, ///< DnsLayer module (Packet++)
|
|
PacketLogModuleMplsLayer, ///< MplsLayer module (Packet++)
|
|
PacketLogModuleIcmpLayer, ///< IcmpLayer module (Packet++)
|
|
PacketLogModuleGreLayer, ///< GreLayer module (Packet++)
|
|
PacketLogModuleSSLLayer, ///< SSLLayer module (Packet++)
|
|
PacketLogModuleSllLayer, ///< SllLayer module (Packet++)
|
|
PacketLogModuleDhcpLayer, ///< DhcpLayer module (Packet++)
|
|
PacketLogModuleDhcpV6Layer, ///< DhcpV6Layer module (Packet++)
|
|
PacketLogModuleIgmpLayer, ///< IgmpLayer module (Packet++)
|
|
PacketLogModuleSipLayer, ///< SipLayer module (Packet++)
|
|
PacketLogModuleSdpLayer, ///< SdpLayer module (Packet++)
|
|
PacketLogModuleRadiusLayer, ///< RadiusLayer module (Packet++)
|
|
PacketLogModuleGtpLayer, ///< GtpLayer module (Packet++)
|
|
PacketLogModuleBgpLayer, ///< GtpLayer module (Packet++)
|
|
PacketLogModuleSSHLayer, ///< SSHLayer module (Packet++)
|
|
PacketLogModuleTcpReassembly, ///< TcpReassembly module (Packet++)
|
|
PacketLogModuleIPReassembly, ///< IPReassembly module (Packet++)
|
|
PacketLogModuleIPSecLayer, ///< IPSecLayers module (Packet++)
|
|
PacketLogModuleNtpLayer, ///< NtpLayer module (Packet++)
|
|
PcapLogModuleWinPcapLiveDevice, ///< WinPcapLiveDevice module (Pcap++)
|
|
PcapLogModuleRemoteDevice, ///< WinPcapRemoteDevice module (Pcap++)
|
|
PcapLogModuleLiveDevice, ///< PcapLiveDevice module (Pcap++)
|
|
PcapLogModuleFileDevice, ///< FileDevice module (Pcap++)
|
|
PcapLogModulePfRingDevice, ///< PfRingDevice module (Pcap++)
|
|
PcapLogModuleMBufRawPacket, ///< MBufRawPacket module (Pcap++)
|
|
PcapLogModuleDpdkDevice, ///< DpdkDevice module (Pcap++)
|
|
PcapLogModuleKniDevice, ///< KniDevice module (Pcap++)
|
|
NetworkUtils, ///< NetworkUtils module (Pcap++)
|
|
NumOfLogModules
|
|
};
|
|
|
|
/**
|
|
* @class Logger
|
|
* PcapPlusPlus logger manager.
|
|
* PcapPlusPlus uses this logger to output both error and debug logs.
|
|
* There are currently 3 log levels: Logger#Error, Logger#Info and Logger#Debug.
|
|
*
|
|
* 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.
|
|
* The default is Logger#Info which outputs only error messages. Changing log level for modules can be done dynamically while the application is running.
|
|
*
|
|
* The logger also exposes a method to retrieve the last error log message.
|
|
*
|
|
* 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
|
|
* other media (such as files, etc.).
|
|
*
|
|
* PcapPlusPlus logger is a singleton which can be reached from anywhere in the code.
|
|
*
|
|
* Note: Logger#Info level logs are currently only used in DPDK devices to set DPDK log level to RTE_LOG_NOTICE.
|
|
*/
|
|
class Logger
|
|
{
|
|
public:
|
|
/**
|
|
* An enum representing the log level. Currently 3 log levels are supported: Error, Info and Debug. Info is the default log level
|
|
*/
|
|
enum LogLevel
|
|
{
|
|
Error, ///< Error log level
|
|
Info, ///< Info log level
|
|
Debug ///< Debug log level
|
|
};
|
|
|
|
/**
|
|
* @typedef LogPrinter
|
|
* Log printer callback. Used for printing the logs in a custom way.
|
|
* @param[in] logLevel The log level for this log message
|
|
* @param[in] logMessage The log message
|
|
* @param[in] file The source file in PcapPlusPlus code the log message is coming from
|
|
* @param[in] method The method in PcapPlusPlus code the log message is coming from
|
|
* @param[in] line The line in PcapPlusPlus code the log message is coming from
|
|
*/
|
|
typedef void (*LogPrinter)(LogLevel logLevel, const std::string& logMessage, const std::string& file, const std::string& method, const int line);
|
|
|
|
/**
|
|
* A static method for converting the log level enum to a string.
|
|
* @param[in] logLevel A log level enum
|
|
* @return The log level as a string
|
|
*/
|
|
static std::string logLevelAsString(LogLevel logLevel);
|
|
|
|
/**
|
|
* Get the log level for a certain module
|
|
* @param[in] module PcapPlusPlus module
|
|
* @return The log level set for this module
|
|
*/
|
|
LogLevel getLogLevel(LogModule module) { return m_LogModulesArray[module]; }
|
|
|
|
/**
|
|
* Set the log level for a certain PcapPlusPlus module
|
|
* @param[in] module PcapPlusPlus module
|
|
* @param[in] level The log level to set the module to
|
|
*/
|
|
void setLogLevel(LogModule module, LogLevel level) { m_LogModulesArray[module] = level; }
|
|
|
|
/**
|
|
* Check whether a certain module is set to debug log level
|
|
* @param[in] module PcapPlusPlus module
|
|
* @return True if this module log level is "debug". False otherwise
|
|
*/
|
|
bool isDebugEnabled(LogModule module) const { return m_LogModulesArray[module] == Debug; }
|
|
|
|
/**
|
|
* Set all PcapPlusPlus modules to a certain log level
|
|
* @param[in] level The log level to set all modules to
|
|
*/
|
|
void setAllModlesToLogLevel(LogLevel level) { for (int i=1; i<NumOfLogModules; i++) m_LogModulesArray[i] = level; }
|
|
|
|
/**
|
|
* Set a custom log printer.
|
|
* @param[in] printer A log printer function that will be called for every log message
|
|
*/
|
|
void setLogPrinter(LogPrinter printer) { m_LogPrinter = printer; }
|
|
|
|
/**
|
|
* Set the log printer back to the default printer
|
|
*/
|
|
void resetLogPrinter() { m_LogPrinter = &defaultLogPrinter; }
|
|
|
|
/**
|
|
* @return Get the last error message
|
|
*/
|
|
std::string getLastError() { return m_LastError; }
|
|
|
|
/**
|
|
* Suppress logs in all PcapPlusPlus modules
|
|
*/
|
|
void suppressLogs() { m_LogsEnabled = false; }
|
|
|
|
/**
|
|
* Enable logs in all PcapPlusPlus modules
|
|
*/
|
|
void enableLogs() { m_LogsEnabled = true; }
|
|
|
|
/**
|
|
* Get an indication if logs are currently enabled.
|
|
* @return True if logs are currently enabled, false otherwise
|
|
*/
|
|
bool logsEnabled() const { return m_LogsEnabled; }
|
|
|
|
template<class T>
|
|
Logger& operator<<(const T& msg)
|
|
{
|
|
(*m_LogStream) << msg;
|
|
return *this;
|
|
}
|
|
|
|
std::ostringstream * internalCreateLogStream();
|
|
|
|
/**
|
|
* An internal method to print log messages. Shouldn't be used externally.
|
|
*/
|
|
void internalPrintLogMessage(std::ostringstream* logStream, Logger::LogLevel logLevel, const char* file, const char* method, int line);
|
|
|
|
/**
|
|
* Get access to Logger singleton
|
|
* @todo: make this singleton thread-safe/
|
|
* @return a pointer to the Logger singleton
|
|
**/
|
|
static Logger& getInstance()
|
|
{
|
|
static Logger instance;
|
|
return instance;
|
|
}
|
|
private:
|
|
bool m_LogsEnabled;
|
|
Logger::LogLevel m_LogModulesArray[NumOfLogModules];
|
|
LogPrinter m_LogPrinter;
|
|
std::string m_LastError;
|
|
std::ostringstream* m_LogStream;
|
|
|
|
// private c'tor - this class is a singleton
|
|
Logger();
|
|
|
|
static void defaultLogPrinter(LogLevel logLevel, const std::string& logMessage, const std::string& file, const std::string& method, const int line);
|
|
};
|
|
|
|
#define PCPP_LOG_DEBUG(message) do \
|
|
{ \
|
|
if (pcpp::Logger::getInstance().logsEnabled() && pcpp::Logger::getInstance().isDebugEnabled(LOG_MODULE)) \
|
|
{ \
|
|
std::ostringstream* sstream = pcpp::Logger::getInstance().internalCreateLogStream(); \
|
|
(*sstream) << message; \
|
|
pcpp::Logger::getInstance().internalPrintLogMessage(sstream, pcpp::Logger::Debug, __FILE__, __FUNCTION__, __LINE__); \
|
|
} \
|
|
} while(0)
|
|
|
|
#define PCPP_LOG_ERROR(message) do \
|
|
{ \
|
|
std::ostringstream* sstream = pcpp::Logger::getInstance().internalCreateLogStream(); \
|
|
(*sstream) << message; \
|
|
pcpp::Logger::getInstance().internalPrintLogMessage(sstream, pcpp::Logger::Error, __FILE__, __FUNCTION__, __LINE__); \
|
|
} while (0)
|
|
|
|
} // namespace pcpp
|
|
|
|
#endif /* PCAPPP_LOGGER */
|