AAO DRAMA/DRAMA2 C++ Interface
DRAMA C++11 and later interface
logger.hh
Go to the documentation of this file.
1#ifndef _DRAMA2_LOGGER_INC
2#define _DRAMA2_LOGGER_INC
17/*
18 * History:
19 01-Jul-2014 - TJF - Original version
20 11-May-2015 - TJF - Start of history after development.
21 Revert to using Task * instead of shared_ptr<Task>
22 since using the later would not delay the
23 construction of the logger until after the
24 Task constructor has returned, which has its own
25 problems
26 30-Sep-2016 - TJF - DramaCtxMapType now has a pair of item each thread,
27 a string and the drama context, rather then just
28 the drama context. The string is supplied when
29 threads are registered and is output in a new
30 field in the log file.
31
32 * The above ID is for Doxygen, this one has the format ACMM is looking for.
33 * "@(#) $Id$"
34 */
35
36
37// Define to enable the LogStream class - which does not work
38// on some systems. Currently disabled all the time until we understand
39// what is wrong in more detail.
40
41//#define D2_PROVIDE_LOG_STREAM
42
43#include "DitsTypes.h"
44#include "Ers.h"
45#include <iostream>
46#include <fstream>
47#if defined(__GNUC__) && !defined(__clang__)
48#define _DRAMA_HaveGnuFileBufExt
49#define _DRAMA_GnuFileBufExtOnly(_A_) _A_
50#include <ext/stdio_filebuf.h> // __gnu_cxx::stdio_filebuf
51#else
52#define _DRAMA_GnuFileBufExtOnly(_A_) _A_
53#endif
54
55#include <map>
56#include <thread>
57
58/*
59 * Usable log levels.
60 *
61 * When a log call is made, if the "and" of the supplied log level
62 * and the currently enabled log level is non-zero, then the message
63 * is logged.
64 */
65#define D2LOG_ALL 0xFFFFFFFF
66#define D2LOG_STARTUP 0x01
67#define D2LOG_ERRORS 0x02
68#define D2LOG_ACTENT 0x04
69#define D2LOG_ACTEXIT 0x08
70#define D2LOG_INST 0x10
71#define D2LOG_MSG 0x20
72#define D2LOG_DEBUG 0x40
73#define D2LOG_COMMS 0x80
74#define D2LOG_USER1 0x100
75#define D2LOG_USER2 0x200
76#define D2LOG_USER3 0x400
77#define D2LOG_USER4 0x800
78#define D2LOG_ARGS 0x1000
80#define D2LOG_DRAMA2 0x2000
82#define D2LOG_ALWAYS 0x40000
83#define D2LOG_ALWAYS_S 0x80000
87namespace drama {
91 namespace logging {
93 /*
94 * We will have a map of the DRAMA context associated with each thread.
95 */
96 typedef std::map<std::thread::id, std::pair<std::string, Dits___CurActType>> DramaCtxMapType;
97 typedef DramaCtxMapType::iterator DramaCtxMapIter;
98 typedef DramaCtxMapType::const_iterator DramaCtxMapIterConst;
100 class Logger;
102 /*
103 * This object fetches and formats the time. The UpdateTime() function
104 * updates the internal time and TimeToString() returns the formated
105 * time string.
106 */
107 class LogTime {
108
109 private:
110 /*
111 * We keep about the formated time we last used - to avoid doing it
112 * again. We also need the time itself - for which we use a
113 * "long int" to avoid having to include time.h for this module.
114 */
115 long int _LastTime; // Last time we logged at
116 int _millisec; // milliseconds within the second
117 char _timeStr[30]; // Formated time string
119 // User specified offset to apply (for debugging)
120 static long int _s_userTimeOffset;
121
122 public:
123 LogTime();
124
125 /*
126 * Readout the current system time and update the internal time
127 * string. If altTime is non-zero, it is a pointer to a time to use
128 * instead of the current system time.
129 *
130 * If updateInternalTime is true, then the internal value kept for the
131 * last time is updated and the log file changed if appropiate.
132 * Otherwise only the string avialable to TimeString() is updated.
133 * We set this to false if we don't want to change the log file on a
134 * day change.
135 *
136 * day returns the current unix day (since 1 Jan 1970), but only
137 * if the time in seconds has changed in the last call, otherwise
138 * returns set to -1.
139 *
140 */
141 void UpdateTime(bool updateInternalTime,
142 int *day,
143 const IMP_AbsTime *altTime);
144
145 /*
146 * Force UpdateTime to re-read the time on the next read.
147 * This is necessary to force a fetch of the day.
148 */
149 void Reset() {
150 _LastTime = 0;
151 }
152
153 /*
154 * Return the time string.
155 */
156 const char *TimeString() const { return _timeStr; };
157
158 /*
159 * Return the time itself.
160 */
161 long GetTime() const { return _LastTime; };
162 /*
163 * Return the milliseconds point within the second.
164 */
165 int Millisec() const { return _millisec; };
166 /*
167 * Set/Get the current time offset.
168 */
169 static void SetTimeOffset(long int t) { _s_userTimeOffset = t; }
170 static long int GetTimeOffset() { return _s_userTimeOffset; }
171
172
173 ~LogTime();
174
175 }; // class LogTime
176
177 /* LogFileStream is a sub-class of std::ofstream which provides some
178 * special features around the type of file to be used for std::ofstream.
179 *
180 * In particular, it allows us to use a GCC file buffer, which allows
181 * us to to create a file buffer(NOT an iostream yet) from FILE *, so
182 * that we can:
183 *
184 * 1. Access the file descriptor (so we can sync the file to disk)
185 * 2. Wrap up access to a popen() call.
186 *
187 * This is currently GCC specific (what are we to do on the Macs?), but
188 * having these features in a class will allow us to isolate the changes
189 * needed.
190 *
191 * I found how to do this from
192 * http://www.unix.com/programming/151517-porting-ofstream-attach-linux-gcc.html
193 * Proper documentation at
194 * http://gcc.gnu.org/onlinedocs/libstdc++/manual/ext_io.html
195 *
196 * Might only work from libstdc++ 3.1 onwards. Need an equivalent
197 * for CLang (but haven't found one as of 21-May-2015.)
198 */
199 class LogFileStream : public std::ofstream {
200 private:
201#ifdef _DRAMA_HaveGnuFileBufExt
202 /*
203 * Pointer to the gcc stdio_filebuf() object. Non-portable
204 * code - may need to replace with other compilers, e.g. CLang.
205 */
206 std::unique_ptr<__gnu_cxx::stdio_filebuf<char> > _fileBuf;
207 /*
208 * A file pointer, being used when we open with popen().
209 */
210 FILE *_pFile = 0;
211#endif
212
213 public:
214 /* Constructor. Don't open the file with these */
215 LogFileStream() {}
216 /* Destructor */
217 ~LogFileStream();
218 /*
219 * Open the stream as the input to a command - using open().
220 */
221#ifdef _DRAMA_HaveGnuFileBufExt
222 void popen(const std::string &command);
223#endif
224 /*
225 * Open the stream to a file. This is provided so that we
226 * can implement fsync(), below.
227 */
228 void fopen(const std::string &filename);
229
230 /*
231 * Since the file to disk.
232 */
233 void fsync();
234
235 /*
236 * Close the file. Overrides ofstream::open();
237 * For some reason, override flag does not work here.
238 */
239 void close();
240
241#ifdef _DRAMA_HaveGnuFileBufExt
242 /*
243 * Indicate if the file is open. Override ofstream::is_open().
244 * For some reason, override flag does not work here.
245 */
246 bool is_open() const {
247 if (!_fileBuf) return false;
248 return _fileBuf->is_open();
249 }
250 /*
251 * Returns rdbuf - non-standard operation, but we need to override
252 * ofstream::rdbuf.
253 *
254 * For some reason, override flag does not work here.
255 */
256 __filebuf_type* rdbuf() const {
258 "Attempt to call LogBuffer::rdbuf");
259 }
260
261#endif
262
263
264 };
265
266 /*
267 * This class is used by Logger to ensure we have the correct
268 * DRAMA Context (Action/UFACE details) for the current thread.
269 * It is a friend of Logger, as it needs access to items the
270 * general public does not need.
271 *
272 * The constructor must work out if the current thread is the DRAMA
273 * main thread (that invoking RunDrama()) or an otherwise known thread.
274 * If the later, it must switch the DRAMA context to that of the known
275 * thread and reverse that effect when the destructor is run.
276 *
277 * This class implements the Resource Acquisition Is Initialization
278 * design pattern, but is intended to be used for Scope-based Resource
279 * Management only.
280 */
281 class GrabLogContext {
282 bool _onKnownThread = false;
283 bool _onCreateThread = false;
284 bool _onRunThread = false;
285 Dits___CurActType _entryContext;
286 std::string _func;
287 public:
288 GrabLogContext(const Logger &);
289 ~GrabLogContext();
290 // Returns true if this thread has a DRAMA context registered.
291 bool IsKnownThread() const {
292 return _onKnownThread;
293 }
294 // Returns true if this is the thread that created the DRAMA task.
295 bool IsDramaCreateThread() const {
296 return _onCreateThread;
297 }
298 // Returns true if this is the thread that run the DRAMA task.
299 bool IsDramaRunThread() const {
300 return _onRunThread;
301 }
302 // Returns the function name associated withe the thread.
303 std::string FuncName() const {
304 if (_onCreateThread)
305 return "";
306 if (_onRunThread) // No DRAMA creation thread, but am running DRAMA.
307 return "<<::RunDrama>>";
308 if (_onKnownThread)
309 return _func;
310 else
311 return "<<ukn thd fnc>>";
312 }
313 };
314
352 class LogStreamBuf : public std::streambuf {
353
354 private:
355 Logger *_theLogger;
356 std::string _prefix; // Log prefix string.
357 unsigned _level; // Log level we write at.
358
359 protected:
360 // Buffer for messages to output.
361 static const int BUFFER_SIZE = 200;
362 char _buffer[BUFFER_SIZE+1];
363
364 /*
365 * Buffer flush operation. returns number output.
366 */
367 int flushBuffer();
368 /*
369 * Invoked if adding a character would overflow the buffer.
370 * We Add it (since our constructor ensured there is sufficient
371 * space and then flush the buffer.
372 */
373 virtual int_type overflow(int_type c) override {
374 if (c != EOF)
375 {
376 // insert character into buffer
377 *pptr() = c;
378 pbump(1);
380 // flush the buffer
381 if (flushBuffer() == EOF)
382 {
383 return EOF;
384 }
385 return c;
386
387 }
388 /*
389 * Sync the file - just flushes to the log file.
390 */
391 virtual int sync() override {
392 if (flushBuffer() == EOF) {
393 return -1;
394 }
395 return 0;
396 }
397
398 public:
405 LogStreamBuf(Logger *theLogger, unsigned level, const std::string &prefix) :
406 _theLogger(theLogger),
407 _prefix(prefix),
408 _level(level) {
409 /*
410 * Need to provide our buffer to the std::Streambuf base
411 * class. One character less to ensure the last character
412 * causes an overflow.
413 */
414 setp(_buffer, _buffer+(BUFFER_SIZE-1));
415 }
420 virtual ~LogStreamBuf() {
421 /*
422 * We want to output what is left, but any exception now
423 * (which may be caused by DRAMA failing to send the message
424 * for various reasons), if left uncaught, will cause the
425 * program to crash (can't throw from destructors), so
426 * catch any DRAMA exception and use stderr.
427 */
428 try
429 {
430 sync();
431 }
433 {
434 fprintf(stderr,"DRAMA Exception thrown by drama::~LogStreamBuf()\n");
435 fprintf(stderr,"%s\n", e.toString().c_str());
436 fprintf(stderr,"DRAMA Status = 0x%lX, %s\n",
437 static_cast<long int>(e.dramaStatus()),
438 e.dramaStatusStr().c_str());
439
440 }
441 }
442
443
450 LogStreamBuf(const LogStreamBuf &source) = delete;
451
460 LogStreamBuf& operator = (const LogStreamBuf &rhs) = delete;
461
468 LogStreamBuf(LogStreamBuf &&source) noexcept :
469 _theLogger(source._theLogger),
470 _prefix(source._prefix),
471 _level(source._level) {
472 source._theLogger = nullptr;
473 }
474
475
483 LogStreamBuf& operator=(LogStreamBuf &&rhs) noexcept {
484
485 this->_theLogger = rhs._theLogger;
486 this->_level = rhs._level;
487 this->_prefix = std::move(rhs._prefix);
488
489 rhs._theLogger = nullptr;
490 return *this;
491 }
492
493
494
495 }; //class LogStreamBuf
496
497#ifdef D2_PROVIDE_LOG_STREAM // Currently disabled. Does not work under CLang compiler, unclear why
498
499// LogStream not working under CLang, later versions. unclear why, but
500// appears related to copy/assignment. tocker would crash when
501// attempting to use a LogStream created by CreateLogStream() below.
502
530 class LogStream : public std::ostream {
531 friend class Logger;
532 private:
533 LogStreamBuf _buf;
534 /* Construct a LogStream object.
535 *
536 * Private since only normally constructed by the Logger object
537 * CreateLogStream() method.
538 *
539 * @param theLogger A pointer to the DRAMA logger object
540 * @param level The level at which the events will be written
541 * @param prefix The prefix for the log messages.
542 */
543 LogStream(Logger *theLogger, unsigned level, const std::string &prefix) :
544 _buf(theLogger, level, prefix) {
545 /*
546 * Set the buffer address for ostream.
547 */
548 rdbuf(&_buf);
549 }
550
551 public:
558 LogStream(const LogStream &source) = delete;
559
567 LogStream& operator = (const LogStream &rhs) = delete;
568
573 LogStream(LogStream &&source) noexcept : _buf(std::move(source._buf)){ }
574
575
580 LogStream& operator=(LogStream &&rhs) noexcept {
581
582 _buf = std::move(rhs._buf);
583 return *this;
584 }
585
586
587 }; //class LogStream.
588#endif
589
590
742 class Logger {
743
744 friend class GrabLogContext;
745 private:
746 /*
747 * This internal object is used to fetch and format the time.
748 */
749 LogTime _timer;
750
751
752 /* Structure used to maintain level names */
753 typedef struct {
754 int minsig; unsigned level; const char *string;
755 } LevelStruct;
756
757 /* Translations of various codes to strings */
758 static const LevelStruct _s_LevelNames[];
759 static const char *_s_RescheduleReasons[];
760 static const char *_s_Requests[];
761 static const char *_s_PathStatus[];
762 static const char *_s_MessageTypes[];
763
764 /* Maximum length of messages */
765 static const int _s_MsgLen;
766
767 /* Current Logging levels.*/
768 unsigned _currentLevels =
770
771
772 /*
773 * If we true,then logging of MsgOut messages is disabled. Used when
774 * we want to output something to the screen but not to the log file.
775 */
776 bool _disableMsgOut = false;
777
778 /* Log file stream and name. */
779 LogFileStream _logFile;
780 //std::ofstream _logFile;
781 std::string _logFileName;
782
783 /*
784 * LogDay contain the day number in the year. We use it to work
785 * out if the day has changed.
786 */
787 int _logDay = 0;
788
789 /*
790 * Pointer to the DRAMA task we are part of.
791 * The pointer is const - we never change it after the constructor.
792 * The task pointed to is NOT const - since we can operate on it.
793 */
794 Task * const _theTask;
795 /*
796 * Directory and system names supplied to constructor.
797 */
798 std::string _directory;
799 std::string _system;
800 /*
801 * Set true to always flush the log file.
802 */
803 bool _flushAlways = false;
804 /*
805 * Set true to turn of fsync() operation when flushing
806 */
807 bool _noFsync = false;
808 /*
809 * Set true to disable LogFlush()
810 */
811 bool _noLogFlush = false;
812 /*
813 * Set true when the log is flushed, cleared when messages
814 * are written.
815 */
816 bool _flushed = false;
817
818 /*
819 * Last write to log file failed.
820 */
821 bool _failed = false;
822 /*
823 * Are we compressing data on the fly)
824 */
825 bool _compress = false;
826 FILE *_compressFD = nullptr;
827 /*
828 * This variable records the approximate file size - in particular,
829 * the amount of data we have written to the file using
830 * Logger::LogMessage(), the core logging routine. It does not
831 * record various bits of header information.
832 *
833 * We use this allow us to create a new log file every 512 MB - to
834 * avoid file system file size problems which occur at about 1 GB on
835 * older file systems..
836 */
837 INT32 _fileSize = 0;
838
839 /*
840 * Should we add a column with the thread ID. This makes
841 * us incompatible with GIT Logger.
842 */
843 bool _logThreadID = false;
844 /*
845 * A MAP of thread to DRAMA context. Allows us to find the
846 * appropriate DRAMA context information for any registered
847 * thread - register threads with the RegisterThread() method.
848 */
849 DramaCtxMapType _threadToDRAMAContextMap;
850 /*
851 * The ID of the main thread - the one that created the logger
852 * (should be the thread running the DRAMA task).
853 */
854 std::thread::id _mainThreadId;
855 /*
856 * Used to actually sync the log file.
857 */
858 void SyncFile(const char *from_where);
859
860 /*
861 * We need a static routine to implement the log level action
862 * which can then call the object routine Action.
863 */
864 static void LogLevelAction(StatusType *status);
865 void Action(StatusType *status);
866
867 /*
868 * Methods supporting the constructor and the Open() method.
869 */
870 void CreateLogLevelAction(StatusType *status);
871 void CreateParameters(StatusType *status);
872 void InitialiseLogLevel(StatusType *status);
873 void LogTaskVersionInfo();
874
875 /*
876 * static routines which are passed to DRAMA to implement the
877 * DRAMA logging system. See DitsSetLogSys().
878 */
879 static DVOID ActionEntryLog(DVOIDP client_data,StatusType *status);
880 static DVOID ActionReturnLog(
882 int argDelete,
885 int delaySet,
889 static DVOID GetPathLog(
891 DCONSTV char * name,
892 DCONSTV char * node,
893 int flags,
895 DitsPathType path,
898 static DVOID MsgSendLog(
900 long int flags,
901 DitsPathType path,
905 static DVOID LoadLog(
907 DCONSTV char * Machine,
908 DCONSTV char * TaskName,
909 DCONSTV char * ArgString,
910 long int Flags,
914 static DVOID NotifyReqLog(
916 int notifyRequested,
917 DitsPathType path,
920 static DVOID MsgOutLog(
922 DCONSTV char * message,
924 static DVOID LogMsgLog(
926 unsigned level,
927 DCONSTV char * prefix,
928 DCONSTV char * fmt,
929 va_list ap,
931
932 static DVOID LogTrigger(
934 SdsIdType arg,
936
937 static DVOID LogTrigBulk(
940 int sds,
941 int NotifyBytes,
944
945 static DVOID LogSignal(
947 long int actptr,
948 DCONSTV DVOIDP ptr,
949 SdsIdType arg,
951
952 static DVOID LogBulkSend(
954 DCONSTV long int flags,
957 int NotifyBytes,
960 StatusType * status);
961
962
965 static DVOID LogShutdown(
967 int taskShutdown,
969
970 static DVOID LogFlush(DVOIDP client_data, StatusType *status);
971 static DVOID LogInfo(DVOIDP client_data, StatusType *status);
972
973
974 /*
975 * The actual routine which logs to the file etc. If altTime is
976 * specified, then the log message is taged with that time, otherwise
977 * it is tagged with the current time
978 */
979 void LogMessage(const char *prefix,
980 const char *message,
981 const IMP_AbsTime *altTime=0);
982
983
984 /*
985 * Methods to set the logging levels from a string.
986 */
987 void SetLevels(const std::string &s, StatusType *status);
988
989 /* Methods to fetch logging levels. */
990 std::string GetLevels() const;
991
992 /* Support function for GetLevels */
993 void LevelCheckAndAdd(unsigned index, std::string *s) const;
994
995 void OpenLogFile(bool day_rollover, bool size);
996 void OpenIt(const std::string &BaseLogFileName);
997 /* Check if the file size has got too large */
998 void CheckFileSize();
999
1000 /* Check if we should use compress mode */
1001 void CheckCompressMode();
1002 /* Close log file */
1003 void CloseLogFile();
1004
1005 /* Create a new log file name */
1006 static std::string NewName(const std::string &BaseLogFileName, int counter);
1007
1008 /* Has a log file named already been used */
1009 static bool NameUsed(const std::string &name);
1010
1011 /* Check if the day has changed. If it has, reopen the log file for
1012 * the new day.
1013 */
1014 void CheckDayChange(int newDay);
1015
1016 /*
1017 * Assignment operation and Copy constructor deleted
1018 * to avoid misuse.
1019 */
1020 void operator=(const Logger&) = delete;
1021 Logger(const Logger&) = delete;
1022
1023
1024 /*
1025 * A class used to temporally disable MsgOut logging.
1026 *
1027 * This class implements the Resource Acquisition Is Initialization
1028 * design pattern, but is intended to be used for Scope-based Resource
1029 * Management only.
1030 */
1031 class MsgOutNoLog {
1032 private:
1033 Logger *_theLogger;
1034 bool _previousState;
1035 public:
1036 MsgOutNoLog(Logger *theLogger) :
1037 _theLogger(theLogger),
1038 _previousState(theLogger->_disableMsgOut) {
1039 theLogger->_disableMsgOut = true;
1040 }
1041 ~MsgOutNoLog() {
1042 _theLogger->_disableMsgOut = _previousState;;
1043 }
1044 };
1045
1046 public:
1047
1061 Logger(Task * dramaTask);
1081 void Open(const std::string &system,
1082 const std::string &dir="",
1083 bool compress=false);
1084
1085
1094 ~Logger();
1095
1096
1097
1106 static void SetTimeOffset(long int t){LogTime::SetTimeOffset(t); }
1107
1123 void Log(unsigned level, bool nofmt, const char *prefix,
1124 const char *fmt, ...)
1125#ifdef __GNUC__
1126 __attribute__ ((format (printf, 5, 6))) /* Note, method version of __attribute__ needs 1 added to each argument over non-method version. */
1127#endif
1128 ;
1129
1130
1151 template<typename... Types>
1152 void SLog(unsigned level, const std::string &prefix,
1153 const std::string &fmt, Types... args) {
1154 /*
1155 * Our approach is to write the output to a string, via
1156 * SafePrintf(), then output that in one operation.
1157 */
1158 std::stringstream sstrm;
1159 drama::SafePrintf(sstrm, fmt.c_str(), args...);
1160 DGCC_DIAG_OFF(format-security) // Since formating disabled, no problem
1161 Log(level, true, prefix.c_str(), sstrm.str().c_str());
1163
1164 }
1192 template<typename... Types>
1193 void SLog( std::ostream &ostream,
1194 unsigned level, const std::string &prefix,
1195 const std::string &fmt, Types... args) {
1196 /*
1197 * Our approach is to write the output to a string, via
1198 * SafePrintf(), then output that in one operation.
1199 */
1200 std::stringstream sstrm;
1201 drama::SafePrintf(sstrm, fmt.c_str(), args...);
1202 Log(level, true, prefix.c_str(), sstrm.str().c_str());
1203
1204 ostream << sstrm.str() << std::endl;
1205 }
1206
1233 void Log(const IMP_AbsTime *time,
1234 unsigned level, bool nofmt, const char *prefix,
1235 const char *fmt, ...)
1236#ifdef __GNUC__
1237 __attribute__ ((format (printf, 6, 7)))
1238#endif
1239 ;
1240
1246 void Set(unsigned newLevels);
1247
1253 void Unset(unsigned disableLevels);
1254
1277 std::thread::id threadId=std::this_thread::get_id(),
1278 const char* func = "*unnamed func*");
1298 void RegisterThread(std::thread::id threadId=std::this_thread::get_id(),
1299 const char* func = "*unamed func*");
1300
1301
1325 void RegisterThread(std::thread::id sourceThread,
1326 std::thread::id newThread,
1327 const char* func = "*unnamed func*");
1328
1329
1330
1345 std::weak_ptr<Task> dramaTask,
1346 const char* func = "*non-drama*");
1347
1348
1349
1350#ifdef D2_PROVIDE_LOG_STREAM // Currently disabled.
1351// Not working under CLANG - Mac ElCapitan and Serria.
1352// Problem with copy/assignment in LogStream!!!! (I think).
1372 const std::string &prefix) {
1373 return LogStream(this, level, prefix);
1374 }
1375#endif
1376
1377 }; // class Logger
1378
1379
1380
1381
1382 } // namespace logging
1383
1384} // namespace drama
1385
1386#endif
An Exception class for exceptions thrown by DRAMA V2 classes.
Definition exception.hh:164
A class which implements a DRAMA task.
Definition task.hh:441
LogStreamBuf & operator=(LogStreamBuf &&rhs) noexcept
Move assignment operator.
Definition logger.hh:510
LogStreamBuf(Logger *theLogger, unsigned level, const std::string &prefix)
Construct a LogStreamBuf object.
Definition logger.hh:432
LogStreamBuf(const LogStreamBuf &source)=delete
Copy constructor - deleted.
virtual ~LogStreamBuf()
Destroy the LogStreamBuf, any remaining output is sent.
Definition logger.hh:447
LogStreamBuf(LogStreamBuf &&source) noexcept
Move copy constructor.
Definition logger.hh:495
LogStreamBuf & operator=(const LogStreamBuf &rhs)=delete
Assignment operator - deleted.
Implement a streambuf sub-class that can write messages via the DRAMA Logger interface.
Definition logger.hh:379
void Set(unsigned newLevels)
Enable new logging levels.
void RegisterThread(const Dits___CurActType &dramaContext, std::thread::id threadId=std::this_thread::get_id(), const char *func="*unnamed func*")
Register the DRAMA context of a thread.
void RegisterThread(std::thread::id threadId=std::this_thread::get_id(), const char *func="*unamed func*")
Register the current DRAMA context against a thread.
void RegisterThread(std::thread::id sourceThread, std::thread::id newThread, const char *func="*unnamed func*")
Register the DRAMA context of one thread against a new thread.
static void SetTimeOffset(long int t)
Change the time offset.
Definition logger.hh:1133
void SLog(std::ostream &ostream, unsigned level, const std::string &prefix, const std::string &fmt, Types... args)
Log a message using type safe formatting and output to a stream.
Definition logger.hh:1220
void SLog(unsigned level, const std::string &prefix, const std::string &fmt, Types... args)
Log a message using type safe formatting.
Definition logger.hh:1179
Logger(Task *dramaTask)
Construct a drama::logging::Logger object.
void Open(const std::string &system, const std::string &dir="", bool compress=false)
Open the log file.
void Log(const IMP_AbsTime *time, unsigned level, bool nofmt, const char *prefix, const char *fmt,...)
Log a message with a specified event time.
void Unset(unsigned disableLevels)
Clear particular logging levels.
void Log(unsigned level, bool nofmt, const char *prefix, const char *fmt,...)
Log a message using C printf formating.
void RegisterThreadNoDramaCtx(std::weak_ptr< Task > dramaTask, const char *func="*non-drama*")
Register this thread with with the logger, but without a DRAMA context.
Implementation of a Class supporting Logging within an AAO DRAMA Task.
Definition logger.hh:769
#define DramaTHROW(status_, message_)
Throw a Drama exception.
Definition exception.hh:93
#define D2LOG_ALWAYS
Always log the message.
Definition logger.hh:109
#define D2LOG_ALWAYS_S
Always log the messages, including to the screen.
Definition logger.hh:110
#define D2LOG_ERRORS
Log Ers and action completion errors.
Definition logger.hh:94
#define D2LOG_MSG
Log MsgOut messages.
Definition logger.hh:98
void CreateRunDramaTask()
Create and run a DRAMA task, with standard exception handling.
Definition task.hh:1322
void SafePrintf(std::ostream &ostream, const char *str)
Safe formatted write to a stream.
The drama namespace contains all the classes, types etc of the DRAMA 2 implementation.
Definition drama.hh:93