File indexing completed on 2026-04-09 07:49:39
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020 #include <cstdlib>
0021 #include <cstring>
0022 #include <cassert>
0023 #include <iostream>
0024 #include <algorithm>
0025 #include <string>
0026
0027
0028 #include "SLOG.hh"
0029 #include "ssys.h"
0030 #include "s_time.h"
0031 #include "sproc.h"
0032
0033 #include "SASCII.hh"
0034
0035 SLOG* SLOG::instance = NULL ;
0036
0037 const int SLOG::MAXARGC = 100 ;
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055 template<int IDX>
0056 plog::Severity SLOG::MaxSeverity(plog::Logger<IDX>* logger)
0057 {
0058 return logger ? logger->getMaxSeverity() : plog::none ;
0059 }
0060 template<int IDX>
0061 const char* SLOG::MaxSeverityString(plog::Logger<IDX>* logger)
0062 {
0063 return plog::severityToString(SLOG::MaxSeverity<IDX>(logger)) ;
0064 }
0065
0066
0067
0068 template<int IDX>
0069 std::string SLOG::Desc(plog::Logger<IDX>* logger)
0070 {
0071 std::stringstream ss ;
0072 ss << " logger " << logger
0073 << " SLOG::MaxSeverity<IDX>(logger) " << SLOG::MaxSeverity<IDX>(logger)
0074 << " SLOG::MaxSeverityString<IDX>(logger) " << SLOG::MaxSeverityString<IDX>(logger)
0075 ;
0076 std::string str = ss.str();
0077 return str ;
0078 }
0079
0080
0081
0082
0083
0084 template<int IDX>
0085 std::string SLOG::Desc()
0086 {
0087 plog::Logger<IDX>* lib_logger = plog::get<IDX>();
0088 return Desc(lib_logger) ;
0089 }
0090
0091 std::string SLOG::banner() const
0092 {
0093 const char* bin = exename() ;
0094 int VERSION = ssys::getenvint("VERSION", 0 );
0095 std::stringstream ss ;
0096 ss << "SLOG::banner"
0097 << " " << ( bin ? bin : "-" )
0098 << " " << s_time::Stamp()
0099 << " " << s_time::EpochSeconds()
0100 << " V" << VERSION
0101 ;
0102
0103 std::string str = ss.str();
0104 return str ;
0105 }
0106 std::string SLOG::Banner()
0107 {
0108 return instance ? instance->banner() : "-" ;
0109 }
0110
0111
0112 template std::string SLOG::Desc<0>(plog::Logger<0>* ) ;
0113 template std::string SLOG::Desc<0>() ;
0114
0115 std::string SLOG::Flags()
0116 {
0117 std::stringstream ss ;
0118 ss
0119 #ifdef PLOG_LOCAL
0120 << " PLOG_LOCAL "
0121 #else
0122 << " NOT:PLOG_LOCAL "
0123 #endif
0124 #ifdef PLOG_GLOBAL
0125 << " PLOG_GLOBAL "
0126 #else
0127 << " NOT:PLOG_GLOBAL "
0128 #endif
0129 ;
0130 std::string s = ss.str();
0131 return s ;
0132 }
0133
0134
0135 void SLOG::Dump()
0136 {
0137 LOG(none) << " LOG(none) " ;
0138 LOG(fatal) << " LOG(fatal) " ;
0139 LOG(error) << " LOG(error) " ;
0140 LOG(warning) << " LOG(warning) " ;
0141 LOG(info) << " LOG(info) " ;
0142 LOG(debug) << " LOG(debug) " ;
0143 LOG(verbose) << " LOG(verbose) " ;
0144 }
0145
0146
0147
0148
0149
0150 plog::Severity SLOG::Delta(plog::Severity level_, int delta)
0151 {
0152 int level = (int)level_ + delta ;
0153 if(level < (int)fatal) level = (int)fatal ;
0154 if(level > (int)verbose) level = (int)verbose ;
0155 return (plog::Severity)level ;
0156 }
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171 plog::Severity SLOG::EnvLevel( const char* key, const char* fallback)
0172 {
0173 const char* level = ssys::getenvvar(key, fallback);
0174 const char* upper_level = SASCII::ToUpper(level);
0175 plog::Severity severity = plog::severityFromString(upper_level) ;
0176
0177 if(strcmp(level, fallback) != 0)
0178 {
0179 std::cerr
0180 << "SLOG::EnvLevel"
0181 << " adjusting loglevel by envvar "
0182 << " key " << key
0183 << " level " << level
0184 << " fallback " << fallback
0185 << " upper_level " << upper_level
0186 << std::endl
0187 ;
0188 }
0189 return severity ;
0190 }
0191
0192
0193
0194
0195 void SLOG::_dump(const char* msg, int argc, char** argv)
0196 {
0197 std::cerr << msg
0198 << " argc " << argc ;
0199
0200 for(int i=0 ; i < argc ; i++) std::cerr << argv[i] ;
0201 std::cerr << std::endl ;
0202 }
0203
0204 int SLOG::_parse(int argc, char** argv, const char* fallback)
0205 {
0206
0207
0208 assert( argc < MAXARGC && " argc sanity check fail ");
0209
0210 std::string ll = fallback ;
0211 for(int i=1 ; i < argc ; ++i )
0212 {
0213 std::string arg(argv[i] ? argv[i] : "");
0214 std::transform(arg.begin(), arg.end(), arg.begin(), ::tolower);
0215 if(arg.compare("--trace")==0) ll = "VERBOSE" ;
0216 if(arg.compare("--verbose")==0) ll = "VERBOSE" ;
0217 if(arg.compare("--debug")==0) ll = "DEBUG" ;
0218 if(arg.compare("--info")==0) ll = "INFO" ;
0219 if(arg.compare("--warning")==0) ll = "WARNING" ;
0220 if(arg.compare("--error")==0) ll = "ERROR" ;
0221 if(arg.compare("--fatal")==0) ll = "FATAL" ;
0222
0223
0224 }
0225
0226 std::transform(ll.begin(), ll.end(), ll.begin(), ::toupper);
0227 plog::Severity severity = plog::severityFromString(ll.c_str()) ;
0228
0229 int level = static_cast<int>(severity);
0230
0231
0232
0233 return level ;
0234 }
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252
0253 const char* SLOG::_logpath_parse_problematic(int argc, char** argv)
0254 {
0255 assert( argc < MAXARGC && " argc sanity check fail ");
0256 std::string lp(argc > 0 ? argv[0] : "default") ;
0257 lp += ".log" ;
0258 return strdup(lp.c_str());
0259 }
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270 const char* SLOG::_logpath()
0271 {
0272 const char* exename = sproc::ExecutableName() ;
0273 std::string lp(exename) ;
0274 lp += ".log" ;
0275 return strdup(lp.c_str());
0276 }
0277
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301 int SLOG::_prefixlevel_parse(int argc, char** argv, const char* fallback, const char* prefix)
0302 {
0303
0304 assert( argc < MAXARGC && " argc sanity check fail ");
0305
0306 std::string pfx(prefix);
0307 std::transform(pfx.begin(), pfx.end(), pfx.begin(), ::tolower);
0308 std::string apfx("--");
0309 apfx += pfx ;
0310
0311 std::string ll(fallback) ;
0312 for(int i=1 ; i < argc ; ++i )
0313 {
0314 char* ai = argv[i] ;
0315 char* aj = i + 1 < argc ? argv[i+1] : NULL ;
0316
0317 std::string arg(ai ? ai : "");
0318 std::transform(arg.begin(), arg.end(), arg.begin(), ::tolower);
0319
0320
0321 if(arg.compare(apfx) == 0 && aj != NULL ) ll.assign(aj) ;
0322 }
0323
0324 std::transform(ll.begin(), ll.end(), ll.begin(), ::toupper);
0325
0326 const char* llc = ll.c_str();
0327 plog::Severity severity = strcmp(llc, "TRACE")==0 ? plog::severityFromString("VERB") : plog::severityFromString(llc) ;
0328 int level = static_cast<int>(severity);
0329
0330
0331
0332 return level ;
0333 }
0334
0335
0336
0337
0338 int SLOG::parse(plog::Severity _fallback)
0339 {
0340 const char* fallback = _name(_fallback);
0341 return parse(fallback);
0342 }
0343 int SLOG::parse(const char* fallback)
0344 {
0345 int ll = _parse(args._argc, args._argv, fallback);
0346
0347 #ifdef SLOG_DBG
0348 std::cerr << "SLOG::parse"
0349 << " fallback " << fallback
0350 << " level " << ll
0351 << " name " << _name(ll)
0352 << std::endl ;
0353 #endif
0354
0355 return ll ;
0356 }
0357
0358
0359 int SLOG::prefixlevel_parse(int _fallback, const char* prefix)
0360 {
0361 plog::Severity fallback = static_cast<plog::Severity>(_fallback);
0362 return prefixlevel_parse(fallback, prefix) ;
0363 }
0364
0365 int SLOG::prefixlevel_parse(plog::Severity _fallback, const char* prefix)
0366 {
0367 const char* fallback = _name(_fallback);
0368 return prefixlevel_parse(fallback, prefix) ;
0369 }
0370
0371
0372
0373
0374
0375
0376
0377
0378
0379
0380
0381
0382
0383
0384
0385
0386
0387
0388
0389
0390 int SLOG::prefixlevel_parse(const char* fallback, const char* prefix)
0391 {
0392 int ll = _prefixlevel_parse(args._argc, args._argv, fallback, prefix);
0393
0394 #ifdef SLOG_DBG
0395 std::cerr << "SLOG::prefixlevel_parse"
0396 << " fallback " << fallback
0397 << " prefix " << prefix
0398 << " level " << ll
0399 << " name " << _name(ll)
0400 << std::endl ;
0401 #endif
0402
0403 return ll ;
0404 }
0405
0406
0407
0408 const char* SLOG::_name(int level)
0409 {
0410 plog::Severity severity = static_cast<plog::Severity>(level);
0411 return plog::severityToString(severity);
0412 }
0413 const char* SLOG::_name(plog::Severity severity)
0414 {
0415 return plog::severityToString(severity);
0416 }
0417
0418 const char* SLOG::name()
0419 {
0420 plog::Severity severity = static_cast<plog::Severity>(level);
0421 return _name(severity);
0422 }
0423
0424 const char* SLOG::exename() const
0425 {
0426 return args.exename();
0427 }
0428 const char* SLOG::cmdline() const
0429 {
0430 return args.cmdline();
0431 }
0432
0433
0434 const char* SLOG::get_arg_after(const char* option, const char* fallback) const
0435 {
0436 return args.get_arg_after(option, fallback);
0437 }
0438 int SLOG::get_int_after(const char* option, const char* fallback) const
0439 {
0440 return args.get_int_after(option, fallback);
0441 }
0442 bool SLOG::has_arg(const char* arg) const
0443 {
0444 return args.has_arg(arg);
0445 }
0446
0447
0448
0449
0450
0451
0452 SLOG::SLOG(const char* name, const char* fallback, const char* prefix)
0453 :
0454 args(name, "OPTICKS_LOG_ARGS" , ' '),
0455 level(info),
0456 filename(_logpath()),
0457 maxFileSize(ssys::getenvint("OPTICKS_LOG_MAXFILESIZE", 5000000)),
0458 maxFiles(ssys::getenvint("OPTICKS_LOG_MAXFILES", 10))
0459 {
0460 init(fallback, prefix);
0461 }
0462
0463 SLOG::SLOG(int argc_, char** argv_, const char* fallback, const char* prefix)
0464 :
0465 args(argc_, argv_, "OPTICKS_LOG_ARGS" , ' '),
0466 level(info),
0467 filename(_logpath()),
0468 maxFileSize(ssys::getenvint("OPTICKS_LOG_MAXFILESIZE", 5000000)),
0469 maxFiles(ssys::getenvint("OPTICKS_LOG_MAXFILES", 10))
0470 {
0471 init(fallback, prefix);
0472 }
0473
0474
0475 void SLOG::init(const char* fallback, const char* prefix)
0476 {
0477 level = prefix == NULL ? parse(fallback) : prefixlevel_parse(fallback, prefix ) ;
0478 assert( instance == NULL && "ONLY EXPECTING A SINGLE SLOG INSTANCE" );
0479 instance = this ;
0480 if(getenv("SLOG")) std::cout << "SLOG::init " << desc() << std::endl ;
0481 }
0482
0483 std::string SLOG::desc() const
0484 {
0485 std::stringstream ss ;
0486 ss << "SLOG::desc"
0487 << " level " << plog::severityToString((plog::Severity)level)
0488 << " filename " << filename
0489 << " maxFileSize " << maxFileSize
0490 << " maxFiles " << maxFiles
0491 ;
0492 std::string s = ss.str();
0493 return s ;
0494 }
0495
0496