Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
log.hpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2016 Quaternion Risk Management Ltd
3 All rights reserved.
4
5 This file is part of ORE, a free-software/open-source library
6 for transparent pricing and risk analysis - http://opensourcerisk.org
7
8 ORE is free software: you can redistribute it and/or modify it
9 under the terms of the Modified BSD License. You should have received a
10 copy of the license along with this program.
11 The license is also available online at <http://opensourcerisk.org>
12
13 This program is distributed on the basis that it will form a useful
14 contribution to risk analytics and model standardisation, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the license for more details.
17*/
18
19/*! \file ored/utilities/log.hpp
20 \brief Classes and functions for log message handling.
21 \ingroup utilities
22*/
23
24#pragma once
25
26// accumulated 'filter' for 'external' DEBUG_MASK
27#define ORE_ALERT 1 // 00000001 1 = 2^1-1
28#define ORE_CRITICAL 2 // 00000010 3 = 2^2-1
29#define ORE_ERROR 4 // 00000100 7
30#define ORE_WARNING 8 // 00001000 15
31#define ORE_NOTICE 16 // 00010000 31
32#define ORE_DEBUG 32 // 00100000 63 = 2^6-1
33#define ORE_DATA 64 // 01000000 127
34#define ORE_MEMORY 128 // 10000000 255
35
36#include <fstream>
37#include <iostream>
38#include <string>
39#include <time.h>
40
41#include <boost/algorithm/string.hpp>
42#include <boost/log/attributes/mutable_constant.hpp>
43#include <boost/log/utility/manipulators/add_value.hpp>
44#include <boost/log/attributes.hpp>
45#include <boost/log/expressions.hpp>
46#include <boost/log/expressions/formatters/date_time.hpp>
47#include <boost/log/sinks.hpp>
48#include <boost/log/sources/global_logger_storage.hpp>
49#include <boost/log/sources/record_ostream.hpp>
50#include <boost/log/sources/severity_logger.hpp>
51#include <boost/filesystem.hpp>
52#include <ql/shared_ptr.hpp>
53#include <map>
54#include <ql/qldefines.hpp>
55#include <queue>
56
57#ifndef BOOST_MSVC
58#include <unistd.h>
59#endif
60
61#include <iomanip>
63#include <ql/patterns/singleton.hpp>
64#include <sstream>
65
66#include <boost/any.hpp>
67#include <boost/thread/shared_mutex.hpp>
68#include <boost/thread/lock_types.hpp>
69
79};
80
81
82//! Outputs stringized representation of the severity level to the stream
83template <typename CharT, typename TraitsT>
84inline std::basic_ostream<CharT, TraitsT>& operator<<(std::basic_ostream<CharT, TraitsT>& strm, oreSeverity lvl) {
85 switch (lvl) {
87 strm << "ALERT";
88 break;
90 strm << "CRITICAL";
91 break;
93 strm << "ERROR";
94 break;
96 strm << "WARNING";
97 break;
99 strm << "NOTICE";
100 break;
102 strm << "DEBUG";
103 break;
105 strm << "DATA";
106 break;
108 strm << "MEMORY";
109 break;
110 default:
111 strm << "UNKNOWN";
112 }
113
114 return strm;
115}
116
117namespace ore {
118namespace data {
119
120typedef boost::log::sinks::synchronous_sink<boost::log::sinks::text_file_backend> file_sink;
121typedef boost::log::sinks::synchronous_sink<boost::log::sinks::text_ostream_backend> text_sink;
122
123//! The Base Custom Log Handler class
124/*!
125 This base log handler class can be used to define your own custom handler and then registered with the Log class.
126 Once registered it will receive all log messages as soon as they occur via it's log() method
127 \ingroup utilities
128 \see Log
129 */
130class Logger {
131public:
132 //! Destructor
133 virtual ~Logger() {}
134
135 //! The Log call back function
136 /*!
137 This function will be called every time a log message is produced.
138 \param level the log level
139 \param s the log message
140 */
141 virtual void log(unsigned level, const std::string& s) = 0;
142
143 //! Returns the Logger name
144 const std::string& name() { return name_; }
145
146protected:
147 //! Constructor
148 /*!
149 Implementations must provide a logger name
150 \param name the logger name
151 */
152 Logger(const std::string& name) : name_(name) {}
153
154private:
155 std::string name_;
156};
157
158//! Stderr Logger
159/*!
160 This logger writes each log message out to stderr (std::cerr)
161 \ingroup utilities
162 \see Log
163 */
164class StderrLogger : public Logger {
165public:
166 //! the name "StderrLogger"
167 static const std::string name;
168 //! Constructor
169 /*!
170 This logger writes all logs to stderr.
171 If alertOnly is set to true, it will only write alerts.
172 */
173 StderrLogger(bool alertOnly = false) : Logger(name), alertOnly_(alertOnly) {}
174 //! Destructor
175 virtual ~StderrLogger() {}
176 //! The log callback that writes to stderr
177 virtual void log(unsigned l, const std::string& s) override {
178 if (!alertOnly_ || l == ORE_ALERT)
179 std::cerr << s << std::endl;
180 }
181
182private:
184};
185
186//! FileLogger
187/*!
188 This logger writes each log message out to the given file.
189 The file is flushed, but not closed, after each log message.
190 \ingroup utilities
191 \see Log
192 */
193class FileLogger : public Logger {
194public:
195 //! the name "FileLogger"
196 static const std::string name;
197 //! Constructor
198 /*!
199 Construct a file logger using the given filename, this filename is passed to std::fostream::open()
200 and this constructor will throw an exception if the file is not opened (e.g. if the filename is invalid)
201 \param filename the log filename
202 */
203 FileLogger(const std::string& filename);
204 //! Destructor
205 virtual ~FileLogger();
206 //! The log callback
207 virtual void log(unsigned, const std::string&) override;
208
209private:
210 std::string filename_;
211 std::fstream fout_;
212};
213
214//! BufferLogger
215/*!
216 This logger stores each log message in an internal buffer, it can then be probed for log messages at a later point.
217 Log messages are always returned in a FIFO order.
218
219 Typical usage to display log messages would be
220 <pre>
221 while (bLogger.hasNext()) {
222 MsgBox("Log Message", bLogger.next());
223 }
224 </pre>
225 \ingroup utilities
226 \see Log
227 */
228class BufferLogger : public Logger {
229public:
230 //! the name "BufferLogger"
231 static const std::string name;
232 //! Constructor
233 BufferLogger(unsigned minLevel = ORE_DATA) : Logger(name), minLevel_(minLevel) {}
234 //! Destructor
235 virtual ~BufferLogger() {}
236 //! The log callback
237 virtual void log(unsigned, const std::string&) override;
238
239 //! Checks if Logger has new messages
240 /*!
241 \return True if this BufferLogger has any new log messages
242 */
243 bool hasNext();
244 //! Retrieve new messages
245 /*!
246 Retrieve the next new message from the buffer, this will throw if the buffer is empty.
247 Messages are returned in a FIFO order. Messages are deleted from the buffer once returned.
248 \return The next message
249 */
250 std::string next();
251
252private:
253 std::queue<std::string> buffer_;
254 unsigned minLevel_;
255};
256
257//! Base Log handler class that utilises Boost logging to create log sinks
258/*!
259 This type of logger should only be received via Log::registerIndependentLoggers().
260 It is responsible for creating and maintaining Boost log sink/s and nothing more.
261 \ingroup utilities
262 \see Log
263 */
265public:
266 //! Destructor
268 virtual void removeSinks() = 0;
269 std::vector<std::string>& messages() { return messages_; }
270 void clear();
271
272 //! Returns the Logger name
273 const std::string& name() const { return name_; }
274
275protected:
276 //! Constructor
277 /*!
278 Implementations must provide a logger name
279 \param name the logger name
280 */
281 IndependentLogger(const std::string& name) : name_(name) {}
282 std::vector<std::string> messages_;
283
284private:
285 std::string name_;
286};
287
288//! ProgressLogger
289//! //! This logger stores each log message in a separate location indicating progress of analytic runs.
291
292public:
293 //! the name "ProgressLogger"
294 static const std::string name;
295 //! Constructors
297 ProgressLogger(const bool coutLog) : ProgressLogger() { setCoutLog(coutLog); }
298 const QuantLib::ext::shared_ptr<file_sink>& fileSink() { return fileSink_; }
299 const QuantLib::ext::shared_ptr<text_sink>& coutSink() { return coutSink_; }
300 const QuantLib::ext::shared_ptr<text_sink>& cacheSink() { return cacheSink_; }
301 //! Destructor
302 virtual void removeSinks() override;
303 void setCoutLog(bool flag);
304 void setFileLog(const std::string& filepath, const boost::filesystem::path& dir, QuantLib::Size rotationSize = 0);
305
306private:
307 QuantLib::ext::shared_ptr<file_sink> fileSink_;
308 QuantLib::ext::shared_ptr<text_sink> coutSink_;
309 QuantLib::ext::shared_ptr<text_sink> cacheSink_;
310};
311
312//! StructuredLogger
313//! //! This logger stores each structured error/warning message in a separate location
315
316public:
317 //! the name "StructuredLogger"
318 static const std::string name;
319 //! Constructors
321 const QuantLib::ext::shared_ptr<file_sink>& fileSink() { return fileSink_; }
322 const QuantLib::ext::shared_ptr<text_sink>& cacheSink() { return cacheSink_; }
323 //! Destructor
324 virtual void removeSinks() override;
325 void setFileLog(const std::string& filepath, const boost::filesystem::path& dir, QuantLib::Size rotationSize = 0);
326
327private:
328 QuantLib::ext::shared_ptr<file_sink> fileSink_;
329 QuantLib::ext::shared_ptr<text_sink> cacheSink_;
330};
331
332//! EventLogger
333/*!
334This logger listens for EventMessage logs from within ORE to support event logging for ORE components
335*/
337public:
338 //! the name "EventLogger"
339 static const std::string name;
340
341 //! Constructor
342 //! This logger will only write event logs. All other logs will be ignored.
344
345 void setFormatter(const std::function<void(const boost::log::record_view&, boost::log::formatting_ostream&)>&);
346 const QuantLib::ext::shared_ptr<file_sink>& fileSink() { return fileSink_; }
347 //! Destructor
348 virtual void removeSinks() override;
349 void setFileLog(const std::string& filepath);
350
351private:
352 QuantLib::ext::shared_ptr<file_sink> fileSink_;
353};
354
355//! Global static Log class
356/*!
357 The Global Log class gets registered with individual loggers and receives application log messages.
358 Once a message is received, it is immediately dispatched to each of the registered loggers, the order in which
359 the loggers are called is not guaranteed.
360
361 Logging is done by the calling thread and the LOG call blocks until all the loggers have returned.
362
363 At start up, the Log class has no loggers and so will ignore any LOG() messages until it is configured.
364
365 To configure the Log class to log to a file "/tmp/my_log.txt"
366 <pre>
367 Log::instance().removeAllLoggers();
368 Log::instance().registerLogger(QuantLib::ext::shared_ptr<Logger>(new FileLogger("/tmp/my_log.txt")));
369 </pre>
370
371 To change the Log class to only use a BufferLogger the user must call
372 <pre>
373 Log::instance().removeAllLoggers();
374 Log::instance().registerLogger(QuantLib::ext::shared_ptr<Logger>(new BufferLogger));
375 </pre>
376 and then to retrieve log messages from the buffer and print them to stdout the user must call:
377 <pre>
378 std::cout << "Begin Log Messages:" << std::endl;
379
380 QuantLib::ext::shared_ptr<BufferLogger> bl = QuantLib::ext::dynamic_pointer_cast<BufferLogger>
381 (Log::instance().logger(BufferLogger::name));
382
383 while (bl.hasNext())
384 std::cout << bl.next() << std::endl;
385 std::cout << "End Log Messages." << std::endl;
386 </pre>
387 \ingroup utilities
388 */
389class Log : public QuantLib::Singleton<Log, std::integral_constant<bool, true>> {
390
391 friend class QuantLib::Singleton<Log, std::integral_constant<bool, true>>;
392
393public:
394 //! Add a new Logger.
395 /*!
396 Adds a new logger to the Log class, the logger will be stored by it's Logger::name().
397 This method will throw if a logger with the same name is already registered.
398 \param logger the logger to add
399 */
400 void registerLogger(const QuantLib::ext::shared_ptr<Logger>& logger);
401 void registerIndependentLogger(const QuantLib::ext::shared_ptr<IndependentLogger>& logger);
403
404 //! Check if logger exists
405 const bool hasLogger(const std::string& name) const;
406 const bool hasIndependentLogger(const std::string& name) const;
407
408 //! Retrieve a Logger.
409 /*!
410 Retrieve a Logger by it's name, for example to retrieve the StderrLogger (assuming it is registered)
411 <pre>
412 QuantLib::ext::shared_ptr<Logger> slogger = Log::instance().logger(StderrLogger::name);
413 </pre>
414 */
415 QuantLib::ext::shared_ptr<Logger>& logger(const std::string& name);
416 QuantLib::ext::shared_ptr<IndependentLogger>& independentLogger(const std::string& name);
417
418 //! Remove a Logger
419 /*!
420 Remove a logger by name
421 \param name the logger name
422 */
423 void removeLogger(const std::string& name);
424 void removeIndependentLogger(const std::string& name);
425
426 //! Remove all loggers
427 /*!
428 Removes all loggers. If called, all subsequent log messages will be ignored.
429 */
430 void removeAllLoggers();
431
432 void addExcludeFilter(const std::string&, const std::function<bool(const std::string&)>);
433
434 void removeExcludeFilter(const std::string&);
435
436 bool checkExcludeFilters(const std::string&);
437
438 //! macro utility function - do not use directly, not thread safe
439 void header(unsigned m, const char* filename, int lineNo);
440 //! macro utility function - do not use directly, not thread safe
441 std::ostream& logStream() { return ls_; }
442 //! macro utility function - do not use directly, not thread safe
443 void log(unsigned m);
444
445 //! mutex to acquire locks
446 boost::shared_mutex& mutex() { return mutex_; }
447
448 // Avoid a large number of warnings in VS by adding 0 !=
449 bool filter(unsigned mask) {
450 boost::shared_lock<boost::shared_mutex> lock(mutex());
451 return 0 != (mask & mask_);
452 }
453 unsigned mask() {
454 boost::shared_lock<boost::shared_mutex> lock(mutex());
455 return mask_;
456 }
457 void setMask(unsigned mask) {
458 boost::unique_lock<boost::shared_mutex> lock(mutex());
459 mask_ = mask;
460 }
461 const boost::filesystem::path& rootPath() {
462 boost::shared_lock<boost::shared_mutex> lock(mutex());
463 return rootPath_;
464 }
465 void setRootPath(const boost::filesystem::path& pth) {
466 boost::unique_lock<boost::shared_mutex> lock(mutex());
467 rootPath_ = pth;
468 }
469 int maxLen() {
470 boost::shared_lock<boost::shared_mutex> lock(mutex());
471 return maxLen_;
472 }
473 void setMaxLen(const int n) {
474 boost::unique_lock<boost::shared_mutex> lock(mutex());
475 maxLen_ = n;
476 }
477
478 bool enabled() {
479 boost::shared_lock<boost::shared_mutex> lock(mutex());
480 return enabled_;
481 }
482 void switchOn() {
483 boost::unique_lock<boost::shared_mutex> lock(mutex());
484 enabled_ = true;
485 }
486 void switchOff() {
487 boost::unique_lock<boost::shared_mutex> lock(mutex());
488 enabled_ = false;
489 }
490
492 boost::shared_lock<boost::shared_mutex> lock(mutex());
494 }
495
496 //! if a PID is set for the logger, messages are tagged with [1234] if pid = 1234
497 void setPid(const int pid) { pid_ = pid; }
498
499private:
500 Log();
501
502 // not thread safe
503 std::string source(const char* filename, int lineNo) const;
504
505 std::map<std::string, QuantLib::ext::shared_ptr<Logger>> loggers_;
506 std::map<std::string, QuantLib::ext::shared_ptr<IndependentLogger>> independentLoggers_;
508 unsigned mask_;
509 boost::filesystem::path rootPath_;
510 std::ostringstream ls_;
511
512 int maxLen_ = 45;
515 std::size_t sameSourceLocationCutoff_ = 1000;
516 std::string lastFileName_;
517 int lastLineNo_ = 0;
518
519 int pid_ = 0;
520
521 mutable boost::shared_mutex mutex_;
522
523 std::map<std::string, std::function<bool(const std::string&)>> excludeFilters_;
524};
525
526/*!
527 Main Logging macro, do not use this directly, use on of the below 6 macros instead
528 */
529#define MLOG(mask, text) \
530 { \
531 if (ore::data::Log::instance().enabled() && ore::data::Log::instance().filter(mask)) { \
532 std::ostringstream __ore_mlog_tmp_stringstream__; \
533 __ore_mlog_tmp_stringstream__ << text; \
534 if (!ore::data::Log::instance().checkExcludeFilters(__ore_mlog_tmp_stringstream__.str())) { \
535 boost::unique_lock<boost::shared_mutex> lock(ore::data::Log::instance().mutex()); \
536 ore::data::Log::instance().header(mask, __FILE__, __LINE__); \
537 ore::data::Log::instance().logStream() << __ore_mlog_tmp_stringstream__.str(); \
538 ore::data::Log::instance().log(mask); \
539 } \
540 } \
541 }
542
543//! Logging Macro (Level = Alert)
544#define ALOG(text) MLOG(oreSeverity::alert, text);
545//! Logging Macro (Level = Critical)
546#define CLOG(text) MLOG(oreSeverity::critical, text)
547//! Logging Macro (Level = Error)
548#define ELOG(text) MLOG(oreSeverity::error, text)
549//! Logging Macro (Level = Warning)
550#define WLOG(text) MLOG(oreSeverity::warning, text)
551//! Logging Macro (Level = Notice)
552#define LOG(text) MLOG(oreSeverity::notice, text)
553//! Logging Macro (Level = Debug)
554#define DLOG(text) MLOG(oreSeverity::debug, text)
555//! Logging Macro (Level = Data)
556#define TLOG(text) MLOG(oreSeverity::data, text)
557
558//! Logging macro specifically for logging memory usage
559#define MEM_LOG MEM_LOG_USING_LEVEL(oreSeverity::memory)
560
561#define MEM_LOG_USING_LEVEL(LEVEL) \
562 { \
563 if (ore::data::Log::instance().enabled() && ore::data::Log::instance().filter(LEVEL)) { \
564 boost::unique_lock<boost::shared_mutex> lock(ore::data::Log::instance().mutex()); \
565 ore::data::Log::instance().header(LEVEL, __FILE__, __LINE__); \
566 ore::data::Log::instance().logStream() << std::to_string(ore::data::os::getPeakMemoryUsageBytes()) << "|"; \
567 ore::data::Log::instance().logStream() << std::to_string(ore::data::os::getMemoryUsageBytes()); \
568 ore::data::Log::instance().log(LEVEL); \
569 } \
570 }
571
572//! LoggerStream class that is a std::ostream replacement that will log each line
573/*! LoggerStream is a simple wrapper around a std::string stream, it has an explicit
574 cast std::ostream& method so it can be used in place of any std::ostream, this
575 can be used with QuantExt methods that take a std::ostream& for logging purposes.
576
577 Once the stream falls out of focus, it's destructor will take the buffered log
578 messages and pass them the main ore::data::Log::instance().
579
580 Note the following
581 - The timestamps for each log message will correspond to when the LoggerStream
582 destructor has been called, this may not correspond to the actual time the event
583 occurred.
584 - The filename and linenumber in the ore::data::Log() have to be explicitly passed to
585 the LoggerStream, as such the log messages will not correspond to any references
586 in QuantExt (or any other library).
587
588 The LoggerStream relies on falling out of scope to trigger the logging, as such they
589 should not be created using the new operator.
590
591 The proper usage is to use the macro LOGGERSTREAM and DLOGGERSTREAM, if a function takes
592 a std::ostream& as a parameter, use the macro instead.
593
594 \code{.cpp}
595 void function(int x, int y, std::ostream& out);
596
597 void main () {
598
599 // call function
600 function (3, 4, LOGGERSTREAM);
601 // All logging will be completed before this line
602 }
603 \endcode
604 */
606public:
607 LoggerStream(unsigned mask, const char* filename, unsigned lineNo);
608
609 //! destructor - this is when the logging takes place.
611
612 //! cast this LoggerStream as a ostream&
613 operator std::ostream &() { return ss_; }
614
615private:
616 unsigned mask_;
617 const char* filename_;
618 unsigned lineNo_;
619 std::stringstream ss_;
620};
621
622#define CHECKED_LOGGERSTREAM(LEVEL, text) \
623 if (ore::data::Log::instance().enabled() && ore::data::Log::instance().filter(LEVEL)) { \
624 (std::ostream&)ore::data::LoggerStream(LEVEL, __FILE__, __LINE__) << text; \
625 }
626
627#define ALOGGERSTREAM(text) CHECKED_LOGGERSTREAM(ORE_ALERT, text)
628#define CLOGGERSTREAM(text) CHECKED_LOGGERSTREAM(ORE_CRITICAL, text)
629#define ELOGGERSTREAM(text) CHECKED_LOGGERSTREAM(ORE_ERROR, text)
630#define WLOGGERSTREAM(text) CHECKED_LOGGERSTREAM(ORE_WARNING, text)
631#define LOGGERSTREAM(text) CHECKED_LOGGERSTREAM(ORE_NOTICE, text)
632#define DLOGGERSTREAM(text) CHECKED_LOGGERSTREAM(ORE_DEBUG, text)
633#define TLOGGERSTREAM(text) CHECKED_LOGGERSTREAM(ORE_DATA, text)
634
636public:
637 virtual ~JSONMessage() {}
638 //! return a std::string for the log file
639 virtual std::string msg() const = 0;
640 //! generate Boost log record to pass to corresponding sinks
641 void log() const;
642 //! create JSON-like output from the data
643 const std::string json() const { return jsonify(data_); }
644 void set(const std::string& key, const boost::any& value) { data_[key] = value; }
645
646protected:
647 //! generate Boost log record - this method is called by log()
648 virtual void emitLog() const = 0;
649 static std::string jsonify(const boost::any&);
650
651 std::map<std::string, boost::any> data_;
652};
653
654// This can be used directly in log messages, e.g.
655// ALOG(StructuredTradeErrorMessage(trade->id(), trade->tradeType(), "Error Parsing Trade", "Invalid XML Node foo"));
656// And in the log file you will get
657//
658// .... StructuredMessage {
659// "category": "Error",
660// "group": "Trade",
661// "message": "Invalid XML Node foo",
662// "subFields": [
663// {
664// "fieldName": "exceptionType",
665// "fieldValue": "Error Parsing Trade"
666// },
667// {
668// "fieldName": "tradeId",
669// "fieldValue": "foo"
670// },
671// {
672// "fieldName": "tradeType",
673// "fieldValue": "Swap"
674// }
675// ]
676//}
678public:
679 enum class Category { Error, Warning, Unknown };
680
682
683 StructuredMessage(const Category& category, const Group& group, const std::string& message,
684 const std::map<std::string, std::string>& subFields = std::map<std::string, std::string>());
685
686 StructuredMessage(const Category& category, const Group& group, const std::string& message,
687 const std::pair<std::string, std::string>& subField = std::pair<std::string, std::string>())
688 : StructuredMessage(category, group, message, std::map<std::string, std::string>({subField})) {}
689
691
692 static constexpr const char* name = "StructuredMessage";
693
694 //! return a std::string for the log file
695 std::string msg() const { return std::string(name) + std::string(" ") + json(); }
696 //! generate Boost log record to pass to corresponding sinks
697 void emitLog() const;
698
699protected:
700 void addSubFields(const std::map<std::string, std::string>&);
701};
702
703std::ostream& operator<<(std::ostream& out, const StructuredMessage::Category&);
704
705std::ostream& operator<<(std::ostream& out, const StructuredMessage::Group&);
706
708public:
709 StructuredLoggingErrorMessage(const std::string& exceptionType, const std::string& exceptionWhat = "")
710 : StructuredMessage(Category::Error, Group::Logging, exceptionWhat,
711 std::pair<std::string, std::string>({"exceptionType", exceptionType})){};
712};
713
714class EventMessage : public JSONMessage {
715public:
716 EventMessage(const std::string& msg, const std::string& msgKey, const std::map<std::string, boost::any> data = {}) {
717 data_ = data;
718 data_[msgKey] = msg;
719 }
720
721 static constexpr const char* name = "EventMessage";
722
723 //! return a std::string for the log file
724 std::string msg() const { return std::string(name) + std::string(" ") + json(); }
725 //! generate Boost log record to pass to corresponding sinks
726 void emitLog() const;
727
728private:
729 std::string message_;
730};
731
733public:
734 ProgressMessage(const std::string&, const QuantLib::Size, const QuantLib::Size, const std::string& detail = "");
735
736 static constexpr const char* name = "ProgressMessage";
737
738 //! return a std::string for the log file
739 std::string msg() const { return std::string(name) + std::string(" ") + json(); }
740 //! generate Boost log record to pass to corresponding sinks
741 void emitLog() const;
742};
743
744//! Singleton to control console logging
745//
746class ConsoleLog : public QuantLib::Singleton<ConsoleLog, std::integral_constant<bool, true>> {
747 friend class QuantLib::Singleton<ConsoleLog, std::integral_constant<bool, true>>;
748private:
749 // may be empty but never uninitialised
751
753 QuantLib::Size width_;
754 QuantLib::Size progressBarWidth_;
755 mutable boost::shared_mutex mutex_;
756
757public:
758 bool enabled() {
759 boost::shared_lock<boost::shared_mutex> lock(mutex());
760 return enabled_;
761 }
762 QuantLib::Size width() {
763 boost::shared_lock<boost::shared_mutex> lock(mutex_);
764 return width_;
765 }
766 QuantLib::Size progressBarWidth() {
767 boost::shared_lock<boost::shared_mutex> lock(mutex_);
768 return progressBarWidth_;
769 }
770 void switchOn() {
771 boost::unique_lock<boost::shared_mutex> lock(mutex_);
772 enabled_ = true;
773 }
774 void switchOff() {
775 boost::unique_lock<boost::shared_mutex> lock(mutex_);
776 enabled_ = false;
777 }
778 void setWidth(QuantLib::Size w) {
779 boost::unique_lock<boost::shared_mutex> lock(mutex_);
780 width_ = w;
781 }
782 void setProgressBarWidth(QuantLib::Size w) {
783 boost::unique_lock<boost::shared_mutex> lock(mutex_);
785 }
786 //! mutex to acquire locks
787 boost::shared_mutex& mutex() { return mutex_; }
788};
789
790#define CONSOLEW(text) \
791 { \
792 if (ore::data::ConsoleLog::instance().enabled()) { \
793 Size w = ore::data::ConsoleLog::instance().width(); \
794 std::ostringstream oss; \
795 oss << text; \
796 Size len = oss.str().length(); \
797 Size wsLen = w > len ? w - len : 1; \
798 oss << std::string(wsLen, ' '); \
799 boost::unique_lock<boost::shared_mutex> lock(ore::data::ConsoleLog::instance().mutex()); \
800 std::cout << oss.str(); \
801 std::cout << std::flush; \
802 } \
803 }
804
805#define CONSOLE(text) \
806 { \
807 if (ore::data::ConsoleLog::instance().enabled()) { \
808 std::ostringstream oss; \
809 oss << text; \
810 boost::unique_lock<boost::shared_mutex> lock(ore::data::ConsoleLog::instance().mutex()); \
811 std::cout << oss.str() << "\n"; \
812 std::cout << std::flush; \
813 } \
814 }
815
816} // namespace data
817} // namespace ore
BufferLogger.
Definition: log.hpp:228
static const std::string name
the name "BufferLogger"
Definition: log.hpp:231
std::queue< std::string > buffer_
Definition: log.hpp:253
BufferLogger(unsigned minLevel=64)
Constructor.
Definition: log.hpp:233
virtual void log(unsigned, const std::string &) override
The log callback.
Definition: log.cpp:68
bool hasNext()
Checks if Logger has new messages.
Definition: log.cpp:73
virtual ~BufferLogger()
Destructor.
Definition: log.hpp:235
unsigned minLevel_
Definition: log.hpp:254
std::string next()
Retrieve new messages.
Definition: log.cpp:75
Singleton to control console logging.
Definition: log.hpp:746
void setWidth(QuantLib::Size w)
Definition: log.hpp:778
boost::shared_mutex & mutex()
mutex to acquire locks
Definition: log.hpp:787
QuantLib::Size progressBarWidth_
Definition: log.hpp:754
QuantLib::Size width_
Definition: log.hpp:753
QuantLib::Size progressBarWidth()
Definition: log.hpp:766
boost::shared_mutex mutex_
Definition: log.hpp:755
QuantLib::Size width()
Definition: log.hpp:762
void setProgressBarWidth(QuantLib::Size w)
Definition: log.hpp:782
EventLogger.
Definition: log.hpp:336
static const std::string name
the name "EventLogger"
Definition: log.hpp:339
virtual void removeSinks() override
Destructor.
Definition: log.cpp:248
QuantLib::ext::shared_ptr< file_sink > fileSink_
Definition: log.hpp:352
void setFileLog(const std::string &filepath)
Definition: log.cpp:255
const QuantLib::ext::shared_ptr< file_sink > & fileSink()
Definition: log.hpp:346
void setFormatter(const std::function< void(const boost::log::record_view &, boost::log::formatting_ostream &)> &)
Definition: log.cpp:265
EventMessage(const std::string &msg, const std::string &msgKey, const std::map< std::string, boost::any > data={})
Definition: log.hpp:716
std::string message_
Definition: log.hpp:729
void emitLog() const
generate Boost log record to pass to corresponding sinks
Definition: log.cpp:622
std::string msg() const
return a std::string for the log file
Definition: log.hpp:724
static constexpr const char * name
Definition: log.hpp:721
FileLogger.
Definition: log.hpp:193
virtual ~FileLogger()
Destructor.
Definition: log.cpp:91
static const std::string name
the name "FileLogger"
Definition: log.hpp:196
std::string filename_
Definition: log.hpp:210
std::fstream fout_
Definition: log.hpp:211
virtual void log(unsigned, const std::string &) override
The log callback.
Definition: log.cpp:96
Base Log handler class that utilises Boost logging to create log sinks.
Definition: log.hpp:264
const std::string & name() const
Returns the Logger name.
Definition: log.hpp:273
IndependentLogger(const std::string &name)
Constructor.
Definition: log.hpp:281
std::vector< std::string > & messages()
Definition: log.hpp:269
virtual void removeSinks()=0
std::vector< std::string > messages_
Definition: log.hpp:282
virtual ~IndependentLogger()
Destructor.
Definition: log.hpp:267
const std::string json() const
create JSON-like output from the data
Definition: log.hpp:643
virtual ~JSONMessage()
Definition: log.hpp:637
static std::string jsonify(const boost::any &)
Definition: log.cpp:496
void set(const std::string &key, const boost::any &value)
Definition: log.hpp:644
virtual std::string msg() const =0
return a std::string for the log file
std::map< std::string, boost::any > data_
Definition: log.hpp:651
void log() const
generate Boost log record to pass to corresponding sinks
Definition: log.cpp:491
virtual void emitLog() const =0
generate Boost log record - this method is called by log()
Global static Log class.
Definition: log.hpp:389
unsigned mask_
Definition: log.hpp:508
void switchOff()
Definition: log.hpp:486
std::ostringstream ls_
Definition: log.hpp:510
void removeLogger(const std::string &name)
Remove a Logger.
Definition: log.cpp:320
std::map< std::string, QuantLib::ext::shared_ptr< Logger > > loggers_
Definition: log.hpp:505
boost::shared_mutex & mutex()
mutex to acquire locks
Definition: log.hpp:446
int lastLineNo_
Definition: log.hpp:517
int maxLen_
Definition: log.hpp:512
QuantLib::ext::shared_ptr< Logger > & logger(const std::string &name)
Retrieve a Logger.
Definition: log.cpp:303
int maxLen()
Definition: log.hpp:469
std::ostream & logStream()
macro utility function - do not use directly, not thread safe
Definition: log.hpp:441
const boost::filesystem::path & rootPath()
Definition: log.hpp:461
bool filter(unsigned mask)
Definition: log.hpp:449
void setMask(unsigned mask)
Definition: log.hpp:457
std::map< std::string, std::function< bool(const std::string &)> > excludeFilters_
Definition: log.hpp:523
const bool hasIndependentLogger(const std::string &name) const
Definition: log.cpp:309
std::size_t sameSourceLocationCutoff_
Definition: log.hpp:515
void setPid(const int pid)
if a PID is set for the logger, messages are tagged with [1234] if pid = 1234
Definition: log.hpp:497
std::size_t sameSourceLocationSince_
Definition: log.hpp:513
boost::filesystem::path rootPath_
Definition: log.hpp:509
unsigned mask()
Definition: log.hpp:453
bool writeSuppressedMessagesHint()
Definition: log.hpp:491
const bool hasLogger(const std::string &name) const
Check if logger exists.
Definition: log.cpp:298
void header(unsigned m, const char *filename, int lineNo)
macro utility function - do not use directly, not thread safe
Definition: log.cpp:391
std::string source(const char *filename, int lineNo) const
Definition: log.cpp:348
void removeIndependentLogger(const std::string &name)
Definition: log.cpp:330
bool enabled_
Definition: log.hpp:507
void registerIndependentLogger(const QuantLib::ext::shared_ptr< IndependentLogger > &logger)
Definition: log.cpp:285
boost::shared_mutex mutex_
Definition: log.hpp:521
bool enabled()
Definition: log.hpp:478
std::map< std::string, QuantLib::ext::shared_ptr< IndependentLogger > > independentLoggers_
Definition: log.hpp:506
void removeAllLoggers()
Remove all loggers.
Definition: log.cpp:341
bool checkExcludeFilters(const std::string &)
Definition: log.cpp:382
QuantLib::ext::shared_ptr< IndependentLogger > & independentLogger(const std::string &name)
Definition: log.cpp:314
void addExcludeFilter(const std::string &, const std::function< bool(const std::string &)>)
Definition: log.cpp:372
std::string lastFileName_
Definition: log.hpp:516
void removeExcludeFilter(const std::string &)
Definition: log.cpp:377
void registerLogger(const QuantLib::ext::shared_ptr< Logger > &logger)
Add a new Logger.
Definition: log.cpp:278
void clearAllIndependentLoggers()
Definition: log.cpp:292
bool writeSuppressedMessagesHint_
Definition: log.hpp:514
void setMaxLen(const int n)
Definition: log.hpp:473
void switchOn()
Definition: log.hpp:482
void log(unsigned m)
macro utility function - do not use directly, not thread safe
Definition: log.cpp:449
void setRootPath(const boost::filesystem::path &pth)
Definition: log.hpp:465
The Base Custom Log Handler class.
Definition: log.hpp:130
const std::string & name()
Returns the Logger name.
Definition: log.hpp:144
virtual void log(unsigned level, const std::string &s)=0
The Log call back function.
std::string name_
Definition: log.hpp:155
virtual ~Logger()
Destructor.
Definition: log.hpp:133
Logger(const std::string &name)
Constructor.
Definition: log.hpp:152
LoggerStream class that is a std::ostream replacement that will log each line.
Definition: log.hpp:605
std::stringstream ss_
Definition: log.hpp:619
~LoggerStream()
destructor - this is when the logging takes place.
Definition: log.cpp:478
const char * filename_
Definition: log.hpp:617
static const std::string name
the name "ProgressLogger"
Definition: log.hpp:294
virtual void removeSinks() override
Destructor.
Definition: log.cpp:133
ProgressLogger()
Constructors.
Definition: log.cpp:103
QuantLib::ext::shared_ptr< text_sink > coutSink_
Definition: log.hpp:308
QuantLib::ext::shared_ptr< file_sink > fileSink_
Definition: log.hpp:307
const QuantLib::ext::shared_ptr< text_sink > & cacheSink()
Definition: log.hpp:300
ProgressLogger(const bool coutLog)
Definition: log.hpp:297
const QuantLib::ext::shared_ptr< file_sink > & fileSink()
Definition: log.hpp:298
const QuantLib::ext::shared_ptr< text_sink > & coutSink()
Definition: log.hpp:299
void setCoutLog(bool flag)
Definition: log.cpp:164
void setFileLog(const std::string &filepath, const boost::filesystem::path &dir, QuantLib::Size rotationSize=0)
Definition: log.cpp:144
QuantLib::ext::shared_ptr< text_sink > cacheSink_
Definition: log.hpp:309
void emitLog() const
generate Boost log record to pass to corresponding sinks
Definition: log.cpp:639
std::string msg() const
return a std::string for the log file
Definition: log.hpp:739
static constexpr const char * name
Definition: log.hpp:736
Stderr Logger.
Definition: log.hpp:164
static const std::string name
the name "StderrLogger"
Definition: log.hpp:167
StderrLogger(bool alertOnly=false)
Constructor.
Definition: log.hpp:173
virtual ~StderrLogger()
Destructor.
Definition: log.hpp:175
virtual void log(unsigned l, const std::string &s) override
The log callback that writes to stderr.
Definition: log.hpp:177
static const std::string name
the name "StructuredLogger"
Definition: log.hpp:318
virtual void removeSinks() override
Destructor.
Definition: log.cpp:221
QuantLib::ext::shared_ptr< file_sink > fileSink_
Definition: log.hpp:328
const QuantLib::ext::shared_ptr< text_sink > & cacheSink()
Definition: log.hpp:322
const QuantLib::ext::shared_ptr< file_sink > & fileSink()
Definition: log.hpp:321
StructuredLogger()
Constructors.
Definition: log.cpp:185
void setFileLog(const std::string &filepath, const boost::filesystem::path &dir, QuantLib::Size rotationSize=0)
Definition: log.cpp:228
QuantLib::ext::shared_ptr< text_sink > cacheSink_
Definition: log.hpp:329
StructuredLoggingErrorMessage(const std::string &exceptionType, const std::string &exceptionWhat="")
Definition: log.hpp:709
StructuredMessage(const Category &category, const Group &group, const std::string &message, const std::pair< std::string, std::string > &subField=std::pair< std::string, std::string >())
Definition: log.hpp:686
void addSubFields(const std::map< std::string, std::string > &)
Definition: log.cpp:594
void emitLog() const
generate Boost log record to pass to corresponding sinks
Definition: log.cpp:576
std::string msg() const
return a std::string for the log file
Definition: log.hpp:695
virtual ~StructuredMessage()
Definition: log.hpp:690
static constexpr const char * name
Definition: log.hpp:692
SafeStack< ValueType > value
oreSeverity
Definition: log.hpp:70
@ notice
Definition: log.hpp:75
@ debug
Definition: log.hpp:76
@ critical
Definition: log.hpp:72
@ data
Definition: log.hpp:77
@ warning
Definition: log.hpp:74
@ memory
Definition: log.hpp:78
@ error
Definition: log.hpp:73
@ alert
Definition: log.hpp:71
#define ORE_DEBUG
Definition: log.hpp:32
std::basic_ostream< CharT, TraitsT > & operator<<(std::basic_ostream< CharT, TraitsT > &strm, oreSeverity lvl)
Outputs stringized representation of the severity level to the stream.
Definition: log.hpp:84
#define ORE_CRITICAL
Definition: log.hpp:28
#define ORE_MEMORY
Definition: log.hpp:34
#define ORE_DATA
Definition: log.hpp:33
#define ORE_NOTICE
Definition: log.hpp:31
#define ORE_ERROR
Definition: log.hpp:29
#define ORE_WARNING
Definition: log.hpp:30
#define ORE_ALERT
Definition: log.hpp:27
std::ostream & operator<<(std::ostream &out, EquityReturnType t)
boost::log::sinks::synchronous_sink< boost::log::sinks::text_ostream_backend > text_sink
Definition: log.hpp:121
boost::log::sinks::synchronous_sink< boost::log::sinks::text_file_backend > file_sink
Definition: log.hpp:120
Serializable Credit Default Swap.
Definition: namespaces.docs:23
Various OS specific utilities.