\doxysection{Log.\+hpp}
\hypertarget{Log_8hpp_source}{}\label{Log_8hpp_source}\index{/home/chr/devel/PhD/Environment/pub/PCBEnv/pcbenv/cxx/Log.hpp@{/home/chr/devel/PhD/Environment/pub/PCBEnv/pcbenv/cxx/Log.hpp}}

\begin{DoxyCode}{0}
\DoxyCodeLine{00001\ }
\DoxyCodeLine{00002\ \textcolor{preprocessor}{\#ifndef\ GYM\_PCB\_LOG\_H}}
\DoxyCodeLine{00003\ \textcolor{preprocessor}{\#define\ GYM\_PCB\_LOG\_H}}
\DoxyCodeLine{00004\ }
\DoxyCodeLine{00005\ \textcolor{preprocessor}{\#include\ <iomanip>}}
\DoxyCodeLine{00006\ \textcolor{preprocessor}{\#include\ <chrono>}}
\DoxyCodeLine{00007\ \textcolor{preprocessor}{\#include\ <fstream>}}
\DoxyCodeLine{00008\ \textcolor{preprocessor}{\#include\ <sstream>}}
\DoxyCodeLine{00009\ \textcolor{preprocessor}{\#include\ <set>}}
\DoxyCodeLine{00010\ \textcolor{preprocessor}{\#include\ <string>}}
\DoxyCodeLine{00011\ \textcolor{preprocessor}{\#include\ <thread>}}
\DoxyCodeLine{00012\ }
\DoxyCodeLine{00013\ \textcolor{keyword}{enum\ class}\ LogLevel}
\DoxyCodeLine{00014\ \{}
\DoxyCodeLine{00015\ \ \ \ \ ERROR\ =\ 0,}
\DoxyCodeLine{00016\ \ \ \ \ WARNING\ =\ 1,}
\DoxyCodeLine{00017\ \ \ \ \ NOTICE\ =\ 2,}
\DoxyCodeLine{00018\ \ \ \ \ INFO\ =\ 3,}
\DoxyCodeLine{00019\ \ \ \ \ DEBUG\ =\ 4,}
\DoxyCodeLine{00020\ \ \ \ \ TRACE\ =\ 5,}
\DoxyCodeLine{00021\ \ \ \ \ COUNT\ =\ 6}
\DoxyCodeLine{00022\ \};}
\DoxyCodeLine{00023\ }
\DoxyCodeLine{00024\ \textcolor{preprocessor}{\#ifndef\ GYM\_PCB\_MAX\_LOG\_LEVEL}}
\DoxyCodeLine{00025\ \textcolor{preprocessor}{\#define\ GYM\_PCB\_MAX\_LOG\_LEVEL\ 3}}
\DoxyCodeLine{00026\ \textcolor{preprocessor}{\#endif}}
\DoxyCodeLine{00027\ \textcolor{preprocessor}{\#ifndef\ GYM\_PCB\_LOG\_SHOW\_THREAD}}
\DoxyCodeLine{00028\ \textcolor{preprocessor}{\#define\ GYM\_PCB\_LOG\_SHOW\_THREAD\ 0}}
\DoxyCodeLine{00029\ \textcolor{preprocessor}{\#endif}}
\DoxyCodeLine{00030\ \textcolor{preprocessor}{\#ifndef\ GYM\_PCB\_LOG\_FORMAT\_TIME}}
\DoxyCodeLine{00031\ \textcolor{preprocessor}{\#define\ GYM\_PCB\_LOG\_FORMAT\_TIME\ 1}}
\DoxyCodeLine{00032\ \textcolor{preprocessor}{\#endif}}
\DoxyCodeLine{00033\ }
\DoxyCodeLine{00034\ \textcolor{preprocessor}{\#define\ \_PCB\_GYM\_LOG\_IF(v,\ func,\ args...)\ if\ (int(v)\ <=\ GYM\_PCB\_MAX\_LOG\_LEVEL\ \&\&\ Logger::get().visible(v))\ \{\ std::stringstream\ \_\_\_ss;\ \_\_\_ss\ <<\ args;\ Logger::get().func(\_\_\_ss.str());\ \}}}
\DoxyCodeLine{00035\ }
\DoxyCodeLine{00036\ \textcolor{preprocessor}{\#define\ ERROR(args...)\ \ do\ \{\ \_PCB\_GYM\_LOG\_IF(LogLevel::ERROR,\ Error,\ args)\ \}\ while\ (0)}}
\DoxyCodeLine{00037\ \textcolor{preprocessor}{\#define\ WARN(args...)\ \ \ do\ \{\ \_PCB\_GYM\_LOG\_IF(LogLevel::WARNING,\ Warn,\ args)\ \}\ while\ (0)}}
\DoxyCodeLine{00038\ \textcolor{preprocessor}{\#define\ INFO(args...)\ \ \ do\ \{\ \_PCB\_GYM\_LOG\_IF(LogLevel::INFO,\ Info,\ args)\ \}\ while\ (0)}}
\DoxyCodeLine{00039\ \textcolor{preprocessor}{\#define\ NOTICE(args...)\ do\ \{\ \_PCB\_GYM\_LOG\_IF(LogLevel::NOTICE,\ Notice,\ args)\ \}\ while\ (0)}}
\DoxyCodeLine{00040\ \textcolor{preprocessor}{\#define\ DEBUG(args...)\ \ do\ \{\ \_PCB\_GYM\_LOG\_IF(LogLevel::DEBUG,\ Debug,\ args)\ \}\ while\ (0)}}
\DoxyCodeLine{00041\ \textcolor{preprocessor}{\#define\ TRACE(args...)\ \ do\ \{\ \_PCB\_GYM\_LOG\_IF(LogLevel::TRACE,\ Trace,\ args)\ \}\ while\ (0)}}
\DoxyCodeLine{00042\ }
\DoxyCodeLine{00043\ \textcolor{preprocessor}{\#define\ RETURN\_ERROR(rv,\ args...)\ do\ \{\ ERROR(args);\ return\ rv;\ \}\ while\ (0)}}
\DoxyCodeLine{00044\ }
\DoxyCodeLine{00045\ \textcolor{keyword}{class\ }\mbox{\hyperlink{classLogFile}{LogFile}}}
\DoxyCodeLine{00046\ \{}
\DoxyCodeLine{00047\ \textcolor{keyword}{public}:}
\DoxyCodeLine{00048\ \ \ \ \ \textcolor{keyword}{constexpr}\ \textcolor{keyword}{static}\ \textcolor{keyword}{const}\ std::size\_t\ MaxSize\ =\ 32ull\ <<\ 20;}
\DoxyCodeLine{00049\ \textcolor{keyword}{public}:}
\DoxyCodeLine{00050\ \ \ \ \ std::ostream\&\ stream()\ \{\ \textcolor{keywordflow}{return}\ *mStream;\ \}}
\DoxyCodeLine{00051\ \ \ \ \ \textcolor{keyword}{const}\ std::string\&\ getPath()\textcolor{keyword}{\ const\ }\{\ \textcolor{keywordflow}{return}\ mPath;\ \}}
\DoxyCodeLine{00052\ \ \ \ \ \textcolor{keywordtype}{void}\ setPath(\textcolor{keyword}{const}\ std::string\_view);}
\DoxyCodeLine{00053\ \ \ \ \ \textcolor{keywordtype}{void}\ redirect(\mbox{\hyperlink{classLogFile}{LogFile}}\&);}
\DoxyCodeLine{00054\ \ \ \ \ \textcolor{keywordtype}{bool}\ isOwner()\textcolor{keyword}{\ const\ }\{\ \textcolor{keywordflow}{return}\ mOwner\ ==\ \textcolor{keyword}{this};\ \}}
\DoxyCodeLine{00055\ \ \ \ \ \mbox{\hyperlink{classLogFile}{LogFile}}\ *owner()\textcolor{keyword}{\ const\ }\{\ \textcolor{keywordflow}{return}\ mOwner;\ \}}
\DoxyCodeLine{00056\ \ \ \ \ \textcolor{keywordtype}{void}\ ownFile();}
\DoxyCodeLine{00057\ \ \ \ \ \textcolor{keywordtype}{void}\ updateOwner();}
\DoxyCodeLine{00058\ \textcolor{keyword}{private}:}
\DoxyCodeLine{00059\ \ \ \ \ std::ostream\ *mStream\{0\};}
\DoxyCodeLine{00060\ \ \ \ \ std::string\ mPath;}
\DoxyCodeLine{00061\ \ \ \ \ std::ofstream\ mFile;}
\DoxyCodeLine{00062\ \ \ \ \ \mbox{\hyperlink{classLogFile}{LogFile}}\ *mOwner\{0\};}
\DoxyCodeLine{00063\ \textcolor{keyword}{private}:}
\DoxyCodeLine{00064\ \ \ \ \ \textcolor{keywordtype}{void}\ open(\textcolor{keyword}{const}\ std::string\_view\ path);}
\DoxyCodeLine{00065\ \ \ \ \ \textcolor{keywordtype}{void}\ shut(\textcolor{keyword}{const}\ std::string\_view\ path\ =\ \textcolor{stringliteral}{"{}cerr"{}});}
\DoxyCodeLine{00066\ \ \ \ \ \textcolor{keywordtype}{void}\ truncate(\textcolor{keyword}{const}\ std::string\_view\ path);}
\DoxyCodeLine{00067\ \};}
\DoxyCodeLine{00068\ }
\DoxyCodeLine{00069\ \textcolor{keyword}{class\ }Logger}
\DoxyCodeLine{00070\ \{}
\DoxyCodeLine{00071\ \textcolor{keyword}{public}:}
\DoxyCodeLine{00072\ \ \ \ \ \textcolor{keyword}{constexpr}\ \textcolor{keyword}{static}\ \textcolor{keyword}{const}\ uint\ NumLevels\ =\ uint(LogLevel::COUNT);}
\DoxyCodeLine{00073\ \ \ \ \ Logger();}
\DoxyCodeLine{00074\ \ \ \ \ \string~Logger();}
\DoxyCodeLine{00075\ }
\DoxyCodeLine{00076\ \ \ \ \ \textcolor{keyword}{static}\ Logger\&\ get()\ \{\ \textcolor{keywordflow}{return}\ sDefault;\ \}}
\DoxyCodeLine{00077\ }
\DoxyCodeLine{00078\ \ \ \ \ \textcolor{keywordtype}{void}\ Error\ (\textcolor{keyword}{const}\ std::string\ \&s)\ \{\ emit(LogLevel::ERROR,\ \textcolor{stringliteral}{"{}\ EE\ "{}},\ s);\ \}}
\DoxyCodeLine{00079\ \ \ \ \ \textcolor{keywordtype}{void}\ Warn\ \ (\textcolor{keyword}{const}\ std::string\ \&s)\ \{\ emit(LogLevel::WARNING,\ \textcolor{stringliteral}{"{}\ WW\ "{}},\ s);\ \}}
\DoxyCodeLine{00080\ \ \ \ \ \textcolor{keywordtype}{void}\ Info\ \ (\textcolor{keyword}{const}\ std::string\ \&s)\ \{\ emit(LogLevel::INFO,\ \textcolor{stringliteral}{"{}\ II\ "{}},\ s);\ \}}
\DoxyCodeLine{00081\ \ \ \ \ \textcolor{keywordtype}{void}\ Notice(\textcolor{keyword}{const}\ std::string\ \&s)\ \{\ emit(LogLevel::NOTICE,\ \textcolor{stringliteral}{"{}\ NN\ "{}},\ s);\ \}}
\DoxyCodeLine{00082\ \ \ \ \ \textcolor{keywordtype}{void}\ Debug\ (\textcolor{keyword}{const}\ std::string\ \&s)\ \{\ emit(LogLevel::DEBUG,\ \textcolor{stringliteral}{"{}\ DD\ "{}},\ s);\ \}}
\DoxyCodeLine{00083\ \ \ \ \ \textcolor{keywordtype}{void}\ Trace\ (\textcolor{keyword}{const}\ std::string\ \&s)\ \{\ emit(LogLevel::TRACE,\ \textcolor{stringliteral}{"{}\ TT\ "{}},\ s);\ \}}
\DoxyCodeLine{00084\ }
\DoxyCodeLine{00085\ \ \ \ \ \textcolor{keywordtype}{bool}\ visible(LogLevel\ v)\textcolor{keyword}{\ const\ }\{\ \textcolor{keywordflow}{return}\ mLevel\ >=\ v;\ \}}
\DoxyCodeLine{00086\ }
\DoxyCodeLine{00087\ \ \ \ \ \textcolor{keywordtype}{void}\ setLevel(\textcolor{keyword}{const}\ std::string\&);}
\DoxyCodeLine{00088\ \ \ \ \ \textcolor{keywordtype}{void}\ setDefaultLevel(\textcolor{keyword}{const}\ std::string\&);}
\DoxyCodeLine{00089\ \ \ \ \ \textcolor{keywordtype}{void}\ setLevel(LogLevel);}
\DoxyCodeLine{00090\ \ \ \ \ \textcolor{keywordtype}{void}\ setPrefix(\textcolor{keyword}{const}\ std::string\&);}
\DoxyCodeLine{00091\ \ \ \ \ \textcolor{keywordtype}{void}\ setTarget(LogLevel,\ \textcolor{keyword}{const}\ std::string\ \&path);}
\DoxyCodeLine{00092\ }
\DoxyCodeLine{00093\ \ \ \ \ \textcolor{keywordtype}{int}\ indent(\textcolor{keywordtype}{int}\ n);}
\DoxyCodeLine{00094\ }
\DoxyCodeLine{00095\ \ \ \ \ \textcolor{keyword}{static}\ \textcolor{keywordtype}{char}\ levelChar(LogLevel);}
\DoxyCodeLine{00096\ \ \ \ \ \textcolor{keyword}{static}\ LogLevel\ level(\textcolor{keyword}{const}\ std::string\_view\ name);}
\DoxyCodeLine{00097\ \ \ \ \ \textcolor{keyword}{static}\ std::string\ nowString();}
\DoxyCodeLine{00098\ \ \ \ \ \textcolor{keyword}{static}\ std::string\ formatDurationUS(uint64\_t\ us);}
\DoxyCodeLine{00099\ \ \ \ \ \textcolor{keyword}{static}\ std::string\ formatMask(uint32\_t);}
\DoxyCodeLine{00100\ }
\DoxyCodeLine{00101\ \textcolor{keyword}{private}:}
\DoxyCodeLine{00102\ \ \ \ \ \textcolor{keyword}{static}\ \textcolor{keyword}{const}\ \textcolor{keywordtype}{char}\ sLevelChars[NumLevels];}
\DoxyCodeLine{00103\ \ \ \ \ \textcolor{keyword}{static}\ Logger\ sDefault;}
\DoxyCodeLine{00104\ }
\DoxyCodeLine{00105\ \textcolor{keyword}{private}:}
\DoxyCodeLine{00106\ \ \ \ \ LogLevel\ mLevel\{LogLevel::INFO\};}
\DoxyCodeLine{00107\ \ \ \ \ std::string\ mPrefix;}
\DoxyCodeLine{00108\ \ \ \ \ \mbox{\hyperlink{classLogFile}{LogFile}}\ mFiles[NumLevels];}
\DoxyCodeLine{00109\ \ \ \ \ \textcolor{keywordtype}{int}\ mIndent\{0\};}
\DoxyCodeLine{00110\ }
\DoxyCodeLine{00111\ \ \ \ \ \textcolor{keywordtype}{void}\ emit(LogLevel,\ \textcolor{keyword}{const}\ \textcolor{keywordtype}{char}\ *pfx,\ \textcolor{keyword}{const}\ std::string\&);}
\DoxyCodeLine{00112\ \};}
\DoxyCodeLine{00113\ }
\DoxyCodeLine{00114\ \textcolor{keyword}{inline}\ \textcolor{keywordtype}{char}\ Logger::levelChar(LogLevel\ l)}
\DoxyCodeLine{00115\ \{}
\DoxyCodeLine{00116\ \ \ \ \ assert(uint(l)\ <\ NumLevels);}
\DoxyCodeLine{00117\ \ \ \ \ \textcolor{keywordflow}{return}\ sLevelChars[uint(l)];}
\DoxyCodeLine{00118\ \}}
\DoxyCodeLine{00119\ }
\DoxyCodeLine{00120\ \textcolor{keyword}{inline}\ \textcolor{keywordtype}{int}\ Logger::indent(\textcolor{keywordtype}{int}\ n)}
\DoxyCodeLine{00121\ \{}
\DoxyCodeLine{00122\ \ \ \ \ mIndent\ =\ std::max(0,\ mIndent\ +\ n);}
\DoxyCodeLine{00123\ \ \ \ \ mPrefix\ =\ std::string(mIndent,\ \textcolor{charliteral}{'\ '});}
\DoxyCodeLine{00124\ \ \ \ \ \textcolor{keywordflow}{return}\ mIndent;}
\DoxyCodeLine{00125\ \}}
\DoxyCodeLine{00126\ }
\DoxyCodeLine{00127\ \textcolor{keyword}{inline}\ \textcolor{keywordtype}{void}\ Logger::setLevel(\textcolor{keyword}{const}\ std::string\ \&name)}
\DoxyCodeLine{00128\ \{}
\DoxyCodeLine{00129\ \ \ \ \ mLevel\ =\ level(name);}
\DoxyCodeLine{00130\ \}}
\DoxyCodeLine{00131\ \textcolor{keyword}{inline}\ \textcolor{keywordtype}{void}\ Logger::setLevel(LogLevel\ v)}
\DoxyCodeLine{00132\ \{}
\DoxyCodeLine{00133\ \ \ \ \ mLevel\ =\ v;}
\DoxyCodeLine{00134\ \}}
\DoxyCodeLine{00135\ }
\DoxyCodeLine{00136\ \textcolor{keyword}{inline}\ \textcolor{keywordtype}{void}\ Logger::setPrefix(\textcolor{keyword}{const}\ std::string\ \&s)}
\DoxyCodeLine{00137\ \{}
\DoxyCodeLine{00138\ \ \ \ \ mPrefix\ =\ s;}
\DoxyCodeLine{00139\ \ \ \ \ indent(0);}
\DoxyCodeLine{00140\ \}}
\DoxyCodeLine{00141\ }
\DoxyCodeLine{00142\ \textcolor{keyword}{inline}\ \textcolor{keywordtype}{void}\ Logger::emit(LogLevel\ l,\ \textcolor{keyword}{const}\ \textcolor{keywordtype}{char}\ *pfx,\ \textcolor{keyword}{const}\ std::string\ \&s)}
\DoxyCodeLine{00143\ \{}
\DoxyCodeLine{00144\ \ \ \ \ \textcolor{keyword}{auto}\ \&os\ =\ mFiles[uint(l)].stream();}
\DoxyCodeLine{00145\ \ \ \ \ \textcolor{keywordflow}{if}\ (GYM\_PCB\_LOG\_SHOW\_THREAD)}
\DoxyCodeLine{00146\ \ \ \ \ \ \ \ \ os\ <<\ \textcolor{charliteral}{'<'}\ <<\ std::this\_thread::get\_id()\ <<\ \textcolor{stringliteral}{"{}>\ "{}};}
\DoxyCodeLine{00147\ \ \ \ \ os\ <<\ nowString()\ <<\ pfx\ <<\ mPrefix\ <<\ s\ <<\ std::endl;}
\DoxyCodeLine{00148\ \}}
\DoxyCodeLine{00149\ }
\DoxyCodeLine{00150\ \textcolor{preprocessor}{\#endif\ }\textcolor{comment}{//\ GYM\_PCB\_LOG\_H}}

\end{DoxyCode}
