A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
log-macros-enabled.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2006,2007 INRIA
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
18 */
19
20#ifndef NS3_LOG_MACROS_ENABLED_H
21#define NS3_LOG_MACROS_ENABLED_H
22
23/**
24 * \file
25 * \ingroup logging
26 * NS_LOG and related logging macro definitions.
27 */
28
29// These two implementation macros
30// NS_LOG_APPEND_TIME_PREFIX_IMPL
31// NS_LOG_APPEND_NODE_PREFIX_IMPL
32// need to be defined in all configurations (debug, release, optimized)
33// for use by NS_FATAL_...
34
35/**
36 * \ingroup logging
37 * Implementation details for NS_LOG_APPEND_TIME_PREFIX.
38 * \internal
39 * Logging implementation macro; should not be called directly.
40 * We define this separately so we can reuse the definition
41 * in NS_FATAL.
42 */
43#define NS_LOG_APPEND_TIME_PREFIX_IMPL \
44 do \
45 { \
46 ns3::TimePrinter printer = ns3::LogGetTimePrinter(); \
47 if (printer != 0) \
48 { \
49 (*printer)(std::clog); \
50 std::clog << " "; \
51 } \
52 } while (false)
53
54/**
55 * \ingroup logging
56 * Implementation details for NS_LOG_APPEND_NODE_PREFIX.
57 * \internal
58 * Logging implementation macro; should not be called directly.
59 * We define this separately so we can reuse the definition
60 * in NS_FATAL.
61 */
62#define NS_LOG_APPEND_NODE_PREFIX_IMPL \
63 do \
64 { \
65 ns3::NodePrinter printer = ns3::LogGetNodePrinter(); \
66 if (printer != 0) \
67 { \
68 (*printer)(std::clog); \
69 std::clog << " "; \
70 } \
71 } while (false)
72
73#ifdef NS3_LOG_ENABLE
74
75/**
76 * \ingroup logging
77 * Append the simulation time to a log message.
78 * \internal
79 * Logging implementation macro; should not be called directly.
80 */
81#define NS_LOG_APPEND_TIME_PREFIX \
82 if (g_log.IsEnabled(ns3::LOG_PREFIX_TIME)) \
83 { \
84 NS_LOG_APPEND_TIME_PREFIX_IMPL; \
85 }
86
87/**
88 * \ingroup logging
89 * Append the simulation node id to a log message.
90 * \internal
91 * Logging implementation macro; should not be called directly.
92 */
93#define NS_LOG_APPEND_NODE_PREFIX \
94 if (g_log.IsEnabled(ns3::LOG_PREFIX_NODE)) \
95 { \
96 NS_LOG_APPEND_NODE_PREFIX_IMPL; \
97 }
98
99/**
100 * \ingroup logging
101 * Append the function name to a log message.
102 * \internal
103 * Logging implementation macro; should not be called directly.
104 */
105#define NS_LOG_APPEND_FUNC_PREFIX \
106 if (g_log.IsEnabled(ns3::LOG_PREFIX_FUNC)) \
107 { \
108 std::clog << g_log.Name() << ":" << __FUNCTION__ << "(): "; \
109 }
110
111/**
112 * \ingroup logging
113 * Append the log severity level to a log message.
114 * \internal
115 * Logging implementation macro; should not be called directly.
116 */
117#define NS_LOG_APPEND_LEVEL_PREFIX(level) \
118 if (g_log.IsEnabled(ns3::LOG_PREFIX_LEVEL)) \
119 { \
120 std::clog << "[" << g_log.GetLevelLabel(level) << "] "; \
121 }
122
123#ifndef NS_LOG_APPEND_CONTEXT
124/**
125 * \ingroup logging
126 * Append the node id (or other file-local programmatic context, such as
127 * MPI rank) to a log message.
128 *
129 * This is implemented locally in `.cc` files because
130 * the relevant variable is only known there.
131 *
132 * Preferred format is something like (assuming the node id is
133 * accessible from `var`:
134 * \code
135 * if (var)
136 * {
137 * std::clog << "[node " << var->GetObject<Node> ()->GetId () << "] ";
138 * }
139 * \endcode
140 */
141#define NS_LOG_APPEND_CONTEXT
142#endif /* NS_LOG_APPEND_CONTEXT */
143
144#ifndef NS_LOG_CONDITION
145/**
146 * \ingroup logging
147 * Limit logging output based on some file-local condition,
148 * such as MPI rank.
149 *
150 * This is implemented locally in `.cc` files because
151 * the relevant condition variable is only known there.
152 *
153 * Since this appears immediately before the `do { ... } while false`
154 * construct of \c NS_LOG(level, msg), it must have the form
155 * \code
156 * #define NS_LOG_CONDITION if (condition)
157 * \endcode
158 */
159#define NS_LOG_CONDITION
160#endif
161
162/**
163 * \ingroup logging
164 *
165 * This macro allows you to log an arbitrary message at a specific
166 * log level.
167 *
168 * The log message is expected to be a C++ ostream
169 * message such as "my string" << aNumber << "my oth stream".
170 *
171 * Typical usage looks like:
172 * \code
173 * NS_LOG (LOG_DEBUG, "a number="<<aNumber<<", anotherNumber="<<anotherNumber);
174 * \endcode
175 *
176 * \param [in] level The log level
177 * \param [in] msg The message to log
178 * \internal
179 * Logging implementation macro; should not be called directly.
180 */
181#define NS_LOG(level, msg) \
182 NS_LOG_CONDITION \
183 do \
184 { \
185 if (g_log.IsEnabled(level)) \
186 { \
187 NS_LOG_APPEND_TIME_PREFIX; \
188 NS_LOG_APPEND_NODE_PREFIX; \
189 NS_LOG_APPEND_CONTEXT; \
190 NS_LOG_APPEND_FUNC_PREFIX; \
191 NS_LOG_APPEND_LEVEL_PREFIX(level); \
192 auto flags = std::clog.setf(std::ios_base::boolalpha); \
193 std::clog << msg << std::endl; \
194 std::clog.flags(flags); \
195 } \
196 } while (false)
197
198/**
199 * \ingroup logging
200 *
201 * Output the name of the function.
202 *
203 * This should be used only in static functions; most member functions
204 * should instead use NS_LOG_FUNCTION().
205 */
206#define NS_LOG_FUNCTION_NOARGS() \
207 NS_LOG_CONDITION \
208 do \
209 { \
210 if (g_log.IsEnabled(ns3::LOG_FUNCTION)) \
211 { \
212 NS_LOG_APPEND_TIME_PREFIX; \
213 NS_LOG_APPEND_NODE_PREFIX; \
214 NS_LOG_APPEND_CONTEXT; \
215 std::clog << g_log.Name() << ":" << __FUNCTION__ << "()" << std::endl; \
216 } \
217 } while (false)
218
219/**
220 * \ingroup logging
221 *
222 * If log level LOG_FUNCTION is enabled, this macro will output
223 * all input parameters separated by ", ".
224 *
225 * Typical usage looks like:
226 * \code
227 * NS_LOG_FUNCTION (aNumber<<anotherNumber);
228 * \endcode
229 * And the output will look like:
230 * \code
231 * Component:Function (aNumber, anotherNumber)
232 * \endcode
233 *
234 * To facilitate function tracing, most functions should begin with
235 * (at least) NS_LOG_FUNCTION(this). Static functions should use
236 * NS_LOG_FUNCTION_NOARGS() instead.
237 *
238 * \param [in] parameters The parameters to output.
239 */
240#define NS_LOG_FUNCTION(parameters) \
241 NS_LOG_CONDITION \
242 do \
243 { \
244 if (g_log.IsEnabled(ns3::LOG_FUNCTION)) \
245 { \
246 NS_LOG_APPEND_TIME_PREFIX; \
247 NS_LOG_APPEND_NODE_PREFIX; \
248 NS_LOG_APPEND_CONTEXT; \
249 std::clog << g_log.Name() << ":" << __FUNCTION__ << "("; \
250 auto flags = std::clog.setf(std::ios_base::boolalpha); \
251 ns3::ParameterLogger(std::clog) << parameters; \
252 std::clog.flags(flags); \
253 std::clog << ")" << std::endl; \
254 } \
255 } while (false)
256
257/**
258 * \ingroup logging
259 *
260 * Output the requested message unconditionally.
261 *
262 * \param [in] msg The message to log
263 */
264#define NS_LOG_UNCOND(msg) \
265 NS_LOG_CONDITION \
266 do \
267 { \
268 auto flags = std::clog.setf(std::ios_base::boolalpha); \
269 std::clog << msg << std::endl; \
270 std::clog.flags(flags); \
271 } while (false)
272
273#endif /* NS3_LOG_ENABLE */
274
275#endif /* NS3_LOG_MACROS_ENABLED_H */