#ifndef PCAPPP_LOGGER #define PCAPPP_LOGGER #include #include #include #include #include #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++) PacketLogModuleIcmpV6Layer, ///< IcmpV6Layer module (Packet++) PacketLogModuleGreLayer, ///< GreLayer module (Packet++) PacketLogModuleSSLLayer, ///< SSLLayer module (Packet++) PacketLogModuleSllLayer, ///< SllLayer module (Packet++) PacketLogModuleNflogLayer, ///< NflogLayer 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++) PacketLogModuleVrrpLayer, ///< Vrrp Record module (Packet++) PacketLogModuleTcpReassembly, ///< TcpReassembly module (Packet++) PacketLogModuleIPReassembly, ///< IPReassembly module (Packet++) PacketLogModuleIPSecLayer, ///< IPSecLayers module (Packet++) PacketLogModuleNtpLayer, ///< NtpLayer module (Packet++) PacketLogModuleTelnetLayer, ///< TelnetLayer module (Packet++) PacketLogModuleStpLayer, ///< StpLayer module (Packet++) PacketLogModuleLLCLayer, ///< LLCLayer module (Packet++) PacketLogModuleSingleCommandTextProtocolLayer, ///< SingleCommandTextProtocol module (Packet++) PacketLogModuleNdpLayer, ///< NdpLayer module (Packet++) PacketLogModuleFtpLayer, ///< FtpLayer module (Packet++) PacketLogModuleSomeIpLayer, ///< SomeIpLayer module (Packet++) PacketLogModuleSomeIpSdLayer, ///< SomeIpSdLayer module (Packet++) PacketLogModuleWakeOnLanLayer, ///< WakeOnLanLayer 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 setAllModulesToLogLevel(LogLevel level) { for (int i=1; i 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 */