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