Back to home page

EIC code displayed by LXR

 
 

    


Warning, /eic-opticks/sysrap/SLOG_review.rst is written in an unsupported language. File is not indexed.

0001 SLOG review
0002 ==============
0003 
0004 Overview
0005 ----------
0006 
0007 SLOG provides a thin convenience/configuration layer above the 
0008 underlying plog logging framework. In particular it 
0009 makes it simple to setup a chained multi-logger system with a
0010 main logger and loggers for each library with individually
0011 controlled logging levels via command line arguments, 
0012 which all log to the same console and logfile. 
0013 
0014 ::
0015 
0016     OKTest --warn \              # global loglevel
0017            --npy verbose \       # per-library loglevel 
0018            --sysrap warning 
0019 
0020 
0021 Getting rid of the dangerous re-define of trace
0022 -------------------------------------------------
0023 
0024 Observe a problem with xercesc headers : so bite the bullet 
0025 and get rid of the dangerous define and switch all 
0026 use of LOG(trace) into LOG(verbose)
0027 
0028 ::
0029 
0030     epsilon:sysrap blyth$ hg diff SLOG.hh
0031     diff -r 3e7743e5bc48 sysrap/SLOG.hh
0032     --- a/sysrap/SLOG.hh    Thu Aug 16 00:01:19 2018 +0800
0033     +++ b/sysrap/SLOG.hh    Thu Aug 16 12:57:29 2018 +0800
0034     @@ -15,7 +15,7 @@
0035      using plog::verbose ;
0036      
0037      // hmm dangerous but what alternative 
0038     -#define trace plog::verbose 
0039     +//#define trace plog::verbose 
0040      
0041      #include "SYSRAP_API_EXPORT.hh"
0042      
0043     epsilon:sysrap blyth$ 
0044 
0045 
0046 
0047 plog
0048 ------
0049 
0050 * https://github.com/SergiusTheBest/plog
0051 
0052 chained loggers
0053 ~~~~~~~~~~~~~~~~~~
0054 
0055 * https://github.com/SergiusTheBest/plog#chained-loggers
0056 * https://github.com/SergiusTheBest/plog/blob/master/samples/Chained/ChainedApp/Main.cpp
0057 * https://github.com/SergiusTheBest/plog/blob/master/samples/Chained/ChainedLib/Main.cpp
0058 
0059 A Logger can work as an Appender for another Logger. So you can chain several
0060 loggers together. This is useful for streaming log messages from a shared
0061 library to the main application binary.
0062 
0063 
0064 ::
0065 
0066     // main app
0067 
0068     // Functions imported form the shared library.
0069     extern "C" void initialize(plog::Severity severity, plog::IAppender* appender);
0070     extern "C" void foo();
0071 
0072     int main()
0073     {
0074         plog::init(plog::debug, "ChainedApp.txt"); // Initialize the main logger.
0075 
0076         LOGD << "Hello from app!"; // Write a log message.
0077 
0078         initialize(plog::debug, plog::get()); // Initialize the logger in the shared library. Note that it has its own severity.
0079         foo(); // Call a function from the shared library that produces a log message.
0080 
0081         return 0;
0082     }
0083 
0084 ::
0085 
0086     // shared library
0087 
0088     // Function that initializes the logger in the shared library. 
0089     extern "C" void EXPORT initialize(plog::Severity severity, plog::IAppender* appender)
0090     {
0091         plog::init(severity, appender); // Initialize the shared library logger.
0092     }
0093 
0094     // Function that produces a log message.
0095     extern "C" void EXPORT foo()
0096     {
0097         LOGI << "Hello from shared lib!";
0098     }
0099 
0100 
0101 Typical Opticks executable main
0102 ----------------------------------
0103 ::
0104 
0105 
0106      01 // op --opticks 
0107       2 
0108       3 #include <iostream>
0109       4 
0110       5 #include "BFile.hh"
0111       6 #include "SLOG.hh"
0112       7 
0113       8 #include "SYSRAP_LOG.hh"
0114       9 #include "BRAP_LOG.hh"
0115      10 #include "NPY_LOG.hh"
0116      11 #include "OKCORE_LOG.hh"
0117      12 
0118      13 #include "Opticks.hh"
0119      14 
0120      ..
0121      74 int main(int argc, char** argv)
0122      75 {
0123      76     SLOG_(argc,argv);
0124      77     LOG(info) << argv[0] ;
0125      78 
0126      79 
0127      80     SYSRAP_LOG__ ;
0128      81     BRAP_LOG__ ;
0129      82     NPY_LOG__ ;
0130      83     OKCORE_LOG__ ;
0131      84 
0132      85 
0133      86     Opticks ok(argc, argv);
0134      87 
0135 
0136 
0137 SLOG.hh
0138 ~~~~~~~~~~
0139 
0140 ::
0141 
0142     005 #include <cstddef>
0143       6 #include <plog/Log.h>
0144       7 
0145       8 // translate from boost log levels to plog 
0146       9 using plog::fatal ;
0147      10 using plog::error ;
0148      11 using plog::warning ;
0149      12 using plog::info ;
0150      13 using plog::debug ;
0151      14 using plog::verbose ;
0152      15 
0153      16 // hmm dangerous but what alternative 
0154      17 #define trace plog::verbose 
0155      18 
0156      19 #include "SYSRAP_API_EXPORT.hh"
0157     ...
0158     105 struct SLOG ;
0159     106 
0160     107 struct SYSRAP_API SLOG
0161     108 {
0162     109     int    argc ;
0163     110     char** argv ;
0164     111     int   level ;
0165     112     const char* logpath ;
0166     113     int   logmax ;
0167     114 
0168     115     SLOG(int argc, char** argv, const char* fallback="VERBOSE", const char* prefix=NULL );
0169     116 
0170     117     const char* name();
0171     118     int parse( const char* fallback);
0172     119     int parse( plog::Severity _fallback);
0173     120     int prefixlevel_parse( const char* fallback, const char* prefix);
0174     121     int prefixlevel_parse( plog::Severity _fallback, const char* prefix);
0175     122 
0176     123     static int  _parse(int argc, char** argv, const char* fallback);
0177     124     static int  _prefixlevel_parse(int argc, char** argv, const char* fallback, const char* prefix);
0178     125     static void _dump(const char* msg, int argc, char** argv);
0179     126     static const char* _name(plog::Severity severity);
0180     127     static const char* _name(int level);
0181     128     static const char* _logpath_parse(int argc, char** argv);
0182     129 
0183     130     static SLOG* instance ;
0184     ...     ^^^^^^^^^^^^^^^^^^^^^^^^^^ static singleton instance : possibly source of stomp problems with recent gcc ?
0185 
0186     131 };
0187     132 
0188     133 
0189     134 #include "SLOG_INIT.hh"
0190     135 
0191 
0192 
0193 SLOG_INIT.hh
0194 ~~~~~~~~~~~~~~
0195 
0196 ::
0197 
0198      01 #include <plog/Log.h>
0199       2 #include <plog/Appenders/ColorConsoleAppender.h>
0200       3 #include <plog/Appenders/ConsoleAppender.h>
0201       4 #include <plog/Formatters/FuncMessageFormatter.h>
0202       5 
0203       6 #include "PlainFormatter.hh"
0204       7 
0205       8 /*
0206       9 
0207      10 SLOG_INIT macros are used in two situations:
0208      11 
0209      12 * an executable main as a result of SLOG_ or PLOT_COLOR applied
0210      13   to the arguments
0211      14 
0212      15 * package logger 
0213      16 
0214      17 
0215      18 */
0216      19 
0217      20 
0218      21 
0219      22 #define SLOG_INIT(level, app1, app2 ) \
0220      23 { \
0221      24     plog::IAppender* appender1 = app1 ? static_cast<plog::IAppender*>(app1) : NULL ; \
0222      25     plog::IAppender* appender2 = app2 ? static_cast<plog::IAppender*>(app2) : NULL ; \
0223      26     plog::Severity severity = static_cast<plog::Severity>(level) ; \
0224      27     plog::init( severity ,  appender1 ); \
0225      28     if(appender2) \
0226      29         plog::get()->addAppender(appender2) ; \
0227      30 } \ 
0228      31     
0229      32     
0230      33 #define SLOG_COLOR(argc, argv) \
0231      34 { \ 
0232      35     SLOG _plog(argc, argv); \
0233      36     static plog::RollingFileAppender<plog::FuncMessageFormatter> fileAppender( _plog.logpath, _plog.logmax); \
0234      37     static plog::ColorConsoleAppender<plog::TxtFormatter> consoleAppender; \
0235      38     SLOG_INIT( _plog.level, &consoleAppender, &fileAppender ); \
0236      39 } \ 
0237      40     
0238      41 #define SLOG_(argc, argv) \
0239      42 { \ 
0240      43     SLOG _plog(argc, argv); \
0241      44     static plog::RollingFileAppender<plog::FuncMessageFormatter> fileAppender( _plog.logpath, _plog.logmax); \
0242      45     static plog::ConsoleAppender<plog::TxtFormatter> consoleAppender; \
0243      46     SLOG_INIT( _plog.level,  &consoleAppender, &fileAppender ); \
0244      47 } \ 
0245      48     
0246      ...
0247 
0248 
0249 What SLOG_(argc, argv) does
0250 ------------------------------
0251 
0252 ::
0253 
0254      74 int main(int argc, char** argv)
0255      75 {
0256      76     SLOG_(argc,argv);
0257      77     LOG(info) << argv[0] ;
0258      78  
0259 
0260 Instanciates SLOG struct into main which parses command line arguments into:
0261 
0262 * global logmax
0263 * global logpath
0264 * holds onto arguments within SLOG::instance, for use from the package loggers
0265 
0266 Invokes SLOG_INIT macro which instanciates the main plog logger and hooks up 
0267 file and console appenders.
0268 
0269 
0270 What SYSRAP_LOG__ and other pkg macros do
0271 ---------------------------------------------
0272 
0273 ::
0274 
0275       5 #define SYSRAP_LOG__  {     SYSRAP_LOG::Initialize(SLOG::instance->prefixlevel_parse( info, "SYSRAP"), plog::get(), NULL );  } 
0276 
0277       ## notice that the main logger plog::get() is being passed to the lib logger as an appender
0278 
0279 
0280 * uses the command line arguments persisted in SLOG::instance to define the per-package logging level 
0281   and passes this level to the package libs where SLOG_INIT is invoked to instanciate the 
0282   per-library loggers.  
0283 
0284 * also chains together the main and library loggers ; this means than the lib 
0285   logger acts as an appender for the main logger
0286 
0287 
0288 Package Loggers
0289 -------------------
0290 
0291 SYSRAP_LOG.hh  SYSRAP_LOG.cc
0292 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0293 
0294 ::
0295 
0296      01 
0297       2 #pragma once
0298       3 #include "SYSRAP_API_EXPORT.hh"
0299       4 
0300       5 #define SYSRAP_LOG__  {     SYSRAP_LOG::Initialize(SLOG::instance->prefixlevel_parse( info, "SYSRAP"), plog::get(), NULL );  } 
0301       6 
0302       7 #define SYSRAP_LOG_ {     SYSRAP_LOG::Initialize(plog::get()->getMaxSeverity(), plog::get(), NULL ); } 
0303       8 class SYSRAP_API SYSRAP_LOG {
0304       9    public:
0305      10        static void Initialize(int level, void* app1, void* app2 );
0306      11        static void Check(const char* msg);
0307      12 };
0308      13 
0309 
0310      01 
0311       2 #include <plog/Log.h>
0312       3 
0313       4 #include "SYSRAP_LOG.hh"
0314       5 #include "SLOG_INIT.hh"
0315       6 #include "SLOG.hh"
0316       7        
0317       8 void SYSRAP_LOG::Initialize(int level, void* app1, void* app2 )
0318       9 {  
0319      10     SLOG_INIT(level, app1, app2); 
0320      11 }      
0321      12 void SYSRAP_LOG::Check(const char* msg)
0322      13 {
0323      14     SLOG_CHECK(msg);
0324      15 }
0325      16 
0326 
0327 
0328 NPY_LOG.hh NPY_LOG.cc
0329 ~~~~~~~~~~~~~~~~~~~~~~~~~~
0330 
0331 ::
0332 
0333 
0334      01 
0335       2 #pragma once
0336       3 #include "NPY_API_EXPORT.hh"
0337       4 
0338       5 #define NPY_LOG__  {     NPY_LOG::Initialize(SLOG::instance->prefixlevel_parse( info, "NPY"), plog::get(), NULL );  } 
0339       6 
0340       7 #define NPY_LOG_ {     NPY_LOG::Initialize(plog::get()->getMaxSeverity(), plog::get(), NULL ); } 
0341       8 class NPY_API NPY_LOG {
0342       9    public:
0343      10        static void Initialize(int level, void* app1, void* app2 );
0344      11        static void Check(const char* msg);
0345      12 };
0346      13 
0347 
0348      01 
0349       2 #include <plog/Log.h>
0350       3 
0351       4 #include "NPY_LOG.hh"
0352       5 #include "SLOG_INIT.hh"
0353       6 #include "SLOG.hh"
0354       7 
0355       8 void NPY_LOG::Initialize(int level, void* app1, void* app2 )
0356       9 {
0357      10     SLOG_INIT(level, app1, app2);
0358      11 }
0359      12 void NPY_LOG::Check(const char* msg)
0360      13 {
0361      14     SLOG_CHECK(msg);
0362      15 }
0363 
0364 
0365 
0366 
0367 
0368 Same pattern followed by all package loggers ...
0369 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0370 
0371 
0372 ::
0373 
0374     simon:opticks blyth$ find . -name '*_LOG.cc'
0375     ./assimprap/ASIRAP_LOG.cc
0376     ./boostrap/BRAP_LOG.cc
0377     ./cfg4/CFG4_LOG.cc
0378     ./cudarap/CUDARAP_LOG.cc
0379     ./ggeo/GGEO_LOG.cc
0380     ./oglrap/OGLRAP_LOG.cc
0381     ./ok/OK_LOG.cc
0382     ./okg4/OKG4_LOG.cc
0383     ./okop/OKOP_LOG.cc
0384     ./openmeshrap/MESHRAP_LOG.cc
0385     ./optickscore/OKCORE_LOG.cc
0386     ./opticksgeo/OKGEO_LOG.cc
0387     ./opticksgl/OKGL_LOG.cc
0388     ./opticksnpy/NPY_LOG.cc
0389     ./optixrap/OXRAP_LOG.cc
0390     ./sysrap/SYSRAP_LOG.cc
0391     ./thrustrap/THRAP_LOG.cc
0392     simon:opticks blyth$ 
0393 
0394 Using the preprocessor macros allows the same logging setup code to 
0395 be planted in every library.
0396 
0397 
0398 
0399 Issue : log level not controlled in standalone script build cfg4/tests/CGDMLKludgeTest.sh 
0400 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0401 
0402 ::
0403 
0404     epsilon:cfg4 blyth$ grep CFG4_LOG *.*
0405     CFG4_LOG.cc:#include "CFG4_LOG.hh"
0406     CFG4_LOG.cc:void CFG4_LOG::Initialize(int level, void* app1, void* app2 )
0407     CFG4_LOG.cc:void CFG4_LOG::Check(const char* msg)
0408     CFG4_LOG.hh:#define CFG4_LOG__  {     CFG4_LOG::Initialize(SLOG::instance->prefixlevel_parse( info, "CFG4"), plog::get(), NULL );  } 
0409     CFG4_LOG.hh:#define CFG4_LOG_ {     CFG4_LOG::Initialize(plog::get()->getMaxSeverity(), plog::get(), NULL ); } 
0410     CFG4_LOG.hh:class CFG4_API CFG4_LOG {
0411     CMakeLists.txt:    CFG4_LOG.cc
0412     CMakeLists.txt:    CFG4_LOG.hh
0413     epsilon:cfg4 blyth$ 
0414 
0415 
0416 The main does this, CGDMLKludgeTest.cc::
0417 
0418      08 #include "OPTICKS_LOG.hh"
0419       9 #include "CGDMLKludge.hh"
0420      10 
0421      11 int main(int argc, char** argv)
0422      12 {
0423      13     OPTICKS_LOG(argc, argv);
0424      14 
0425 
0426        
0427 What OPTICKS_LOG does depends on the preprocessor macros such as *-DOPTICKS_CFG4*::
0428 
0429    #define OPTICKS_LOG(argc, argv) {      SLOG_COLOR(argc, argv);     OPTICKS_LOG_::Initialize(SLOG::instance, plog::get(), NULL ); } 
0430 
0431 
0432 
0433 OPTICKS_LOG.hh::
0434 
0435     108 class SYSRAP_API OPTICKS_LOG_ {
0436     109    public:
0437     110        // initialize all linked loggers and hookup the main logger
0438     111        static void Initialize(SLOG* instance, void* app1, void* /*app2*/ )
0439     112        {
0440     113            int max_level = instance->parse("info") ;
0441     114            // note : can decrease verbosity from the max_level in the subproj, but not increase
0442     115 
0443     116 #ifdef OPTICKS_SYSRAP
0444     117     SYSRAP_LOG::Initialize(instance->prefixlevel_parse( max_level, "SYSRAP"), app1, NULL );
0445     118 #endif
0446     119 #ifdef OPTICKS_BRAP
0447     120     BRAP_LOG::Initialize(instance->prefixlevel_parse( max_level, "BRAP"), app1, NULL );
0448     121 #endif
0449     ...
0450     164 #ifdef OPTICKS_X4
0451     165     X4_LOG::Initialize(instance->prefixlevel_parse( max_level, "X4"), app1, NULL );
0452     166 #endif
0453     167 #ifdef OPTICKS_CFG4
0454     168     CFG4_LOG::Initialize(instance->prefixlevel_parse( max_level, "CFG4"), app1, NULL );
0455     169 #endif
0456 
0457 
0458 
0459 
0460