Peano
Loading...
Searching...
No Matches
CommandLineLogger.cpp
Go to the documentation of this file.
2
3#include "tarch/Assertions.h"
4
8
9#include "LogFilter.h"
10
11#include <sstream>
12#include <fstream>
13#include <stdlib.h>
14#include <chrono>
15
16#include "../mpi/Rank.h"
17
18
19
20tarch::logging::Log tarch::logging::CommandLineLogger::_log( "tarch::logging::CommandLineLogger" );
21
22
23std::string::size_type tarch::logging::CommandLineLogger::_indent = 0;
24
25
26const std::string::size_type tarch::logging::CommandLineLogger::NumberOfIndentSpaces = 2;
30
31
33
34
36 _outputStream(nullptr),
37 _hasWrittenToOuputStream(false),
38 _iterationCounter(0),
39 _quitOnError(false) {
48}
49
50
54
55
57 if (_outputStream==nullptr) {
58 return std::cout;
59 } else {
60 _hasWrittenToOuputStream = true;
61 return *_outputStream;
62 }
63}
64
65
67 out().setf( std::ios_base::scientific, std::ios_base::floatfield );
68 out().precision(20);
69 std::cerr.setf( std::ios_base::scientific, std::ios_base::floatfield );
70 std::cerr.precision(20);
71}
72
73
77
78
80
81
85
86
87std::string tarch::logging::CommandLineLogger::addSeparators(std::string::size_type spaces, std::string message) const {
88 if ( message.size() > 0 ) {
89 while (message.size() < spaces) {
90 message += " ";
91 }
92 message = getLogColumnSeparator() + message;
93 }
94
95 return message;
96}
97
98
100 _iterationCounter ++;
101
102 #if PeanoDebug>0
103 if ( _indentTraces.size()>0 ) {
104 while (not _indentTraces.empty()) {
105 logWarning( "closeOutputStreamAndReopenNewOne()", "tag still open: " << _indentTraces.top() );
106 _indentTraces.pop();
107 }
108 }
109 else if (_indent!=0) {
110 logWarning( "closeOutputStreamAndReopenNewOne()", "indent is " << _indent << ". Indentation messed up - likely due to missing logTraceOut. Re-translate without shared memory parallelisation and rerun" );
111 _indent = 0;
112 }
113 #endif
114
115
116 reopenOutputStream();
117}
118
119
120std::string tarch::logging::CommandLineLogger::getTimeStampHumanReadable( long int timestampNanoseconds ) {
121 long int timestampSeconds = timestampNanoseconds / 1000 / 1000 / 1000;
122 const int HourScaling = 60 * 60;
123 long int hours = timestampSeconds / HourScaling;
124 timestampSeconds = timestampSeconds - HourScaling * hours;
125
126 const int MinutesScaling = 60;
127 long int minutes = timestampSeconds / MinutesScaling;
128 timestampSeconds = timestampSeconds - MinutesScaling * minutes;
129
130 const int SecondsScaling = 1;
131 long int seconds = timestampSeconds / SecondsScaling;
132
133 std::stringstream result;
134 if (hours<10) {
135 result << "0";
136 }
137 result << hours << ":";
138 if (minutes<10) {
139 result << "0";
140 }
141 result << minutes << ":";
142 if (seconds<10) {
143 result << "0";
144 }
145 result << seconds;
146 return result.str();
147}
148
149
151 std::string messageType,
152 long int timestampNanoseconds, int rank, int threadId, const std::string& trace, const std::string& message
153) {
154 assertion( _indent!=0 or _indentTraces.empty() );
155
156 std::string prefix = "";
157 const unsigned int indent = _indent;
158 for (unsigned int i=0; i<indent; i++ ) prefix += " ";
159
160 std::string result;
161
162 if ( getLogTimeStamp() ) {
163 std::ostringstream timeStampString;
164 timeStampString << timestampNanoseconds;
165 result += addSeparators(NumberOfStandardColumnSpaces,timeStampString.str() );
166 }
167
168 if ( getLogTimeStampHumanReadable() ) {
169 result += addSeparators(NumberOfStandardColumnSpaces,getTimeStampHumanReadable(timestampNanoseconds));
170 }
171
172 if ( getLogMachineName() ) {
173 result += addSeparators(NumberOfStandardColumnSpaces,"rank:" + std::to_string(rank));
174 }
175
176 if ( getLogThreadName() ) {
177 result += addSeparators(NumberOfStandardColumnSpaces,"core:" + std::to_string(threadId));
178 }
179
180 if ( getLogMessageType() ) {
181 result += addSeparators(NumberOfStandardColumnSpaces,messageType);
182 }
183
184 if ( getLogTrace() ) {
185 result += addSeparators(NumberOfTraceColumnSpaces,trace);
186 }
187
188 result += addSeparators(NumberOfStandardColumnSpaces,prefix + message);
189
190 result += "\n";
191
192 return result;
193}
194
195
196void tarch::logging::CommandLineLogger::debug(long int timestampNanoseconds, int rank, int threadId, const std::string& trace, const std::string& message) {
197 #if !defined(PeanoDebug) || PeanoDebug<1
198 assertion(false);
199 #endif
200
201 std::string outputMessage = constructMessageString(
203 timestampNanoseconds, rank, threadId, trace, message
204 );
205
206 tarch::multicore::Lock lockCout( _semaphore );
207 out() << outputMessage;
208 out().flush();
209}
210
211
212void tarch::logging::CommandLineLogger::info(long int timestampNanoseconds, int rank, int threadId, const std::string& trace, const std::string& message) {
213 std::string outputMessage = constructMessageString(
215 timestampNanoseconds, rank, threadId, trace, message
216 );
217
218 tarch::multicore::Lock lockCout( _semaphore );
219 out() << outputMessage;
220 if (_outputStream!=nullptr) {
221 std::cout << outputMessage;
222 }
223}
224
225
226void tarch::logging::CommandLineLogger::warning(long int timestampNanoseconds, int rank, int threadId, const std::string& trace, const std::string& message) {
227 std::string outputMessage = constructMessageString(
229 timestampNanoseconds, rank, threadId, trace, message
230 );
231
232 tarch::multicore::Lock lockCout( _semaphore );
233 if (_outputStream!=nullptr) {
234 out() << outputMessage;
235 out().flush();
236 }
237 std::cerr << outputMessage;
238 std::cerr.flush();
239}
240
241
242void tarch::logging::CommandLineLogger::error(long int timestampNanoseconds, int rank, int threadId, const std::string& trace, const std::string& message) {
243 std::string outputMessage = constructMessageString(
244 "error",
245 timestampNanoseconds, rank, threadId, trace, message
246 );
247
248 tarch::multicore::Lock lockCout( _semaphore );
249 if (_outputStream!=nullptr) {
250 out() << outputMessage;
251 out().flush();
252 }
253 std::cerr << outputMessage;
254 std::cerr.flush();
255
256 if (_quitOnError) {
258 }
259}
260
261
262void tarch::logging::CommandLineLogger::traceIn(long int timestampNanoseconds, int rank, int threadId, const std::string& trace, const std::string& message) {
263 std::string outputMessage = constructMessageString(
264 "trace",
265 timestampNanoseconds, rank, threadId, trace, message
266 );
267
268 tarch::multicore::Lock lockCout( _semaphore );
269 out() << outputMessage;
270 out().flush();
271}
272
273
274void tarch::logging::CommandLineLogger::traceOut(long int timestampNanoseconds, int rank, int threadId, const std::string& trace, const std::string& message) {
275 std::string outputMessage = constructMessageString(
276 "trace",
277 timestampNanoseconds, rank, threadId, trace, message
278 );
279
280 tarch::multicore::Lock lockCout( _semaphore );
281 out() << outputMessage;
282 out().flush();
283}
284
285
286void tarch::logging::CommandLineLogger::indent( [[maybe_unused]] bool indent, [[maybe_unused]] const std::string& trace, [[maybe_unused]] const std::string& message ) {
287 #if PeanoDebug>=1
288 tarch::multicore::Lock lockCout( _semaphore );
289 if (indent) {
290 _indent+=NumberOfIndentSpaces;
291 if ( tarch::multicore::Core::getInstance().getNumberOfThreads()<=1 ) {
292 _indentTraces.push(trace);
293 }
294 } else {
295 if ( tarch::multicore::Core::getInstance().getNumberOfThreads()<=1 ) {
297 not _indentTraces.empty(),
298 trace,
299 message,
300 indent
301 );
303 _indentTraces.top(),
304 trace,
305 message,
306 indent
307 );
308 _indentTraces.pop();
310 _indent >= NumberOfIndentSpaces,
311 _indent, NumberOfIndentSpaces,
312 "more logTraceOut calls than logTraceIn calls invoked before",
313 trace, message
314 );
315 }
316 _indent-=NumberOfIndentSpaces;
317 }
318 #endif
319}
320
321
323 tarch::multicore::Lock lock( _semaphore );
324
325 if (_outputStream!=nullptr && _hasWrittenToOuputStream) {
326 _outputStream->flush();
327 delete _outputStream;
328 _outputStream = nullptr;
329 _hasWrittenToOuputStream = false;
330 }
331
332 if (!_outputFileName.empty() && _outputStream==nullptr) {
333 std::ostringstream fileName;
334 if (_iterationCounter>0) {
335 int leadingZeros = 1;
336 for (int i=0; i<DigitsInFilenamesIterationNumer-1; i++) {
337 leadingZeros*=10;
338 }
339 fileName << "grid-traversal-" ;
340 while (_iterationCounter < leadingZeros) {
341 fileName << "0";
342 leadingZeros /= 10;
343 }
344 fileName << _iterationCounter << "-";
345 }
346 fileName << _outputFileName;
347 _outputStream = new std::ofstream( fileName.str().c_str() );
348 }
349}
350
351
352void tarch::logging::CommandLineLogger::setOutputFile( const std::string& outputLogFileName ) {
353 #ifdef Parallel
354 if (!outputLogFileName.empty()) {
355 std::ostringstream myOutputFileName;
356 myOutputFileName << "rank-" << tarch::mpi::Rank::getInstance().getRank() << "-" << outputLogFileName;
357 _outputFileName = myOutputFileName.str();
358 }
359 else {
360 _outputFileName = outputLogFileName;
361 }
362 #else
363 _outputFileName = outputLogFileName;
364 #endif
365
366 reopenOutputStream();
367}
368
369
371 const std::string& columnSeparator,
372 bool logTimeStamp,
373 bool logTimeStampHumanReadable,
374 bool logMachineName,
375 bool logThreadName,
376 bool logMessageType,
377 bool logTrace,
378 const std::string& outputLogFileName
379) {
380 _logColumnSeparator = columnSeparator;
381 _logTimeStamp = logTimeStamp;
382 _logTimeStampHumanReadable = logTimeStampHumanReadable;
383 _logMachineName = logMachineName;
384 _logThreadName = logThreadName;
385 _logMessageType = logMessageType;
386 _logTrace = logTrace;
387
388 setOutputFile( outputLogFileName );
389}
390
391
393 return _logColumnSeparator;
394}
395
396
398 return _logTimeStamp;
399}
400
401
403 return _logTimeStampHumanReadable;
404}
405
406
408 return _logMachineName;
409}
410
411
413 return _logThreadName;
414}
415
416
418 return _logMessageType;
419}
420
421
423 return _logTrace;
424}
425
426
428 _logColumnSeparator = separator;
429}
430
431
433 _logTimeStamp = value;
434}
435
436
438 _logTimeStampHumanReadable = value;
439}
440
441
443 _logMachineName = value;
444}
445
446
448 _logThreadName = value;
449}
450
451
453 _logMessageType = value;
454}
455
456
458 _logTrace = value;
459}
460
461
463 _quitOnError = value;
464}
465
466
468 std::cout.flush();
469 std::cerr.flush();
470 if (_outputStream!=nullptr) {
471 _outputStream->flush();
472 delete _outputStream;
473 _outputStream = nullptr;
474 }
475}
#define assertion3(expr, param0, param1, param2)
#define assertion(expr)
#define assertionEquals2(lhs, rhs, a, b)
#define assertion5(expr, param0, param1, param2, param3, param4)
#define logWarning(methodName, logMacroMessageStream)
Wrapper macro around tarch::tarch::logging::Log to improve logging.
Definition Log.h:440
bool getLogTrace() const
Is public as some analysis frameworks check explicitly whether these features are switched on.
bool getLogTimeStamp() const
Is public as some analysis frameworks check explicitly whether these features are switched on.
static const std::string::size_type NumberOfIndentSpaces
std::string constructMessageString(std::string messageType, long int timestampNanoseconds, int rank, int threadId, const std::string &trace, const std::string &message)
Construct message string.
void closeOutputStreamAndReopenNewOne()
The command line logger can pipe debug data into an output file instead of piping everything to the t...
static const std::string::size_type NumberOfStandardColumnSpaces
void setLogTimeStampHumanReadable(bool value=true)
void setLogFormat(const std::string &columnSeparator, bool logTimeStamp, bool logTimeStampHumanReadable, bool logMachineName, bool logThreadName, bool logMessageType, bool logTrace, const std::string &outputLogFileName)
void setLogColumnSeparator(const std::string &separator=" ")
static CommandLineLogger & getInstance()
void indent(bool indent, const std::string &trace, const std::string &message)
Tells the logger to increment/decrement the indent.
static std::string getTimeStampHumanReadable(long int timestampNanoseconds)
static const std::string::size_type NumberOfTraceColumnSpaces
The trace column is not formatted using only tabulators, but it uses spaces to create a unique column...
void traceOut(long int timestampNanoseconds, int rank, int threadId, const std::string &trace, const std::string &message)
void configureOutputStreams()
Configures the output streams.
static CommandLineLogger _singleton
CommandLineLogger & operator=(const CommandLineLogger &)
Declared private since assignment does not make sense for an output class (output information mismatc...
void debug(long int timestampNanoseconds, int rank, int threadId, const std::string &trace, const std::string &message)
void error(long int timestampNanoseconds, int rank, int threadId, const std::string &trace, const std::string &message)
Write Error.
bool getLogMachineName() const
Is public as some analysis frameworks check explicitly whether these features are switched on.
void setOutputFile(const std::string &outputLogFileName)
Is redundant, as you could use setLogFormat() instead.
void traceIn(long int timestampNanoseconds, int rank, int threadId, const std::string &trace, const std::string &message)
void info(long int timestampNanoseconds, int rank, int threadId, const std::string &trace, const std::string &message)
static std::string::size_type _indent
Indent is supported only in debug mode.
std::string addSeparators(std::string::size_type spaces, std::string message) const
Takes the message and adds spaces such that the entries are aligned like in a table.
void warning(long int timestampNanoseconds, int rank, int threadId, const std::string &trace, const std::string &message)
Write Warning.
bool getLogThreadName() const
Is public as some analysis frameworks check explicitly whether these features are switched on.
Log Device.
Definition Log.h:516
static Rank & getInstance()
This operation returns the singleton instance.
Definition Rank.cpp:539
int getRank() const
Return rank of this node.
Definition Rank.cpp:529
static void abort(int errorCode)
A proper abort in an MPI context has to use MPI_Abort.
Definition Rank.cpp:592
static Core & getInstance()
Definition Core.cpp:56
Create a lock around a boolean semaphore region.
Definition Lock.h:19
static const std::string TargetDebug
Definition LogFilter.h:35
static const std::string TargetInfo
Definition LogFilter.h:34
static const std::string TargetWarning
Definition LogFilter.h:37