00001 #include "CondCore/DBCommon/interface/Logger.h"
00002 #include "CondCore/DBCommon/interface/LogDBEntry.h"
00003 #include "CondCore/DBCommon/interface/UserLogInfo.h"
00004 #include "CondCore/DBCommon/interface/CoralTransaction.h"
00005 #include "CondCore/DBCommon/interface/SequenceManager.h"
00006 #include "CondCore/DBCommon/interface/TokenInterpreter.h"
00007 #include "CondCore/DBCommon/interface/Connection.h"
00008 #include "CondCore/DBCommon/interface/Exception.h"
00009 #include "RelationalAccess/ISchema.h"
00010 #include "RelationalAccess/ITable.h"
00011 #include "RelationalAccess/ITableDataEditor.h"
00012 #include "RelationalAccess/IQuery.h"
00013 #include "RelationalAccess/ICursor.h"
00014 #include "RelationalAccess/TableDescription.h"
00015 #include "RelationalAccess/ITablePrivilegeManager.h"
00016 #include "CoralBase/Attribute.h"
00017 #include "CoralBase/AttributeList.h"
00018 #include "CoralBase/AttributeSpecification.h"
00019 #include "LogDBNames.h"
00020 #include <boost/date_time/posix_time/posix_time_types.hpp>
00021
00022 #include <sstream>
00023 #include <exception>
00024 namespace cond{
00025 template <class T>
00026 std::string to_string(const T& t){
00027 std::stringstream ss;
00028 ss<<t;
00029 return ss.str();
00030 }
00031 }
00032 cond::Logger::Logger(cond::Connection* connectionHandle):m_connectionHandle(connectionHandle),m_coraldb(connectionHandle->coralTransaction()),m_locked(false),m_statusEditorHandle(0),m_sequenceManager(0),m_logTableExists(false){
00033 }
00034 bool
00035 cond::Logger::getWriteLock()throw() {
00036 try{
00037 m_coraldb.start(false);
00038 coral::ITable& statusTable=m_coraldb.nominalSchema().tableHandle(LogDBNames::LogTableName());
00039
00040 m_statusEditorHandle=statusTable.newQuery();
00041 m_statusEditorHandle->setForUpdate();
00042 m_statusEditorHandle->execute();
00043 }catch(const std::exception& er){
00044 delete m_statusEditorHandle;
00045 m_statusEditorHandle=0;
00046 return false;
00047 }
00048 m_locked=true;
00049 return true;
00050 }
00051 bool
00052 cond::Logger::releaseWriteLock()throw() {
00053 if(m_locked){
00054 delete m_statusEditorHandle;
00055 m_statusEditorHandle=0;
00056 }
00057 m_locked=false;
00058 m_coraldb.commit();
00059 return !m_locked;
00060 }
00061 void
00062 cond::Logger::createLogDBIfNonExist(){
00063 if(m_logTableExists) return;
00064 m_coraldb.start(false);
00065 if(m_coraldb.nominalSchema().existsTable(cond::LogDBNames::SequenceTableName())&&m_coraldb.nominalSchema().existsTable(cond::LogDBNames::LogTableName())){
00066 m_logTableExists=true;
00067 m_coraldb.commit();
00068 return;
00069 }
00070
00071 cond::SequenceManager sequenceGenerator(m_coraldb,cond::LogDBNames::SequenceTableName());
00072 if( !sequenceGenerator.existSequencesTable() ){
00073 sequenceGenerator.createSequencesTable();
00074 }
00075
00076 coral::TableDescription description( "CONDLOG" );
00077 description.setName(cond::LogDBNames::LogTableName());
00078 description.insertColumn(std::string("LOGID"),
00079 coral::AttributeSpecification::typeNameForType<unsigned long long>() );
00080 description.setPrimaryKey( std::vector<std::string>( 1, std::string("LOGID")));
00081 description.insertColumn(std::string("EXECTIME"),
00082 coral::AttributeSpecification::typeNameForType<std::string>() );
00083 description.setNotNullConstraint(std::string("EXECTIME"));
00084
00085 description.insertColumn(std::string("IOVTAG"),
00086 coral::AttributeSpecification::typeNameForType<std::string>() );
00087 description.setNotNullConstraint(std::string("IOVTAG"));
00088
00089 description.insertColumn(std::string("IOVTIMETYPE"),
00090 coral::AttributeSpecification::typeNameForType<std::string>() );
00091 description.setNotNullConstraint(std::string("IOVTIMETYPE"));
00092
00093 description.insertColumn(std::string("PAYLOADCONTAINER"),
00094 coral::AttributeSpecification::typeNameForType<std::string>() );
00095 description.setNotNullConstraint(std::string("PAYLOADCONTAINER"));
00096
00097 description.insertColumn(std::string("PAYLOADNAME"),
00098 coral::AttributeSpecification::typeNameForType<std::string>() );
00099 description.setNotNullConstraint(std::string("PAYLOADNAME"));
00100
00101 description.insertColumn(std::string("PAYLOADTOKEN"),
00102 coral::AttributeSpecification::typeNameForType<std::string>() );
00103 description.setNotNullConstraint(std::string("PAYLOADTOKEN"));
00104
00105 description.insertColumn(std::string("PAYLOADINDEX"),
00106 coral::AttributeSpecification::typeNameForType<unsigned int>() );
00107 description.setNotNullConstraint(std::string("PAYLOADINDEX"));
00108
00109 description.insertColumn(std::string("DESTINATIONDB"),
00110 coral::AttributeSpecification::typeNameForType<std::string>() );
00111 description.setNotNullConstraint(std::string("DESTINATIONDB"));
00112
00113 description.insertColumn(std::string("PROVENANCE"),
00114 coral::AttributeSpecification::typeNameForType<std::string>() );
00115 description.insertColumn(std::string("USERTEXT"),
00116 coral::AttributeSpecification::typeNameForType<std::string>() );
00117 description.insertColumn(std::string("EXECMESSAGE"),
00118 coral::AttributeSpecification::typeNameForType<std::string>() );
00119 m_coraldb.nominalSchema().createTable( description ).privilegeManager().grantToPublic( coral::ITablePrivilegeManager::Select );
00120 m_logTableExists=true;
00121 m_coraldb.commit();
00122 }
00123 void
00124 cond::Logger::logOperationNow(
00125 const cond::UserLogInfo& userlogInfo,
00126 const std::string& destDB,
00127 const std::string& payloadToken,
00128 const std::string& iovtag,
00129 const std::string& iovtimetype,
00130 unsigned int payloadIdx
00131 ){
00132
00133
00134 boost::posix_time::ptime p=boost::posix_time::microsec_clock::local_time();
00135 std::string now=cond::to_string(p.date().year())+"-"+cond::to_string(p.date().month())+"-"+cond::to_string(p.date().day())+"-"+cond::to_string(p.time_of_day().hours())+":"+cond::to_string(p.time_of_day().minutes())+":"+cond::to_string(p.time_of_day().seconds());
00136
00137 if(!m_sequenceManager){
00138 m_sequenceManager=new cond::SequenceManager(m_coraldb,cond::LogDBNames::SequenceTableName());
00139 }
00140 unsigned long long targetLogId=m_sequenceManager->incrementId(LogDBNames::LogTableName());
00141
00142 this->insertLogRecord(targetLogId,now,destDB,payloadToken,userlogInfo,iovtag,iovtimetype,payloadIdx,"OK");
00143 }
00144 void
00145 cond::Logger::logFailedOperationNow(
00146 const cond::UserLogInfo& userlogInfo,
00147 const std::string& destDB,
00148 const std::string& payloadToken,
00149 const std::string& iovtag,
00150 const std::string& iovtimetype,
00151 unsigned int payloadIdx,
00152 const std::string& exceptionMessage
00153 ){
00154
00155 boost::posix_time::ptime p=boost::posix_time::microsec_clock::local_time();
00156 std::string now=cond::to_string(p.date().year())+"-"+cond::to_string(p.date().month())+"-"+cond::to_string(p.date().day())+"-"+cond::to_string(p.time_of_day().hours())+":"+cond::to_string(p.time_of_day().minutes())+":"+cond::to_string(p.time_of_day().seconds());
00157
00158 if(!m_sequenceManager){
00159 m_sequenceManager=new cond::SequenceManager(m_coraldb,cond::LogDBNames::SequenceTableName());
00160 }
00161 unsigned long long targetLogId=m_sequenceManager->incrementId(LogDBNames::LogTableName());
00162
00163 this->insertLogRecord(targetLogId,now,destDB,payloadToken,userlogInfo,iovtag,iovtimetype,payloadIdx,exceptionMessage);
00164 }
00165
00166 void
00167 cond::Logger::LookupLastEntryByProvenance(const std::string& provenance,
00168 LogDBEntry& logentry,
00169 bool filterFailedOp) const{
00170
00171
00172 std::string whereClause=cond::LogDBNames::LogTableName();
00173 whereClause+=".PROVENANCE=:provenance";
00174 if(filterFailedOp){
00175 whereClause+=std::string(" AND ");
00176 whereClause+=cond::LogDBNames::LogTableName();
00177 whereClause+=std::string(".EXECMESSAGE=:execmessage");
00178 }
00179 coral::AttributeList BindVariableList;
00180 BindVariableList.extend("provenance",typeid(std::string) );
00181 BindVariableList.extend("execmessage",typeid(std::string) );
00182 BindVariableList["provenance"].data<std::string>()=provenance;
00183 BindVariableList["execmessage"].data<std::string>()="OK";
00184 m_coraldb.start(true);
00185 coral::IQuery* query = m_coraldb.nominalSchema().newQuery();
00186
00187 query->addToOutputList( cond::LogDBNames::LogTableName()+".LOGID" );
00188 query->defineOutputType( cond::LogDBNames::LogTableName()+".LOGID", "unsigned long long" );
00189 query->addToOutputList( cond::LogDBNames::LogTableName()+".DESTINATIONDB" );
00190 query->addToOutputList( cond::LogDBNames::LogTableName()+".PROVENANCE" );
00191 query->addToOutputList( cond::LogDBNames::LogTableName()+".USERTEXT" );
00192 query->addToOutputList( cond::LogDBNames::LogTableName()+".IOVTAG" );
00193 query->addToOutputList( cond::LogDBNames::LogTableName()+".IOVTIMETYPE" );
00194 query->addToOutputList( cond::LogDBNames::LogTableName()+".PAYLOADINDEX" );
00195 query->defineOutputType( cond::LogDBNames::LogTableName()+".PAYLOADINDEX", "unsigned int" );
00196 query->addToOutputList( cond::LogDBNames::LogTableName()+".PAYLOADNAME" );
00197 query->addToOutputList( cond::LogDBNames::LogTableName()+".PAYLOADTOKEN" );
00198 query->addToOutputList( cond::LogDBNames::LogTableName()+".PAYLOADCONTAINER" );
00199 query->addToOutputList( cond::LogDBNames::LogTableName()+".EXECTIME" );
00200 query->addToOutputList( cond::LogDBNames::LogTableName()+".EXECMESSAGE" );
00201
00202 coral::IQueryDefinition& subquery=query->defineSubQuery("subQ");
00203 query->addToTableList("subQ");
00204 query->addToTableList(cond::LogDBNames::LogTableName());
00205 subquery.addToTableList( cond::LogDBNames::LogTableName() );
00206 subquery.addToOutputList( "max(LOGID)", "max_logid");
00207 subquery.setCondition( whereClause, BindVariableList );
00208 query->setCondition(cond::LogDBNames::LogTableName()+std::string(".LOGID=subQ.max_logid"),coral::AttributeList() );
00209 query->defineOutputType( "subQ.max_logid", "unsigned long long" );
00210
00211 coral::ICursor& cursor = query->execute();
00212 if( cursor.next() ) {
00213 const coral::AttributeList& row = cursor.currentRow();
00214 logentry.logId=row[cond::LogDBNames::LogTableName()+".LOGID"].data<unsigned long long>();
00215 logentry.destinationDB=row[cond::LogDBNames::LogTableName()+".DESTINATIONDB"].data<std::string>();
00216 logentry.provenance=row[cond::LogDBNames::LogTableName()+".PROVENANCE"].data<std::string>();
00217 logentry.usertext=row[cond::LogDBNames::LogTableName()+".USERTEXT"].data<std::string>();
00218 logentry.iovtag=row[cond::LogDBNames::LogTableName()+".IOVTAG"].data<std::string>();
00219 logentry.iovtimetype=row[cond::LogDBNames::LogTableName()+".IOVTIMETYPE"].data<std::string>();
00220 logentry.payloadIdx=row[cond::LogDBNames::LogTableName()+".PAYLOADINDEX"].data<unsigned int>();
00221 logentry.payloadName=row[cond::LogDBNames::LogTableName()+".PAYLOADNAME"].data<std::string>();
00222 logentry.payloadToken=row[cond::LogDBNames::LogTableName()+".PAYLOADTOKEN"].data<std::string>();
00223 logentry.payloadContainer=row[cond::LogDBNames::LogTableName()+".PAYLOADCONTAINER"].data<std::string>();
00224 logentry.exectime=row[cond::LogDBNames::LogTableName()+".EXECTIME"].data<std::string>();
00225 logentry.execmessage=row[cond::LogDBNames::LogTableName()+".EXECMESSAGE"].data<std::string>();
00226
00227
00228 }
00229 delete query;
00230 m_coraldb.commit();
00231 }
00232 void
00233 cond::Logger::LookupLastEntryByTag( const std::string& iovtag,
00234 const std::string & connectionStr,
00235 cond::LogDBEntry& logentry,
00236 bool filterFailedOp) const{
00241 std::string whereClause=cond::LogDBNames::LogTableName();
00242 whereClause+=std::string(".IOVTAG=:iovtag");
00243 coral::AttributeList BindVariableList;
00244 BindVariableList.extend("iovtag",typeid(std::string) );
00245 BindVariableList["iovtag"].data<std::string>()=iovtag;
00246 if(connectionStr!=""){
00247 whereClause+=std::string(" AND ");
00248 whereClause+=cond::LogDBNames::LogTableName();
00249 whereClause+=std::string(".DESTINATIONDB=:destinationdb");
00250 BindVariableList.extend("destinationdb",typeid(std::string) );
00251 BindVariableList["destinationdb"].data<std::string>()=connectionStr;
00252 }
00253 if(filterFailedOp){
00254 whereClause+=std::string(" AND ");
00255 whereClause+=cond::LogDBNames::LogTableName();
00256 whereClause+=std::string(".EXECMESSAGE=:execmessage");
00257 BindVariableList.extend("execmessage",typeid(std::string) );
00258 BindVariableList["execmessage"].data<std::string>()="OK";
00259 }
00260
00261 m_coraldb.start(true);
00262
00263 coral::IQuery* query = m_coraldb.nominalSchema().newQuery();
00264
00265 query->addToOutputList( cond::LogDBNames::LogTableName()+".LOGID" );
00266 query->defineOutputType( cond::LogDBNames::LogTableName()+".LOGID", "unsigned long long" );
00267 query->addToOutputList( cond::LogDBNames::LogTableName()+".DESTINATIONDB" );
00268 query->addToOutputList( cond::LogDBNames::LogTableName()+".PROVENANCE" );
00269 query->addToOutputList( cond::LogDBNames::LogTableName()+".USERTEXT" );
00270 query->addToOutputList( cond::LogDBNames::LogTableName()+".IOVTAG" );
00271 query->addToOutputList( cond::LogDBNames::LogTableName()+".IOVTIMETYPE" );
00272 query->addToOutputList( cond::LogDBNames::LogTableName()+".PAYLOADINDEX" );
00273 query->defineOutputType( cond::LogDBNames::LogTableName()+".PAYLOADINDEX", "unsigned int" );
00274 query->addToOutputList( cond::LogDBNames::LogTableName()+".PAYLOADNAME" );
00275 query->addToOutputList( cond::LogDBNames::LogTableName()+".PAYLOADTOKEN" );
00276 query->addToOutputList( cond::LogDBNames::LogTableName()+".PAYLOADCONTAINER" );
00277 query->addToOutputList( cond::LogDBNames::LogTableName()+".EXECTIME" );
00278 query->addToOutputList( cond::LogDBNames::LogTableName()+".EXECMESSAGE" );
00279
00280 coral::IQueryDefinition& subquery=query->defineSubQuery("subQ");
00281 query->addToTableList("subQ");
00282 query->addToTableList(cond::LogDBNames::LogTableName());
00283 subquery.addToTableList( cond::LogDBNames::LogTableName() );
00284 subquery.addToOutputList( "max(LOGID)", "max_logid");
00285 subquery.setCondition( whereClause, BindVariableList );
00286 query->setCondition(cond::LogDBNames::LogTableName()+std::string(".LOGID=subQ.max_logid"),coral::AttributeList() );
00287 query->defineOutputType( "subQ.max_logid", "unsigned long long" );
00288
00289 coral::ICursor& cursor = query->execute();
00290 if( cursor.next() ) {
00291 const coral::AttributeList& row = cursor.currentRow();
00292 logentry.logId=row[cond::LogDBNames::LogTableName()+".LOGID"].data<unsigned long long>();
00293 logentry.destinationDB=row[cond::LogDBNames::LogTableName()+".DESTINATIONDB"].data<std::string>();
00294 logentry.provenance=row[cond::LogDBNames::LogTableName()+".PROVENANCE"].data<std::string>();
00295 logentry.usertext=row[cond::LogDBNames::LogTableName()+".USERTEXT"].data<std::string>();
00296 logentry.iovtag=row[cond::LogDBNames::LogTableName()+".IOVTAG"].data<std::string>();
00297 logentry.iovtimetype=row[cond::LogDBNames::LogTableName()+".IOVTIMETYPE"].data<std::string>();
00298 logentry.payloadIdx=row[cond::LogDBNames::LogTableName()+".PAYLOADINDEX"].data<unsigned int>();
00299 logentry.payloadName=row[cond::LogDBNames::LogTableName()+".PAYLOADNAME"].data<std::string>();
00300 logentry.payloadToken=row[cond::LogDBNames::LogTableName()+".PAYLOADTOKEN"].data<std::string>();
00301 logentry.payloadContainer=row[cond::LogDBNames::LogTableName()+".PAYLOADCONTAINER"].data<std::string>();
00302 logentry.exectime=row[cond::LogDBNames::LogTableName()+".EXECTIME"].data<std::string>();
00303 logentry.execmessage=row[cond::LogDBNames::LogTableName()+".EXECMESSAGE"].data<std::string>();
00304
00305
00306 }
00307 delete query;
00308 m_coraldb.commit();
00309 }
00310 void
00311 cond::Logger::LookupLastEntryByTag( const std::string& iovtag,
00312 LogDBEntry& logentry,
00313 bool filterFailedOp ) const{
00314 LookupLastEntryByTag(iovtag,"",logentry,filterFailedOp);
00315 }
00316 void
00317 cond::Logger::insertLogRecord(unsigned long long logId,
00318 const std::string& localtime,
00319 const std::string& destDB,
00320 const std::string& payloadToken,
00321 const cond::UserLogInfo& userLogInfo,
00322 const std::string& iovtag,
00323 const std::string& iovtimetype,
00324 unsigned int payloadIdx,
00325 const std::string& exceptionMessage){
00326 try{
00327 cond::TokenInterpreter tokenteller(payloadToken);
00328 std::string containerName=tokenteller.containerName();
00329 std::string payloadName=tokenteller.className();
00330 coral::AttributeList rowData;
00331 rowData.extend<unsigned long long>("LOGID");
00332 rowData.extend<std::string>("EXECTIME");
00333 rowData.extend<std::string>("PAYLOADCONTAINER");
00334 rowData.extend<std::string>("DESTINATIONDB");
00335 rowData.extend<std::string>("PAYLOADNAME");
00336 rowData.extend<std::string>("PAYLOADTOKEN");
00337 rowData.extend<std::string>("PROVENANCE");
00338 rowData.extend<std::string>("USERTEXT");
00339 rowData.extend<std::string>("IOVTAG");
00340 rowData.extend<std::string>("IOVTIMETYPE");
00341 rowData.extend<unsigned int>("PAYLOADINDEX");
00342 rowData.extend<std::string>("EXECMESSAGE");
00343 rowData["LOGID"].data< unsigned long long >() = logId;
00344 rowData["EXECTIME"].data< std::string >() = localtime;
00345 rowData["PAYLOADCONTAINER"].data< std::string >() = containerName;
00346 rowData["DESTINATIONDB"].data< std::string >() = destDB;
00347 rowData["PAYLOADNAME"].data< std::string >() = payloadName;
00348 rowData["PAYLOADTOKEN"].data< std::string >() = payloadToken;
00349 rowData["PROVENANCE"].data< std::string >() = userLogInfo.provenance;
00350 rowData["USERTEXT"].data< std::string >() = userLogInfo.usertext;
00351 rowData["IOVTAG"].data< std::string >() = iovtag;
00352 rowData["IOVTIMETYPE"].data< std::string >() = iovtimetype;
00353 rowData["PAYLOADINDEX"].data< unsigned int >() = payloadIdx;
00354 rowData["EXECMESSAGE"].data< std::string >() = exceptionMessage;
00355 m_coraldb.nominalSchema().tableHandle(cond::LogDBNames::LogTableName()).dataEditor().insertRow(rowData);
00356 }catch(const std::exception& er){
00357 throw cond::Exception(std::string(er.what()));
00358 }
00359 }
00360
00361 cond::Logger::~Logger(){
00362 if( m_sequenceManager ){
00363 delete m_sequenceManager;
00364 m_sequenceManager=0;
00365 }
00366 }