Go to the documentation of this file.00001 #include "CondCore/ORA/interface/Monitoring.h"
00002
00003 #include "uuid/uuid.h"
00004
00005 #include <string.h>
00006 #include <cstdlib>
00007 #include <fstream>
00008
00009 namespace ora {
00010 static char const* fmt_Guid =
00011 "%08lX-%04hX-%04hX-%02hhX%02hhX-%02hhX%02hhX%02hhX%02hhX%02hhX%02hhX";
00012
00013 std::string guidFromTime(){
00014 uuid_t me_;
00015 ::uuid_generate_time(me_);
00016 unsigned int* tmp = reinterpret_cast<unsigned int*>(me_);
00017 unsigned int d1 = *tmp;
00018 unsigned short d2 = *reinterpret_cast<unsigned short*>(me_+4);
00019 unsigned short d3 = *reinterpret_cast<unsigned short*>(me_+6);
00020 unsigned char d4[8];
00021 for (int i = 0; i < 8; ++i){
00022 d4[i]=me_[i+8];
00023 }
00024
00025 char text[128];
00026 ::sprintf(text, fmt_Guid,
00027 d1, d2, d3,
00028 d4[0], d4[1], d4[2], d4[3],
00029 d4[4], d4[5], d4[6], d4[7]);
00030 return std::string(text);
00031 }
00032 }
00033
00034 ora::TransactionMonitoringData::TransactionMonitoringData( boost::posix_time::ptime start ):
00035 m_start(start),
00036 m_stop(boost::posix_time::neg_infin),
00037 m_status(false){
00038 }
00039
00040 void ora::TransactionMonitoringData::stop(bool commit_status){
00041 m_stop = boost::posix_time::microsec_clock::universal_time();
00042 m_status = commit_status;
00043 }
00044
00045 ora::SessionMonitoringData::SessionMonitoringData( boost::posix_time::ptime start, const std::string& connectionString ):
00046 m_connectionString( connectionString ),
00047 m_start(start),
00048 m_stop(boost::posix_time::neg_infin),
00049 m_currentTransaction(0),
00050 m_transactions(),
00051 m_ncur(0){
00052 }
00053
00054 ora::SessionMonitoringData::~SessionMonitoringData(){
00055 for(std::map<std::string,TransactionMonitoringData*>::const_iterator iT = m_transactions.begin();
00056 iT != m_transactions.end();iT++ ){
00057 delete iT->second;
00058 }
00059 }
00060
00061 size_t ora::SessionMonitoringData::newTransaction(){
00062 m_currentTransaction = new TransactionMonitoringData( boost::posix_time::microsec_clock::universal_time() );
00063 m_transactions.insert(std::make_pair(guidFromTime(),m_currentTransaction));
00064 m_ncur = m_transactions.size();
00065 return m_ncur;
00066 }
00067
00068 size_t ora::SessionMonitoringData::stopTransaction( bool commit_status ){
00069 size_t ncur = 0;
00070 if(m_currentTransaction){
00071 m_currentTransaction->stop( commit_status );
00072 m_currentTransaction = 0;
00073 ncur = m_ncur;
00074 m_ncur = 0;
00075 }
00076 return ncur;
00077 }
00078
00079 void ora::SessionMonitoringData::stop(){
00080 m_stop = boost::posix_time::microsec_clock::universal_time();
00081 m_currentTransaction = 0;
00082 m_ncur = 0;
00083 }
00084
00085 size_t ora::SessionMonitoringData::numberOfTransactions() const{
00086 return m_transactions.size();
00087 }
00088
00089 void ora::SessionMonitoringData::report( std::ostream& out ) const {
00090 size_t i=1;
00091 for(std::map<std::string,TransactionMonitoringData*>::const_iterator iT = m_transactions.begin();
00092 iT != m_transactions.end();iT++ ){
00093 TransactionMonitoringData& data = *iT->second;
00094 boost::posix_time::time_duration duration;
00095 if( !data.m_stop.is_neg_infinity() ){
00096 duration = data.m_stop-data.m_start;
00097 }
00098 out <<" -> Transaction #"<<i<<" duration="<<boost::posix_time::to_simple_string(duration)<<" status="<<(data.m_status?std::string("COMMIT"):std::string("ROLLBACK"))<<std::endl;
00099 i++;
00100 }
00101 }
00102
00103 bool ora::Monitoring::s_enabled = false;
00104
00105 ora::Monitoring& ora::Monitoring::get(){
00106 static ora::Monitoring s_mon;
00107 return s_mon;
00108 }
00109
00110 bool ora::Monitoring::isEnabled(){
00111 if(! s_enabled ){
00112 const char* envVar = ::getenv( "ORA_MONITORING_LEVEL" );
00113 if( envVar && ::strcmp(envVar,"SESSION")==0 ) s_enabled = true;
00114 }
00115 return s_enabled;
00116 }
00117
00118 void ora::Monitoring::enable(){
00119 s_enabled = true;
00120 }
00121
00122 std::string& ora::Monitoring::outFileName(){
00123 static std::string s_outFileName("");
00124 if( s_outFileName.empty() ){
00125 const char* fileEnvVar = ::getenv( "ORA_MONITORING_FILE" );
00126 if( fileEnvVar ){
00127 s_outFileName = fileEnvVar;
00128 }
00129 }
00130 return s_outFileName;
00131 }
00132
00133 ora::Monitoring::~Monitoring() throw(){
00134 if( isEnabled() ){
00135 try {
00136 if( !outFileName().empty() ){
00137 std::ofstream outFile;
00138 outFile.open( outFileName().c_str() );
00139 if(outFile.good()){
00140 report( outFile );
00141 outFile.flush();
00142 }
00143 outFile.close();
00144
00145 } else {
00146 report( std::cout );
00147 }
00148 } catch ( const std::exception& e ){
00149 std::cout <<"ORA_MONITORING Error: "<<e.what()<<std::endl;
00150 }
00151 }
00152
00153 for(std::map<std::string,SessionMonitoringData*>::const_iterator iS = m_sessions.begin();
00154 iS != m_sessions.end();iS++ ){
00155 delete iS->second;
00156 }
00157 }
00158
00159 ora::SessionMonitoringData* ora::Monitoring::startSession( const std::string& connectionString ){
00160 ora::SessionMonitoringData* ret = new SessionMonitoringData( boost::posix_time::microsec_clock::universal_time(), connectionString );
00161 m_sessions.insert(std::make_pair(guidFromTime(),ret));
00162 return ret;
00163 }
00164
00165 void ora::Monitoring::report( std::ostream& out ){
00166 out << "### ---------------------------------------------------------------------- "<<std::endl;
00167 out << "### ORA Monitoring Summary "<<std::endl;
00168 out << "### "<<m_sessions.size()<<" session(s) registered."<<std::endl;
00169 size_t j = 1;
00170 for( std::map<std::string,SessionMonitoringData*>::const_iterator iS = m_sessions.begin();
00171 iS != m_sessions.end(); ++iS ){
00172 SessionMonitoringData& data = *iS->second;
00173 boost::posix_time::time_duration duration;
00174 if( !data.m_stop.is_neg_infinity() ){
00175 duration = data.m_stop-data.m_start;
00176 }
00177 out <<" -> Session #"<<j<<": connection=\""<<data.m_connectionString<<"\" duration="<<boost::posix_time::to_simple_string(duration)<<" transactions="<<(iS->second)->numberOfTransactions()<<std::endl;
00178 (iS->second)->report(out);
00179 j++;
00180 }
00181 out << "### ---------------------------------------------------------------------- "<<std::endl;
00182
00183 }
00184
00185 ora::Monitoring::Monitoring():
00186 m_sessions(){
00187 }