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=
"",
1150#ifndef RUNNING_DOXYGEN
1151 D2_FMT_DEPRECATED(
"Replace Log() by LogF() (or LogNF()). See MessageUserF() page for details on the former.")
1154 const char *fmt, ...)
1206 void LogNF(std::ostream &ostream,
unsigned level,
const std::string &
prefix,
const std::string &
message) {
1236 template<
typename...
Types>
1237#ifndef RUNNING_DOXYGEN
1238 D2_FMT_DEPRECATED(
"Replace SLog() by LogF(). See MessageUserF() page for details.")
1240 void SLog(
unsigned level,
const std::string &
prefix,
1241 const std::string &fmt,
Types...
args) {
1246 std::stringstream
sstrm;
1281 template<
typename...
Types>
1282#ifndef RUNNING_DOXYGEN
1283 D2_FMT_DEPRECATED(
"Replace SLog() by LogF(). See MessageUserF() page for details.")
1285 void SLog( std::ostream &ostream,
1286 unsigned level,
const std::string &
prefix,
1287 const std::string &fmt,
Types...
args) {
1292 std::stringstream
sstrm;
1296 ostream <<
sstrm.str() << std::endl;
1315 template<
typename...
Args>
1316 void LogF(
unsigned level,
1317 const std::string &
prefix,
1318 const fmt::format_string<Args...> fmt,
1322 fmt::vformat(fmt.get(), fmt::make_format_args(
args...)));
1362 template<
typename...
Args>
1363 void LogF( std::ostream &ostream,
1365 const std::string &
prefix,
1366 const fmt::format_string<Args...> fmt,
1370 auto logMessage = fmt::vformat(fmt.get(), fmt::make_format_args(
args...));
1404 const char *fmt, ...)
1446 std::thread::id
threadId=std::this_thread::get_id(),
1447 const char*
func =
"*unnamed func*");
1468 const char*
func =
"*unamed func*");
1496 const char*
func =
"*unnamed func*");
1515 const char*
func =
"*non-drama*");
1529#ifdef D2_PROVIDE_LOG_STREAM
1551 const std::string &
prefix) {
An Exception class for exceptions thrown by DRAMA V2 classes.
Definition exception.hh:183
A class which implements a DRAMA task.
Definition task.hh:452
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 LogNF(unsigned level, const std::string &prefix, const std::string &message)
Log a message using, no formatting.
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:1312
void LogF(std::ostream &ostream, unsigned level, const std::string &prefix, const fmt::format_string< Args... > fmt, Args &&... args)
Log a message sing with fmt::format string formatting and also output to a stream.
Definition logger.hh:1390
void SLog(unsigned level, const std::string &prefix, const std::string &fmt, Types... args)
Log a message using type safe formatting.
Definition logger.hh:1267
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:1552
void LogF(unsigned level, const std::string &prefix, const fmt::format_string< Args... > fmt, Args &&... args)
Log a message using with fmt::format string formatting.
Definition logger.hh:1343
void Log(unsigned level, bool nofmt, const char *prefix, const char *fmt,...)
Log a message using C printf formatting.
void RegisterThreadNoDramaCtx(std::weak_ptr< Task > dramaTask, const char *func="*non-drama*")
Register this thread with with the logger, but without a DRAMA context.
void LogNF(std::ostream &ostream, unsigned level, const std::string &prefix, const std::string &message)
Log a message using, no formatting.
Definition logger.hh:1233
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:90
#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:1339
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:99