From c76bf8e6a835a56b455a7008c201e996441fb6cd Mon Sep 17 00:00:00 2001 From: Ovidiu Mircescu Date: Mon, 4 Aug 2014 14:57:11 +0200 Subject: [PATCH] Send execution traces to a server. --- bin/CMakeLists.txt | 1 + bin/runSalome.py | 10 +++ bin/sendTraces.py | 113 ++++++++++++++++++++++++++++ src/Container/Container_i.cxx | 3 +- src/SALOMELocalTrace/CMakeLists.txt | 3 + src/SALOMELocalTrace/StucTrace.cxx | 51 +++++++++++++ src/SALOMELocalTrace/StucTrace.hxx | 51 +++++++++++++ 7 files changed, 231 insertions(+), 1 deletion(-) create mode 100755 bin/sendTraces.py create mode 100644 src/SALOMELocalTrace/StucTrace.cxx create mode 100644 src/SALOMELocalTrace/StucTrace.hxx diff --git a/bin/CMakeLists.txt b/bin/CMakeLists.txt index 455fc61e1..30d577485 100755 --- a/bin/CMakeLists.txt +++ b/bin/CMakeLists.txt @@ -54,6 +54,7 @@ SET(SCRIPTS salome_session.py salome_utils.py searchFreePort.py + sendTraces.py server.py setenv.py showNS.py diff --git a/bin/runSalome.py b/bin/runSalome.py index c819b857c..fd3cacb5b 100755 --- a/bin/runSalome.py +++ b/bin/runSalome.py @@ -33,6 +33,7 @@ from launchConfigureParser import verbose from server import process_id, Server import json import subprocess +import sendTraces # ----------------------------------------------------------------------------- @@ -236,6 +237,7 @@ class LoggerServer(Server): print logfile print "===========================================================" self.CMD=['SALOME_Logger_Server', logfile] + self.logfile = logfile pass pass # end of LoggerServer class @@ -480,9 +482,11 @@ def startSalome(args, modules_list, modules_root_dir): # and wait until it is registered in naming service # + sendTraces.logfile=None if args['logger']: myServer=LoggerServer(args) myServer.run() + sendTraces.logfile=myServer.logfile clt.waitLogger("Logger") # set siman python path before the session server launching to import scripts inside python console @@ -888,6 +892,12 @@ def foreGround(clt, args): from killSalomeWithPort import killMyPort killMyPort(port) pass + if not sendTraces.logfile is None: + try: + sendTraces.sendSalome(sendTraces.logfile) + except Exception as err: + print "sendTraces failed:" + print err return # diff --git a/bin/sendTraces.py b/bin/sendTraces.py new file mode 100755 index 000000000..16604d474 --- /dev/null +++ b/bin/sendTraces.py @@ -0,0 +1,113 @@ +#!/usr/bin/env python + +""" + This module is used to send execution traces to a server. +""" + +import sys +import os +import json +import urllib2 +import urllib + +class TracesSender(object): + """ + Collect and send STUC traces to a server. + """ + + def loadLogFile(self, filePath): + """ + Load STUC traces from a log file. + + STUC traces have this format: + [STUC TRACE]{ "label":"name","begin":"2014-07-24 14:18:45","end":"2014-07-24 14:18:47"} + + Lines which don't containt the flag "[STUC TRACE]" are ignored. + Between [STUC TRACE] and the end of the line, there should be + the trace data in json format. + """ + self.traces = [] + logFile = open(filePath) + flag = '[STUC TRACE]' + for line in logFile: + x, y, p = line.partition(flag) + if p != '': + trace = json.loads(p) + self.traces.append(trace) + pass + logFile.close() + pass + + def setInfo(self, appName, appVersion, installPath): + """ + Informations to join to the traces. + + :param appName: name of the current application + :param appVersion: version of the current application + :param installPath: installation path of the current application + """ + self.appName = appName + self.appVersion = appVersion + self.installPath = installPath + pass + + def send(self, serverUrl): + """ + Send STUC traces to a server. + + :param serverUrl: complet url where the traces should be sent + """ + session = {'appName' : self.appName, + 'appVersion' : self.appVersion, + 'installPath': self.installPath, + 'traces' : json.dumps(self.traces)} + dataToSend = urllib.urlencode(session) +# headers = {"Content-type": "application/x-www-form-urlencoded", +# "Accept": "text/plain"} +# req = urllib2.Request(serverUrl, dataToSend,headers ) + req = urllib2.Request(serverUrl, dataToSend) + response = urllib2.urlopen(req) + return response + + pass + +def sendSalome(logfilepath): + """ + TracesSender usecase for SALOME + """ + ts = TracesSender() + salome_path = os.getenv("ROOT_SALOME") + kernel_path = os.getenv('KERNEL_ROOT_DIR', '' ) + version_path = os.path.join(kernel_path, "bin", "salome", "VERSION") + version_file = open(version_path) + version = "unknown" + for line in version_file: + x, y, p = line.partition("[SALOME KERNEL] :") + if p != '': + version = p + break + pass + pass + + ts.setInfo("SALOME", version, salome_path) + ts.loadLogFile(logfilepath) + ts.send("http://localhost:8000/cgi-bin/traces.py") + +### MAIN ## +if __name__ == "__main__": + try: + serverUrl = sys.argv[1] + appName = sys.argv[2] + appVersion = sys.argv[3] + installPath = sys.argv[4] + logFile = sys.argv[5] + except: + print "usage:" + print " sendTraces.py " + exit() + pass + + ts = TracesSender() + ts.setInfo(appName, appVersion, installPath) + ts.loadLogFile(logFile) + ts.send(serverUrl) diff --git a/src/Container/Container_i.cxx b/src/Container/Container_i.cxx index a8a5f0147..d110b5c74 100644 --- a/src/Container/Container_i.cxx +++ b/src/Container/Container_i.cxx @@ -44,6 +44,7 @@ int SIGUSR1 = 1000; #endif #include "utilities.h" +#include "StucTrace.hxx" #include #include CORBA_SERVER_HEADER(SALOME_Component) #include CORBA_SERVER_HEADER(SALOME_Exception) @@ -396,7 +397,7 @@ void Engines_Container_i::Shutdown() bool Engines_Container_i::load_component_Library(const char* componentName, CORBA::String_out reason) { - + STUC_TRACE("load_component_Library: " << componentName) //================================================================= // --- C++ implementation section //================================================================= diff --git a/src/SALOMELocalTrace/CMakeLists.txt b/src/SALOMELocalTrace/CMakeLists.txt index 1be50d8f5..0e4cb5928 100755 --- a/src/SALOMELocalTrace/CMakeLists.txt +++ b/src/SALOMELocalTrace/CMakeLists.txt @@ -28,6 +28,7 @@ SET(COMMON_HEADERS LocalTraceBufferPool.hxx BaseTraceCollector.hxx SALOME_LocalTrace.hxx + StucTrace.hxx ) SET(SALOMELocalTrace_SOURCES @@ -40,6 +41,8 @@ SET(SALOMELocalTrace_SOURCES LocalTraceBufferPool.cxx LocalTraceBufferPool.hxx SALOME_LocalTrace.hxx + StucTrace.hxx + StucTrace.cxx ) ADD_LIBRARY(SALOMELocalTrace ${SALOMELocalTrace_SOURCES}) diff --git a/src/SALOMELocalTrace/StucTrace.cxx b/src/SALOMELocalTrace/StucTrace.cxx new file mode 100644 index 000000000..872247fc2 --- /dev/null +++ b/src/SALOMELocalTrace/StucTrace.cxx @@ -0,0 +1,51 @@ +#include "StucTrace.hxx" +#include +#include + +#include "LocalTraceBufferPool.hxx" + +StucTrace::StucTrace(const std::string& label) +: _label(label), + _beginTime(), + _endTime(), + _trace() +{ + begin(); +} + +StucTrace::~StucTrace() +{ +} + +void StucTrace::begin() +{ + time_t now = time(0); + struct tm tstruct = *localtime(&now); + strftime(_beginTime, sizeof(_beginTime), "%Y-%m-%d %X", &tstruct); +} + +void StucTrace::end() +{ + time_t now = time(0); + struct tm tstruct = *localtime(&now); + strftime(_endTime, sizeof(_endTime), "%Y-%m-%d %X", &tstruct); + + print(); +} + +const std::string& StucTrace::getTrace()const +{ + _trace = "[STUC TRACE]{\"label\":\""; + _trace += _label + "\",\"begin\":\""; + _trace += _beginTime; + _trace += "\",\"end\":\""; + _trace += _endTime; + _trace += "\"}"; + + return _trace; +} + +void StucTrace::print()const +{ + LocalTraceBufferPool::instance()->insert(NORMAL_MESS,(getTrace()+"\n").c_str()); +} diff --git a/src/SALOMELocalTrace/StucTrace.hxx b/src/SALOMELocalTrace/StucTrace.hxx new file mode 100644 index 000000000..57199f5c3 --- /dev/null +++ b/src/SALOMELocalTrace/StucTrace.hxx @@ -0,0 +1,51 @@ +#ifndef __STUC__TRACE__HXX__ +#define __STUC__TRACE__HXX__ + +#include + +/*! + * Print a timestamped and labeled trace. + * These traces will be recognised by sendTraces.py. + */ +class StucTrace +{ + public: + /*! + * Save the label and the begin time. + * The begin time can be changed later by begin(). + */ + StucTrace(const std::string& label); + + virtual ~StucTrace(); + + /*! + * Reset the begin time + */ + void begin(); + + /*! + * Save the end time and print the trace + */ + void end(); + + /*! + * Get the formated trace. + */ + const std::string& getTrace()const; + + /*! + * Overload this method in your derived class in order to define where + * the trace should be written. + */ + virtual void print()const; + + private: + std::string _label; + char _beginTime[64]; + char _endTime[64]; + mutable std::string _trace; +}; + +#define STUC_TRACE(label) std::ostringstream os; os << label; StucTrace t(os.str().c_str()); t.print(); + +#endif \ No newline at end of file -- 2.39.2