Files
unison/src/core/model/log.h
Andrey Mazo 210aefc777 Bug 1170: Formulate best practices for dealing with unused debug variables.
Fixed clang-3.4 unused function warnings in optimized builds like the following:
"""
../examples/energy/energy-model-example.cc:39:1: error: unused function
'PrintReceivedPacket' [-Werror,-Wunused-function]
PrintReceivedPacket (Address& from)
^
1 error generated.
"""

Implemented "if (false)" trick inside NS_LOG* macros for optimized builds.

"sizeof()" trick might be a little better but it produces the following
warning with clang-3.4:
"""
../examples/energy/energy-model-example.cc:39:1: error: function
'PrintReceivedPacket' is not needed and will not be emitted
[-Werror,-Wunneeded-internal-declaration]
PrintReceivedPacket (Address& from)
^
1 error generated.
"""


Macros from log.h, that depend on NS3_LOG_ENABLE, were moved to log-macros-enabled.h and log-macros-disabled.h to make log.h smaller.
2014-03-23 19:08:54 +04:00

375 lines
9.8 KiB
C++

/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* Copyright (c) 2006,2007 INRIA
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
*/
#ifndef NS3_LOG_H
#define NS3_LOG_H
#include <string>
#include <iostream>
#include <stdint.h>
#include <map>
#include "log-macros-enabled.h"
#include "log-macros-disabled.h"
namespace ns3 {
/**
* \ingroup debugging
* \defgroup logging Logging
*
* \brief Logging functions and macros
*
* LOG functionality: macros which allow developers to
* send information to the std::clog output stream. All logging messages
* are disabled by default. To enable selected logging
* messages, use the ns3::LogComponentEnable
* function or use the NS_LOG environment variable
*
* Use the environment variable NS_LOG to define a ':'-separated list of
* logging components to enable. For example (using bash syntax),
* NS_LOG="OlsrAgent" would enable one component at all log levels.
* NS_LOG="OlsrAgent:Ipv4L3Protocol" would enable two components,
* at all log levels, etc.
* NS_LOG="*" will enable all available log components at all levels.
*
* To control more selectively the log levels for each component, use
* this syntax: NS_LOG='Component1=func|warn:Component2=error|debug'
* This example would enable the 'func', and 'warn' log
* levels for 'Component1' and the 'error' and 'debug' log levels
* for 'Component2'. The wildcard can be used here as well. For example
* NS_LOG='*=level_all|prefix' would enable all log levels and prefix all
* prints with the component and function names.
*
* A note on NS_LOG_FUNCTION() and NS_LOG_FUNCTION_NOARGS():
* generally, use of (at least) NS_LOG_FUNCTION(this) is preferred.
* Use NS_LOG_FUNCTION_NOARGS() only in static functions.
*/
/**
* \ingroup logging
*
* Logging severity classes and levels.
*/
enum LogLevel {
LOG_NONE = 0x00000000, //!< no logging
LOG_ERROR = 0x00000001, //!< serious error messages only
LOG_LEVEL_ERROR = 0x00000001,
LOG_WARN = 0x00000002, //!< warning messages
LOG_LEVEL_WARN = 0x00000003,
LOG_DEBUG = 0x00000004, //!< rare ad-hoc debug messages
LOG_LEVEL_DEBUG = 0x00000007,
LOG_INFO = 0x00000008, //!< informational messages (e.g., banners)
LOG_LEVEL_INFO = 0x0000000f,
LOG_FUNCTION = 0x00000010, //!< function tracing
LOG_LEVEL_FUNCTION = 0x0000001f,
LOG_LOGIC = 0x00000020, //!< control flow tracing within functions
LOG_LEVEL_LOGIC = 0x0000003f,
LOG_ALL = 0x0fffffff, //!< print everything
LOG_LEVEL_ALL = LOG_ALL,
LOG_PREFIX_FUNC = 0x80000000, //!< prefix all trace prints with function
LOG_PREFIX_TIME = 0x40000000, //!< prefix all trace prints with simulation time
LOG_PREFIX_NODE = 0x20000000, //!< prefix all trace prints with simulation node
LOG_PREFIX_LEVEL = 0x10000000, //!< prefix all trace prints with log level (severity)
LOG_PREFIX_ALL = 0xf0000000 //!< all prefixes
};
/**
* \ingroup logging
*
* Enable the logging output associated with that log component.
*
* The logging output can be later disabled with a call
* to ns3::LogComponentDisable.
*
* Same as running your program with the NS_LOG environment
* variable set as NS_LOG='name=level'
*
* \param name a log component name
* \param level a logging level
*/
void LogComponentEnable (char const *name, enum LogLevel level);
/**
* \ingroup logging
*
* Enable the logging output for all registered log components.
*
* Same as running your program with the NS_LOG environment
* variable set as NS_LOG='*=level'
*
* \param level a logging level
*/
void LogComponentEnableAll (enum LogLevel level);
/**
* \ingroup logging
*
* Disable the logging output associated with that log component.
*
* The logging output can be later re-enabled with a call
* to ns3::LogComponentEnable.
*
* \param name a log component name
* \param level a logging level
*/
void LogComponentDisable (char const *name, enum LogLevel level);
/**
* \ingroup logging
*
* Disable all logging for all components.
*
* \param level a logging level
*/
void LogComponentDisableAll (enum LogLevel level);
} // namespace ns3
/**
* \ingroup logging
*
* Define a Log component with a specific name.
*
* This macro should be used at the top of every file in which you want
* to use the NS_LOG macro. This macro defines a new
* "log component" which can be later selectively enabled
* or disabled with the ns3::LogComponentEnable and
* ns3::LogComponentDisable functions or with the NS_LOG
* environment variable.
*
* \param name a string
*/
#define NS_LOG_COMPONENT_DEFINE(name) \
static ns3::LogComponent g_log = ns3::LogComponent (name)
/**
* \ingroup logging
*
* Define a logging component with a mask.
*
* See LogComponent().
*
* \param name a string
* \param mask the default mask
*/
#define NS_LOG_COMPONENT_DEFINE_MASK(name, mask) \
static ns3::LogComponent g_log = ns3::LogComponent (name, mask)
/**
* \ingroup logging
*
* Use \ref NS_LOG to output a message of level LOG_ERROR.
*
* \param msg the message to log
*/
#define NS_LOG_ERROR(msg) \
NS_LOG (ns3::LOG_ERROR, msg)
/**
* \ingroup logging
*
* Use \ref NS_LOG to output a message of level LOG_WARN.
*
* \param msg the message to log
*/
#define NS_LOG_WARN(msg) \
NS_LOG (ns3::LOG_WARN, msg)
/**
* \ingroup logging
*
* Use \ref NS_LOG to output a message of level LOG_DEBUG.
*
* \param msg the message to log
*/
#define NS_LOG_DEBUG(msg) \
NS_LOG (ns3::LOG_DEBUG, msg)
/**
* \ingroup logging
*
* Use \ref NS_LOG to output a message of level LOG_INFO.
*
* \param msg the message to log
*/
#define NS_LOG_INFO(msg) \
NS_LOG (ns3::LOG_INFO, msg)
/**
* \ingroup logging
*
* Use \ref NS_LOG to output a message of level LOG_LOGIC
*
* \param msg the message to log
*/
#define NS_LOG_LOGIC(msg) \
NS_LOG (ns3::LOG_LOGIC, msg)
namespace ns3 {
/**
* \ingroup logging
*
* Print the list of logging messages available.
* Same as running your program with the NS_LOG environment
* variable set as NS_LOG=print-list
*/
void LogComponentPrintList (void);
typedef void (*LogTimePrinter)(std::ostream &os);
typedef void (*LogNodePrinter)(std::ostream &os);
void LogSetTimePrinter (LogTimePrinter);
LogTimePrinter LogGetTimePrinter (void);
void LogSetNodePrinter (LogNodePrinter);
LogNodePrinter LogGetNodePrinter (void);
/**
* \ingroup logging
*
* A single log component configuration.
*/
class LogComponent
{
public:
/**
* Constructor
*
* \param [in] name the user-visible name for this component.
* \param [in] mask LogLevels blocked for this LogComponent. Blocking
* a log level helps prevent recursion by logging in
* functions which help implement the logging facility.
*/
LogComponent (const std::string & name, const enum LogLevel mask = LOG_NONE);
/**
* Check if this LogComponent is enabled for \pname{level}
*
* \param [in] level the level to check for.
* \return true if \pname{level} is enabled.
*/
bool IsEnabled (const enum LogLevel level) const;
/**
* Check if all levels are disabled.
*
* \return true if all levels are disabled.
*/
bool IsNoneEnabled (void) const;
/**
* Enable this LogComponent at \pname{level}
*
* \param [in] level the LogLevel to enable.
*/
void Enable (const enum LogLevel level);
/**
* Disable logging at \pname{level} for this LogComponent.
*
* \param [in] level the LogLevel to disable.
*/
void Disable (const enum LogLevel level);
/**
* Get the name of this LogComponent.
*
* \return the name of this LogComponent.
*/
char const *Name (void) const;
/**
* Get the string label for the given LogLevel.
*
* \param [in] level the LogLevel to get the label for.
* \return the string label for \pname{level}
*/
static std::string GetLevelLabel(const enum LogLevel level);
/**
* Prevent the enabling of a specific LogLevel.
*
* \param level the LogLevel to block
*/
void SetMask (const enum LogLevel level);
private:
/**
* Parse the `NS_LOG` environment variable for options relating to this
* LogComponent.
*/
void EnvVarCheck (void);
int32_t m_levels; //!< Enabled LogLevels
int32_t m_mask; //!< Blocked LogLevels
std::string m_name; //!< LogComponent name
}; // class LogComponent
/**
* \ingroup logging
*
* Insert `, ` when streaming function arguments.
*/
class ParameterLogger
{
bool m_first; //!< First argument flag, doesn't get `, `.
std::ostream &m_os; //!< Underlying output stream.
public:
/**
* Constructor.
*
* \param [in] os Underlying output stream.
*/
ParameterLogger (std::ostream &os);
/**
* Write a function parameter on the output stream,
* separating paramters after the first by `,` strings.
*
* \param [in] param the function parameter
*/
template<typename T>
ParameterLogger& operator<< (T param)
{
if (m_first)
{
m_os << param;
m_first = false;
}
else
{
m_os << ", " << param;
}
return *this;
}
};
} // namespace ns3
#endif /* NS3_LOG_H */