FesaLogger.cpp
Go to the documentation of this file.00001
00002
00003
00004
00006
00007 #include <fesa-core/Diagnostic/FesaLogger.h>
00008 #include <fesa-core/Utilities/Lock.h>
00009
00010 #include <iostream>
00011 #include <syslog.h>
00012
00013 namespace fesa
00014 {
00015
00016 class FesaLoggerBuffer;
00017
00018
00019
00020
00021 const std::string FesaLogger::fwkSender = "FWK";
00022 const std::string FesaLogger::usrSender = "USR";
00023 std::map<std::string, FesaLogger *> FesaLogger::logFactoryMap_;
00024 Mutex FesaLogger::mutex_;
00025 UdpLogger* FesaLogger::pUDPLog_ = NULL;
00026 std::string FesaLogger::connectedHostName_ = "";
00027 int32_t FesaLogger::connectedPortNumber_ = -1;
00028 uint32_t FesaLogger::logCount_ = 0;
00029 TsCounter FesaLogger::logTsc_(true);
00030 bool FesaLogger::modeDiagnostic_ = false;
00031
00032 bool FesaLogger::isInitPhase_ = true;
00033 int32_t FesaLogger::fwkTopic_ = 0xffffffff;
00034 FesaLogger* FesaLogger::defaultLog_ =
00035 FesaLogger::getLogger(defaultLogName, undefinedThreadName, undefinedClassName);
00036
00037 const char* FesaLogger::logActionStr_[] = { "|-|", "|START|", "|STOP|" };
00038
00039
00040
00041 FesaLogger::FesaLogger(FesaLoggerBuffer* pBuf) :
00042 std::ostream(pBuf)
00043 {
00044 logBuffer_ = pBuf;
00045 pBuf->setFesaLogger(this);
00046
00047 modeDiagnostic_ = isInitPhase_;
00048 customTopic_ = 0xffffffff;
00049 lastError_ = 0;
00050 errSeverity_ = none;
00051 }
00052
00053
00054
00055
00056 FesaLogger::FesaLogger(const FesaLogger& refLogger) :
00057 std::ostream(NULL)
00058 {
00059
00060
00061 FesaLoggerBuffer* pBuffer = new FesaLoggerBuffer();
00062 rdbuf(pBuffer);
00063 logBuffer_ = pBuffer;
00064 pBuffer->setFesaLogger(this);
00065 modeDiagnostic_ = refLogger.modeDiagnostic_;
00066 lastError_ = 0;
00067
00068
00069 className_ = refLogger.className_;
00070 logSource_ = refLogger.logSource_;
00071 logThread_ = refLogger.logThread_;
00072 logName_ = refLogger.logName_;
00073 logType_ = refLogger.logType_;
00074 customTopic_ = refLogger.customTopic_;
00075 errSeverity_ = refLogger.errSeverity_;
00076 }
00077
00078
00079
00080 FesaLogger::~FesaLogger()
00081 {
00082
00083
00084 if (logBuffer_ != NULL)
00085 delete logBuffer_;
00086 }
00087
00088
00089
00090 void FesaLogger::init(char *bname)
00091 {
00092
00093
00094
00095
00096
00097 openlog(bname, LOG_PID | LOG_NDELAY | LOG_CONS, LOG_USER);
00098 }
00099
00100 bool FesaLogger::isEnabled()
00101 {
00102 return modeDiagnostic_;
00103 }
00104
00105
00106
00107 void FesaLogger::enableConsoleOutput()
00108 {
00109
00110
00111
00112
00113 isInitPhase_ = true;
00114 fwkTopic_ = 0xffffffff;
00115 std::map<std::string, FesaLogger *>::iterator itr;
00116 for (itr = logFactoryMap_.begin(); itr != logFactoryMap_.end(); itr++)
00117 {
00118 FesaLogger* pLogger = (FesaLogger *) ((*itr).second);
00119 pLogger->customTopic_ = 0xffffffff;
00120 }
00121
00122 setDiagnosticMode(true);
00123 }
00124
00125
00126
00127 void FesaLogger::disableConsoleOutput()
00128 {
00129
00130
00131 setDiagnosticMode(false);
00132 fwkTopic_ = 0;
00133 std::map<std::string, FesaLogger *>::iterator itr;
00134 for (itr = logFactoryMap_.begin(); itr != logFactoryMap_.end(); itr++)
00135 {
00136 FesaLogger* pLogger = (FesaLogger *) ((*itr).second);
00137 pLogger->customTopic_ = 0;
00138 }
00139 isInitPhase_ = false;
00140 }
00141
00142
00143
00144 void FesaLogger::reinit()
00145 {
00146
00147 UdpLogger* oldTraceLog = NULL;
00148 if (pUDPLog_ != NULL)
00149 oldTraceLog = pUDPLog_;
00150 unsigned short lport = (unsigned short) connectedPortNumber_;
00151
00152
00153
00154
00155 void (*oldHandler)(int32_t) = signal(SIGPIPE, SIG_IGN);
00156 pUDPLog_ = new UdpLogger(connectedHostName_.c_str(), lport, false);
00157
00158
00159 logCount_ = 0;
00160
00161 if (oldTraceLog != NULL)
00162 delete oldTraceLog;
00163 signal(SIGPIPE, oldHandler);
00164 }
00165
00166
00167
00168 void FesaLogger::destroy()
00169 {
00170
00171
00172 std::map<std::string, FesaLogger *>::iterator itr;
00173 for (itr = logFactoryMap_.begin(); itr != logFactoryMap_.end(); itr++)
00174 {
00175 delete ((FesaLogger *) ((*itr).second));
00176 }
00177
00178
00179 if (FesaLogger::pUDPLog_ != NULL)
00180 delete FesaLogger::pUDPLog_;
00181
00182
00183 closelog();
00184 }
00185
00186
00187
00188 FesaLogger* FesaLogger::getLogger(const std::string& source, const std::string& thread)
00189 {
00190 return getLogger(source, thread, undefinedClassName);
00191 }
00192
00193
00194
00195 FesaLogger* FesaLogger::getLogger(const std::string& source, const std::string& thread, const std::string& cname)
00196 {
00197
00198 FesaLogger* pLogger;
00199 FesaLoggerBuffer* pBuffer;
00200
00201 const std::string& cname_ = (cname.empty()) ? undefinedClassName : cname;
00202 const std::string& thread_ = (thread.empty()) ? undefinedThreadName : thread;
00203
00204
00205
00206
00207 std::string loggerName = source + thread_ + cname_;
00208
00209
00210
00211
00212 {
00213 Lock lock(mutex_);
00214
00215 std::map<std::string, FesaLogger *>::iterator itr = logFactoryMap_.find(loggerName);
00216 if (itr != logFactoryMap_.end())
00217 {
00218
00219
00220
00221 pLogger = (FesaLogger *) ((*itr).second);
00222 }
00223 else
00224 {
00225
00226
00227 pBuffer = new FesaLoggerBuffer();
00228 pLogger = new FesaLogger(pBuffer);
00229
00230
00231 logFactoryMap_[loggerName] = pLogger;
00232
00233 pLogger->className_ = cname_;
00234
00235
00236 pLogger->logSource_ = source + "|";
00237 pLogger->logThread_ = "|" + thread_ + "|";
00238 pLogger->logName_ = loggerName;
00239
00240 pLogger->logType_ = FesaLogger::traceType;
00241
00242
00243 }
00244
00245 }
00246 return pLogger;
00247 }
00248
00249
00250
00251
00252 void FesaLogger::setDiagnosticMode(bool mode)
00253 {
00254 modeDiagnostic_ = mode;
00255
00256
00257 std::map<std::string, FesaLogger *>::iterator itr;
00258 for (itr = logFactoryMap_.begin(); itr != logFactoryMap_.end(); itr++)
00259 {
00260 FesaLogger* pLogger = (FesaLogger *) ((*itr).second);
00261 pLogger->lastError_ = 0;
00262 }
00263
00264
00265 if (mode == false && pUDPLog_ != NULL)
00266 {
00267 connectedHostName_.erase();
00268 connectedPortNumber_ = -1;
00269 delete pUDPLog_;
00270 pUDPLog_ = NULL;
00271 }
00272 }
00273
00274
00275
00276
00277 void FesaLogger::setCustomTopic(int32_t customTopic, const std::string& cname)
00278 {
00279
00280
00281 std::map<std::string, FesaLogger *>::iterator itr;
00282 for (itr = logFactoryMap_.begin(); itr != logFactoryMap_.end(); itr++)
00283 {
00284 FesaLogger* pLogger = (FesaLogger *) ((*itr).second);
00285
00286 if (pLogger->className_ == cname)
00287 {
00288 pLogger->customTopic_ = customTopic;
00289 }
00290 }
00291 }
00292
00293
00294
00295 void FesaLogger::send(const char* msg, LogType type)
00296 {
00297
00298
00299
00300
00301
00302 if (pUDPLog_ == NULL)
00303 return;
00304 if ((logType_ = type) == FesaLogger::traceType)
00305 {
00306 if (!isInitPhase_)
00307 {
00308
00309
00310
00311
00312 int32_t err = FesaLogger::pUDPLog_->sendStr(msg);
00313 switch (err)
00314 {
00315
00316 case 0:
00317 case EAGAIN:
00318
00319
00320
00321 break;
00322
00323
00324 default:
00325
00326 if (lastError_ != err)
00327 {
00328
00329 std::string str("UDP send failure: ");
00330 str += strerror(err);
00331 syslog(errSeverity_, (char *) str.c_str());
00332 lastError_ = err;
00333 }
00334 }
00335 }
00336 else
00337 {
00338
00339
00340
00341 std::string str = std::string(msg);
00342 std::cout << str.substr(str.rfind('|') + 1) << std::endl;
00343 }
00344 }
00345 else
00346 {
00347
00348
00349 if (modeDiagnostic_ && !FesaLogger::isInitPhase_)
00350 {
00351 int32_t err = FesaLogger::pUDPLog_->sendStr(msg);
00352 switch (err)
00353 {
00354
00355 case 0:
00356 case EAGAIN:
00357
00358
00359
00360 break;
00361
00362
00363 default:
00364
00365 if (lastError_ != err)
00366 {
00367 std::string str("UDP send failure: ");
00368 str += strerror(err);
00369 syslog(errSeverity_, (char *) str.c_str());
00370 lastError_ = err;
00371 }
00372 }
00373 }
00374 else
00375 {
00376
00377 syslog(errSeverity_, (char *) msg);
00378
00379
00380
00381
00382
00383
00384
00385 if (errSeverity_ <= FesaLogger::error || FesaLogger::isInitPhase_)
00386 std::cout << msg << std::endl;
00387 }
00388 }
00389 }
00390
00391
00392
00393 int32_t FesaLoggerBuffer::sync()
00394 {
00395
00396
00397
00398 *pptr() = '\0';
00399 pbump(1);
00400
00401 int32_t num = static_cast<int32_t>(pptr() - pbase());
00402
00403
00404
00405
00406
00407 if (logger_->logType_ == FesaLogger::traceType)
00408 {
00409
00410 if ((!FesaLogger::isInitPhase_) && (FesaLogger::pUDPLog_ != NULL))
00411 {
00412
00413
00414
00415
00416 int32_t err = FesaLogger::pUDPLog_->sendStr(pbase());
00417 switch (err)
00418 {
00419
00420 case 0:
00421 case EAGAIN:
00422
00423
00424
00425 break;
00426
00427
00428 default:
00429
00430 if (logger_->lastError_ != err)
00431 {
00432 std::string str("UDP send failure: ");
00433 str += strerror(err);
00434 syslog(logger_->errSeverity_, (char *) str.c_str());
00435 logger_->lastError_ = err;
00436 }
00437 }
00438 }
00439 else
00440 {
00441
00442
00443
00444 if (pbase() != NULL)
00445 {
00446 std::string str = std::string(pbase());
00447 uint32_t position = static_cast<uint32_t>(str.rfind("|"));
00448
00449 if (position == std::string::npos)
00450 std::cout << str;
00451 else
00452 std::cout << str.substr(position + 1);
00453 }
00454 }
00455 }
00456 else
00457 {
00458
00459
00460 if (logger_->modeDiagnostic_ && !FesaLogger::isInitPhase_ && (FesaLogger::pUDPLog_ != NULL))
00461 {
00462 int32_t err = FesaLogger::pUDPLog_->sendStr(pbase());
00463 switch (err)
00464 {
00465
00466 case 0:
00467 case EAGAIN:
00468
00469
00470
00471 break;
00472
00473
00474 default:
00475
00476 if (logger_->lastError_ != err)
00477 {
00478 std::string str("UDP send failure: ");
00479 str += strerror(err);
00480 syslog(logger_->errSeverity_, (char *) str.c_str());
00481 logger_->lastError_ = err;
00482 }
00483 }
00484 }
00485 else
00486 {
00487
00488 syslog(logger_->errSeverity_, pbase());
00489
00490
00491
00492
00493
00494
00495
00496 if (logger_->errSeverity_ <= FesaLogger::error || FesaLogger::isInitPhase_)
00497 std::cout << pbase() << std::endl;
00498 }
00499 }
00500
00501
00502 pbump(-num);
00503 return std::streambuf::sync();
00504 }
00505
00506
00507
00508
00509
00510 int32_t FesaLoggerBuffer::overflow(int32_t c)
00511 {
00512
00513
00514 return (int32_t) '\0';
00515 }
00516
00517 }