1#ifndef _DRAMA2_LOGGER_INC
2#define _DRAMA2_LOGGER_INC
47#if defined(__GNUC__) && !defined(__clang__)
48#define _DRAMA_HaveGnuFileBufExt
49#define _DRAMA_GnuFileBufExtOnly(_A_) _A_
50#include <ext/stdio_filebuf.h>
52#define _DRAMA_GnuFileBufExtOnly(_A_) _A_
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
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
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;
120 static long int _s_userTimeOffset;
156 const char *TimeString()
const {
return _timeStr; };
161 long GetTime()
const {
return _LastTime; };
165 int Millisec()
const {
return _millisec; };
169 static void SetTimeOffset(
long int t) { _s_userTimeOffset =
t; }
170 static long int GetTimeOffset() {
return _s_userTimeOffset; }
199 class LogFileStream :
public std::ofstream {
201#ifdef _DRAMA_HaveGnuFileBufExt
206 std::unique_ptr<__gnu_cxx::stdio_filebuf<char> >
_fileBuf;
221#ifdef _DRAMA_HaveGnuFileBufExt
228 void fopen(
const std::string &
filename);
241#ifdef _DRAMA_HaveGnuFileBufExt
258 "Attempt to call LogBuffer::rdbuf");
281 class GrabLogContext {
282 bool _onKnownThread =
false;
283 bool _onCreateThread =
false;
284 bool _onRunThread =
false;
288 GrabLogContext(
const Logger &);
291 bool IsKnownThread()
const {
292 return _onKnownThread;
295 bool IsDramaCreateThread()
const {
296 return _onCreateThread;
299 bool IsDramaRunThread()
const {
303 std::string FuncName()
const {
307 return "<<::RunDrama>>";
311 return "<<ukn thd fnc>>";
362 class LogStreamBuf :
public std::streambuf {
371 static const int BUFFER_SIZE = 200;
372 char _buffer[BUFFER_SIZE+1];
391 if (flushBuffer() ==
EOF)
402 virtual int sync()
override {
403 if (flushBuffer() ==
EOF) {
430 setp(_buffer, _buffer+(BUFFER_SIZE-1));
432 void Debug(
const char *
where) {
433 fprintf(
stderr,
"LogStreamBuf(%s):object 0x%p, logger 0x%p, prefix %s, levels %u\n",
434 where, (
void *)(
this), (
void *)(_theLogger), _prefix.c_str(), _level);
455 fprintf(
stderr,
"DRAMA Exception thrown by drama::~LogStreamBuf()\n");
458 static_cast<long int>(
e.dramaStatus()),
459 e.dramaStatusStr().c_str());
471 LogStreamBuf(
const LogStreamBuf &
source) =
delete;
490 _theLogger(
source._theLogger),
493 source._theLogger =
nullptr;
506 this->_theLogger =
rhs._theLogger;
507 this->_level =
rhs._level;
508 this->_prefix = std::move(
rhs._prefix);
510 rhs._theLogger =
nullptr;
518#ifdef D2_PROVIDE_LOG_STREAM
564 LogStream(
Logger *theLogger,
unsigned level,
const std::string &prefix) :
565 _buf(theLogger, level, prefix) {
579 LogStream(
const LogStream &source) =
delete;
588 LogStream& operator = (
const LogStream &rhs) =
delete;
594 LogStream(LogStream &&source) noexcept : _buf(std::move(source._buf)){ }
601 LogStream& operator=(LogStream &&rhs)
noexcept {
603 _buf = std::move(rhs._buf);
765 friend class GrabLogContext;
775 int minsig;
unsigned level;
const char *string;
779 static const LevelStruct _s_LevelNames[];
780 static const char *_s_RescheduleReasons[];
781 static const char *_s_Requests[];
782 static const char *_s_PathStatus[];
783 static const char *_s_MessageTypes[];
786 static const int _s_MsgLen;
789 unsigned _currentLevels =
797 bool _disableMsgOut =
false;
800 LogFileStream _logFile;
802 std::string _logFileName;
815 Task *
const _theTask;
819 std::string _directory;
824 bool _flushAlways =
false;
828 bool _noFsync =
false;
832 bool _noLogFlush =
false;
837 bool _flushed =
false;
842 bool _failed =
false;
846 bool _compress =
false;
847 FILE *_compressFD =
nullptr;
864 bool _logThreadID =
false;
870 DramaCtxMapType _threadToDRAMAContextMap;
875 std::thread::id _mainThreadId;
894 void LogTaskVersionInfo();
901 static DVOID ActionReturnLog(
910 static DVOID GetPathLog(
919 static DVOID MsgSendLog(
926 static DVOID LoadLog(
935 static DVOID NotifyReqLog(
941 static DVOID MsgOutLog(
945 static DVOID LogMsgLog(
953 static DVOID LogTrigger(
958 static DVOID LogTrigBulk(
966 static DVOID LogSignal(
973 static DVOID LogBulkSend(
986 static DVOID LogShutdown(
1000 void LogMessage(
const char *
prefix,
1011 std::string GetLevels()
const;
1014 void LevelCheckAndAdd(
unsigned index, std::string *
s)
const;
1019 void CheckFileSize();
1022 void CheckCompressMode();
1024 void CloseLogFile();
1030 static bool NameUsed(
const std::string &name);
1035 void CheckDayChange(
int newDay);
1041 void operator=(
const Logger&) =
delete;
1055 bool _previousState;
1059 _previousState(
theLogger->_disableMsgOut) {
1063 _theLogger->_disableMsgOut = _previousState;;
1103 const std::string &
dir=
"",
1145 const char *
fmt, ...)
1172 template<
typename...
Types>
1173 void SLog(
unsigned level,
const std::string &
prefix,
1179 std::stringstream
sstrm;
1213 template<
typename...
Types>
1214 void SLog( std::ostream &ostream,
1215 unsigned level,
const std::string &
prefix,
1221 std::stringstream
sstrm;
1225 ostream <<
sstrm.str() << std::endl;
1256 const char *
fmt, ...)
1298 std::thread::id
threadId=std::this_thread::get_id(),
1299 const char*
func =
"*unnamed func*");
1320 const char*
func =
"*unamed func*");
1348 const char*
func =
"*unnamed func*");
1367 const char*
func =
"*non-drama*");
1381#ifdef D2_PROVIDE_LOG_STREAM
1403 const std::string &
prefix) {
An Exception class for exceptions thrown by DRAMA V2 classes.
Definition exception.hh:162
A class which implements a DRAMA task.
Definition task.hh:446
LogStreamBuf & operator=(LogStreamBuf &&rhs) noexcept
Move assignment operator.
Definition logger.hh:531
LogStreamBuf(Logger *theLogger, unsigned level, const std::string &prefix)
Construct a LogStreamBuf object.
Definition logger.hh:448
LogStreamBuf(const LogStreamBuf &source)=delete
Copy constructor - deleted.
virtual ~LogStreamBuf()
Destroy the LogStreamBuf, any remaining output is sent.
Definition logger.hh:467
LogStreamBuf(LogStreamBuf &&source) noexcept
Move copy constructor.
Definition logger.hh:516
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:389
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:1154
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:1241
void SLog(unsigned level, const std::string &prefix, const std::string &fmt, Types... args)
Log a message using type safe formatting.
Definition logger.hh:1200
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.
Task * GetTask()
Return the DRAMA task associated with the logger.
Definition logger.hh:1404
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:790
#define DramaTHROW(status_, message_)
Throw a Drama exception.
Definition exception.hh:87
#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:1327
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