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