From d4d49581073bead9d674141961acd30b737ef7b3 Mon Sep 17 00:00:00 2001 From: aschwinn <al.schwinn@gsi.de> Date: Mon, 24 Jul 2017 13:21:30 +0200 Subject: [PATCH] [SIL-262] Review the SILECS logger to make it compliant with the CO-DO TRACING standarization fields --- .../communication/SilecsConnection.cpp | 62 +++++++++++++------ .../interface/core/SilecsService.cpp | 12 ++-- .../interface/equipment/SilecsCluster.cpp | 19 ++---- .../interface/equipment/SilecsCluster.h | 5 -- .../interface/equipment/SilecsPLC.cpp | 26 ++++---- .../interface/utility/SilecsLog.cpp | 33 +++++++--- .../interface/utility/SilecsLog.h | 9 +++ 7 files changed, 100 insertions(+), 66 deletions(-) diff --git a/silecs-communication-cpp/src/silecs-communication/interface/communication/SilecsConnection.cpp b/silecs-communication-cpp/src/silecs-communication/interface/communication/SilecsConnection.cpp index 77b3abc..b072532 100644 --- a/silecs-communication-cpp/src/silecs-communication/interface/communication/SilecsConnection.cpp +++ b/silecs-communication-cpp/src/silecs-communication/interface/communication/SilecsConnection.cpp @@ -143,14 +143,20 @@ namespace Silecs if (thePLC->isSharedConnection()) { - LOG((COMM|DIAG)) << "Shared connection with " << thePLC->getName() << " is established."; + std::ostringstream os; + os << "Shared connection with " << thePLC->getName() << " is established."; + if (thePLC->theHeader_ != NULL) TRACE("info") << os.str(); + LOG(COMM) << os.str(); } else { - LOG((COMM|DIAG)) << "Connection with " << thePLC->getName() << - ":" << thePLC->theCluster_->getClassName() << - "/v" << thePLC->theCluster_->getClassVersion() << - " is established."; + std::ostringstream os; + os << "Connection with " << thePLC->getName() << + ":" << thePLC->theCluster_->getClassName() << + "/v" << thePLC->theCluster_->getClassVersion() << + " is established."; + if (thePLC->theHeader_ != NULL) TRACE("info") << os.str(); + LOG(COMM) << os.str(); } isAlive_ = true; @@ -199,14 +205,20 @@ namespace Silecs if (thePLC->isSharedConnection()) { - LOG((COMM|DIAG)) << "Shared connection with " << thePLC->getName() << " is closed."; + std::ostringstream os; + os << "Shared connection with " << thePLC->getName() << " is closed."; + if (thePLC->theHeader_ != NULL) TRACE("warn") << os.str(); + LOG(COMM) << os.str(); } else { - LOG((COMM|DIAG)) << "Connection with " << thePLC->getName() << - " (" << thePLC->theCluster_->getClassName() << - "/v" << thePLC->theCluster_->getClassVersion() << - ")" << " is closed."; + std::ostringstream os; + os << "Connection with " << thePLC->getName() << + " (" << thePLC->theCluster_->getClassName() << + "/v" << thePLC->theCluster_->getClassVersion() << + ")" << " is closed."; + if (thePLC->theHeader_ != NULL) TRACE("warn") << os.str(); + LOG(COMM) << os.str(); } } else @@ -337,17 +349,27 @@ namespace Silecs : "Controller " + thePLC->getName() + " does not respond to ping, might be OFF!\n"; if (delayConn_ == LongTermConnection) - { if (remainConn_ > 0) - { LOG((COMM|DIAG)) << errorMsg << "Periodic attempt to reconnect, delay " << delayConn_ << "s (logging off)."; - remainConn_ = 1; //Try to reconnect again and again (=1 means disable logging). - } - else - { - LOG((COMM|DIAG)) << errorMsg << "PLC does not respond anymore. It's probably stopped for a long time. Trying to reconnect with long-term delay"; - } + { + if (remainConn_ > 0) + { + std::ostringstream os; + os << errorMsg << "Periodic attempt to reconnect, delay " << delayConn_ << "s (tracing off)."; + if (thePLC->theHeader_ != NULL) TRACE("error") << os.str(); + LOG(COMM) << os.str(); + remainConn_ = 1; //Try to reconnect again and again (=1 means disable tracing). + } + /*else + PLC does not respond anymore. It's probably stopped for a long time. + Do not log error anymore (but still try to reconnect, with long-term delay). + */ } - else - LOG((COMM|DIAG)) << errorMsg << "Next attempt to reconnect in " << delayConn_ << "s if requested. Remains: " << remainConn_; + else + { + std::ostringstream os; + os << errorMsg << "Next attempt to reconnect in " << delayConn_ << "s if requested. Remains: " << remainConn_; + if (thePLC->theHeader_ != NULL) TRACE("error") << os.str(); + LOG(COMM) << os.str(); + } } //------------------------------------------------------------------------------------------------------------------------------------------------ diff --git a/silecs-communication-cpp/src/silecs-communication/interface/core/SilecsService.cpp b/silecs-communication-cpp/src/silecs-communication/interface/core/SilecsService.cpp index 6256e28..0acc032 100644 --- a/silecs-communication-cpp/src/silecs-communication/interface/core/SilecsService.cpp +++ b/silecs-communication-cpp/src/silecs-communication/interface/core/SilecsService.cpp @@ -95,12 +95,12 @@ namespace Silecs if (instance_ == NULL) { instance_ = new Service(argc, argv); - LOG((ALLOC|DIAG)) << "SILECS Service create"; + LOG((ALLOC)) << "SILECS Service create"; XMLParser::init(); - //ACET start-up message (once per process) - TRACE("process") << "Version=" << semverMajor_ << "." << semverMinor_ << "." << semverPatch_; + //ACET start-up message (once per process) + TRACE("info") << "SILECS service startup: libsilecs-comm " << semverMajor_ << "." << semverMinor_ << "." << semverPatch_; } return instance_; } @@ -109,9 +109,11 @@ namespace Silecs { if (!isShutingDown_) { isShutingDown_ = true; - LOG((ALLOC|DIAG)) << "SILECS Resources release"; + LOG((ALLOC)) << "SILECS Resources release"; - XMLParser::init(); + TRACE("info") << "SILECS service shutdown: libsilecs-comm " << semverMajor_ << "." << semverMinor_ << "." << semverPatch_; + + XMLParser::cleanUp(); if (instance_ != NULL) delete instance_; instance_ = NULL; diff --git a/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsCluster.cpp b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsCluster.cpp index dd6afac..8bb5cf7 100644 --- a/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsCluster.cpp +++ b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsCluster.cpp @@ -38,18 +38,12 @@ namespace Silecs Cluster::Cluster(const std::string className, const std::string classVersion) : className_ (className), classVersion_ (classVersion) { - char hostName[128]; - if (gethostname(hostName, 128) == -1) - throw SilecsException(__FILE__, __LINE__, errno, strerror(errno)); - - //store the hostname by removing the domain-name (.cern.ch) if any. - hostName_ = std::string(hostName); - removeDomainName(hostName_); + hostName_ = Log::getHost(); //Default run-time configuration setup configuration.sharedConnection = false; //Do not shared connection with other clusters by default - LOG((ALLOC|DIAG)) << "CLUSTER (create): " << className_ << "/" << classVersion_; + LOG((ALLOC)) << "CLUSTER (create): " << className_ << "/" << classVersion_; } Cluster::~Cluster() @@ -65,11 +59,6 @@ namespace Silecs IPAddrMap_.clear(); //this map refer the same PLC object (not necessary to delete them) } - void Cluster::removeDomainName(std::string& hostName) - { size_t domain = hostName.find_first_of('.'); - if (domain != std::string::npos) hostName.erase(domain); - } - bool Cluster::getHostNameByAddress(const std::string IPAddress, std::string& hostName) { struct hostent *he = NULL; @@ -169,7 +158,9 @@ namespace Silecs if (!getAddressByHostName(hostName, IPAddress)) throw SilecsException(__FILE__, __LINE__, PARAM_UNKNOWN_PLC_HOSTNAME, hostName); } - removeDomainName(hostName); //remove ".cern.ch" if any + //remove domain name (.cern.ch) if any + size_t domain = hostName.find_first_of('.'); + if (domain != std::string::npos) hostName.erase(domain); //Then create the new instance of the PLC diff --git a/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsCluster.h b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsCluster.h index 866fc47..af88c07 100644 --- a/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsCluster.h +++ b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsCluster.h @@ -171,11 +171,6 @@ namespace Silecs */ ~Cluster(); - /*! - * \brief returns the input hostname without domain-name extension (cern.ch for instance) - */ - void removeDomainName(std::string& hostName); - bool getHostNameByAddress(const std::string IPAddress, std::string& hostName); bool getAddressByHostName(const std::string hostName, std::string& IPAddress); diff --git a/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsPLC.cpp b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsPLC.cpp index edc5896..0c49b45 100644 --- a/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsPLC.cpp +++ b/silecs-communication-cpp/src/silecs-communication/interface/equipment/SilecsPLC.cpp @@ -146,19 +146,19 @@ namespace Silecs //Warn ACET service that a new connection is established (except for SilecsHeader) if (theHeader_ != NULL) { - TRACE("cluster") << "ClassName=" << theCluster_->getClassName() << "|" << - "ClassVersion=" << theCluster_->getClassVersion() << "|" << - "Owner=" << localOwner_ << "|" << - "GenerationRelease=" << localRelease_ << "|" << - "GenerationDate=" << localDate_ << "|" << - "PlcChecksum=" << localChecksum_ << "|" << - "PlcDomain=" << domain_ << "|" << - "PlcHostname=" << name_ << "|" << - "PlcBrand=" << brand_ << "|" << - "PlcSystem=" << system_ << "|" << - "PlcModel=" << model_ << "|" << - "ProtocolAddress=" << baseAddr_ << "|" << - "ProtocolMode=" << protocolMode_ << "|" << + TRACE("info") << "Connection setup: ClassName=" << theCluster_->getClassName() << ", " << + "ClassVersion=" << theCluster_->getClassVersion() << ", " << + "Owner=" << localOwner_ << ", " << + "GenerationRelease=" << localRelease_ << ", " << + "GenerationDate=" << localDate_ << ", " << + "PlcChecksum=" << localChecksum_ << ", " << + "PlcDomain=" << domain_ << ", " << + "PlcHostname=" << name_ << ", " << + "PlcBrand=" << brand_ << ", " << + "PlcSystem=" << system_ << ", " << + "PlcModel=" << model_ << ", " << + "ProtocolAddress=" << baseAddr_ << ", " << + "ProtocolMode=" << protocolMode_ << ", " << "InstanceNumber=" << deviceCol_.size(); } }; diff --git a/silecs-communication-cpp/src/silecs-communication/interface/utility/SilecsLog.cpp b/silecs-communication-cpp/src/silecs-communication/interface/utility/SilecsLog.cpp index 0891e46..4177ded 100644 --- a/silecs-communication-cpp/src/silecs-communication/interface/utility/SilecsLog.cpp +++ b/silecs-communication-cpp/src/silecs-communication/interface/utility/SilecsLog.cpp @@ -16,9 +16,10 @@ #include <silecs-communication/interface/utility/SilecsLog.h> #include <silecs-communication/interface/utility/StringUtilities.h> #include <silecs-communication/interface/utility/TimeStamp.h> +#include <silecs-communication/interface/utility/SilecsException.h> #include <syslog.h> #include <string.h> - +#include <errno.h> namespace Silecs { @@ -30,6 +31,10 @@ namespace Silecs unsigned long Log::topics_ = 0; unsigned long Log::systopics_ = TRACE|DIAG; + std::string Log::host_ = ""; + pid_t Log::pid_ = -1; + std::string Log::process_ = ""; + bool Log::syslogIsStarted_ = false; //syslog not yet started TsCounter Log::timeStamp_(true); @@ -72,7 +77,6 @@ namespace Silecs } //Return false if topic parameters are not correct or empty - //if (!(wrongTopic || topicCol.size()==0)) // replaced for performance if (!(wrongTopic || topicCol.empty())) { topics_ = topicsTemp; @@ -99,12 +103,11 @@ namespace Silecs return os; } - std::ostringstream& Log::getTrace(std::string source) - { - os << "Environment=prod|MessageType=static|MessageSeverity=info|SenderType=library|SenderDomain=silecs|SenderSubdomain=client|"; - os << "SenderSource=" << source << "||"; - return os; - } + std::ostringstream& Log::getTrace(std::string level) + { + os << "host=" << getHost() << ",level=" << level << ",pid=" << getPid() << ",system=SILECS" << ",subsystem=libsilecs-comm" << ",process=" << getProcess() << ",body="; + return os; + } std::ostringstream& Log::getLogDelay() { @@ -139,7 +142,19 @@ namespace Silecs { if (!syslogIsStarted_) { - systopics_ |= topics; + char hostName[128]; + if (gethostname(hostName, 128) == -1) + throw SilecsException(__FILE__, __LINE__, errno, strerror(errno)); + + //remove domain name (.cern.ch) if any + host_ = std::string(hostName); + size_t domain = host_.find_first_of('.'); + if (domain != std::string::npos) host_.erase(domain); + + pid_ = getpid(); + process_ = std::string(ident); + + systopics_ |= topics; /* syslog service uses file configuration (required root access): * /etc/<syslog.conf> : to define the ouput channel (file, console, host) diff --git a/silecs-communication-cpp/src/silecs-communication/interface/utility/SilecsLog.h b/silecs-communication-cpp/src/silecs-communication/interface/utility/SilecsLog.h index bf0ae83..b5cd5f9 100644 --- a/silecs-communication-cpp/src/silecs-communication/interface/utility/SilecsLog.h +++ b/silecs-communication-cpp/src/silecs-communication/interface/utility/SilecsLog.h @@ -89,6 +89,10 @@ namespace Silecs static void startSyslog(char* ident, unsigned long systopics); static void stopSyslog(); + static std::string& getHost() { return host_; } + static pid_t& getPid() { return pid_; } + static std::string& getProcess() { return process_; } + // return valid log arguments as string: '-plcLog topic1[,topic2,..]' static std::string getLogArguments(); @@ -101,11 +105,16 @@ namespace Silecs static unsigned long systopics_;//set of topics to be logged using the syslog mechanism private: + friend class SilecsService; + Log(const Log&); Log& operator =(const Log&); std::ostringstream os; static TsCounter timeStamp_; static bool syslogIsStarted_; + static std::string host_; + static pid_t pid_; + static std::string process_; }; } // namespace -- GitLab