00001 #include "CondCore/DBCommon/interface/Logger.h"
00002 #include "CondCore/DBCommon/interface/LogDBEntry.h"
00003 #include "CondCore/DBCommon/interface/SequenceManager.h"
00004 #include "CondCore/DBCommon/interface/DbTransaction.h"
00005 #include "CondCore/DBCommon/interface/DbScopedTransaction.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
00034 void
00035 cond::Logger::createLogDBIfNonExist(){
00036 if(m_logTableExists) return;
00037 cond::DbScopedTransaction trans( m_sessionHandle );
00038 trans.start(false);
00039 if(m_sessionHandle.nominalSchema().existsTable(cond::LogDBNames::SequenceTableName()) &&
00040 m_sessionHandle.nominalSchema().existsTable(cond::LogDBNames::LogTableName())){
00041 m_logTableExists=true;
00042 trans.commit();
00043 return;
00044 }
00045
00046 cond::SequenceManager sequenceGenerator(m_sessionHandle,cond::LogDBNames::SequenceTableName());
00047 if( !sequenceGenerator.existSequencesTable() ){
00048 sequenceGenerator.createSequencesTable();
00049 }
00050
00051 coral::TableDescription description( "CONDLOG" );
00052 description.setName(cond::LogDBNames::LogTableName());
00053 description.insertColumn(std::string("LOGID"),
00054 coral::AttributeSpecification::typeNameForType<unsigned long long>() );
00055 description.setPrimaryKey( std::vector<std::string>( 1, std::string("LOGID")));
00056 description.insertColumn(std::string("EXECTIME"),
00057 coral::AttributeSpecification::typeNameForType<std::string>() );
00058 description.setNotNullConstraint(std::string("EXECTIME"));
00059
00060 description.insertColumn(std::string("IOVTAG"),
00061 coral::AttributeSpecification::typeNameForType<std::string>() );
00062 description.setNotNullConstraint(std::string("IOVTAG"));
00063
00064 description.insertColumn(std::string("IOVTIMETYPE"),
00065 coral::AttributeSpecification::typeNameForType<std::string>() );
00066 description.setNotNullConstraint(std::string("IOVTIMETYPE"));
00067
00068 description.insertColumn(std::string("PAYLOADCLASS"),
00069 coral::AttributeSpecification::typeNameForType<std::string>() );
00070 description.setNotNullConstraint(std::string("PAYLOADCLASS"));
00071
00072 description.insertColumn(std::string("PAYLOADTOKEN"),
00073 coral::AttributeSpecification::typeNameForType<std::string>() );
00074 description.setNotNullConstraint(std::string("PAYLOADTOKEN"));
00075
00076 description.insertColumn(std::string("PAYLOADINDEX"),
00077 coral::AttributeSpecification::typeNameForType<unsigned int>() );
00078 description.setNotNullConstraint(std::string("PAYLOADINDEX"));
00079
00080 description.insertColumn(std::string("LASTSINCE"),
00081 coral::AttributeSpecification::typeNameForType<unsigned long long>() );
00082 description.setNotNullConstraint(std::string("LASTSINCE"));
00083
00084 description.insertColumn(std::string("DESTINATIONDB"),
00085 coral::AttributeSpecification::typeNameForType<std::string>() );
00086 description.setNotNullConstraint(std::string("DESTINATIONDB"));
00087
00088 description.insertColumn(std::string("PROVENANCE"),
00089 coral::AttributeSpecification::typeNameForType<std::string>() );
00090 description.insertColumn(std::string("USERTEXT"),
00091 coral::AttributeSpecification::typeNameForType<std::string>() );
00092 description.insertColumn(std::string("EXECMESSAGE"),
00093 coral::AttributeSpecification::typeNameForType<std::string>() );
00094 coral::ITable& table = m_sessionHandle.nominalSchema().createTable( description );
00095 table.privilegeManager().grantToUser( DbSession::CONDITIONS_GENERAL_READER, coral::ITablePrivilegeManager::Select );
00096 table.privilegeManager().grantToUser( DbSession::CONDITIONS_GENERAL_WRITER, coral::ITablePrivilegeManager::Select );
00097 table.privilegeManager().grantToUser( DbSession::CONDITIONS_GENERAL_WRITER, coral::ITablePrivilegeManager::Update );
00098 table.privilegeManager().grantToUser( DbSession::CONDITIONS_GENERAL_WRITER, coral::ITablePrivilegeManager::Insert );
00099 table.privilegeManager().grantToUser( DbSession::CONDITIONS_GENERAL_WRITER, coral::ITablePrivilegeManager::Delete );
00100 m_logTableExists=true;
00101 trans.commit();
00102 }
00103 void
00104 cond::Logger::logOperationNow(
00105 const cond::UserLogInfo& userlogInfo,
00106 const std::string& destDB,
00107 const std::string& payloadClass,
00108 const std::string& payloadToken,
00109 const std::string& iovtag,
00110 const std::string& iovtimetype,
00111 unsigned int payloadIdx,
00112 unsigned long long lastSince
00113 ){
00114 cond::DbScopedTransaction trans( m_sessionHandle );
00115 trans.start(false);
00116
00117
00118 boost::posix_time::ptime p=boost::posix_time::microsec_clock::universal_time();
00119 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());
00120
00121 if(!m_sequenceManager){
00122 m_sequenceManager=new cond::SequenceManager(m_sessionHandle,cond::LogDBNames::SequenceTableName());
00123 }
00124 unsigned long long targetLogId=m_sequenceManager->incrementId(LogDBNames::LogTableName());
00125
00126 this->insertLogRecord(targetLogId,now,destDB,payloadClass,payloadToken,userlogInfo,iovtag,iovtimetype,payloadIdx,lastSince,"OK");
00127 trans.commit();
00128 }
00129 void
00130 cond::Logger::logFailedOperationNow(
00131 const cond::UserLogInfo& userlogInfo,
00132 const std::string& destDB,
00133 const std::string& payloadClass,
00134 const std::string& payloadToken,
00135 const std::string& iovtag,
00136 const std::string& iovtimetype,
00137 unsigned int payloadIdx,
00138 unsigned long long lastSince,
00139 const std::string& exceptionMessage
00140 ){
00141 cond::DbScopedTransaction trans( m_sessionHandle );
00142 trans.start(false);
00143
00144 boost::posix_time::ptime p=boost::posix_time::microsec_clock::universal_time();
00145 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());
00146
00147 if(!m_sequenceManager){
00148 m_sequenceManager=new cond::SequenceManager(m_sessionHandle,cond::LogDBNames::SequenceTableName());
00149 }
00150 unsigned long long targetLogId=m_sequenceManager->incrementId(LogDBNames::LogTableName());
00151
00152 this->insertLogRecord(targetLogId,now,destDB,payloadClass,payloadToken,userlogInfo,iovtag,iovtimetype,payloadIdx,lastSince,exceptionMessage);
00153 trans.commit();
00154 }
00155
00156 void
00157 cond::Logger::LookupLastEntryByProvenance(const std::string& provenance,
00158 LogDBEntry& logentry,
00159 bool filterFailedOp) const{
00160
00161 std::string whereClause=cond::LogDBNames::LogTableName();
00162 whereClause+=".PROVENANCE=:provenance";
00163 if(filterFailedOp){
00164 whereClause+=std::string(" AND ");
00165 whereClause+=cond::LogDBNames::LogTableName();
00166 whereClause+=std::string(".EXECMESSAGE=:execmessage");
00167 }
00168 coral::AttributeList BindVariableList;
00169 BindVariableList.extend("provenance",typeid(std::string) );
00170 BindVariableList.extend("execmessage",typeid(std::string) );
00171 BindVariableList["provenance"].data<std::string>()=provenance;
00172 BindVariableList["execmessage"].data<std::string>()="OK";
00173 m_sessionHandle.transaction().start(true);
00174 {
00175 std::auto_ptr<coral::IQuery> query(m_sessionHandle.nominalSchema().tableHandle( cond::LogDBNames::LogTableName() ).newQuery());
00176
00177 query->addToOutputList( "LOGID" );
00178 query->defineOutputType( "LOGID", "unsigned long long" );
00179 query->addToOutputList( "DESTINATIONDB" );
00180 query->addToOutputList( "PROVENANCE" );
00181 query->addToOutputList( "USERTEXT" );
00182 query->addToOutputList( "IOVTAG" );
00183 query->addToOutputList( "IOVTIMETYPE" );
00184 query->addToOutputList( "PAYLOADINDEX" );
00185 query->defineOutputType( "PAYLOADINDEX", "unsigned int" );
00186 query->addToOutputList( "LASTSINCE" );
00187 query->defineOutputType( "LASTSINCE", "unsigned long long" );
00188 query->addToOutputList( "PAYLOADCLASS" );
00189 query->addToOutputList( "PAYLOADTOKEN" );
00190 query->addToOutputList( "EXECTIME" );
00191 query->addToOutputList( "EXECMESSAGE" );
00192
00193 query->setCondition( whereClause, BindVariableList );
00194 query->addToOrderList( cond::LogDBNames::LogTableName()+".LOGID desc" );
00195 query->limitReturnedRows();
00196 coral::ICursor& cursor = query->execute();
00197 if( cursor.next() ) {
00198 const coral::AttributeList& row = cursor.currentRow();
00199 logentry.logId=row["LOGID"].data<unsigned long long>();
00200 logentry.destinationDB=row["DESTINATIONDB"].data<std::string>();
00201 logentry.provenance=row["PROVENANCE"].data<std::string>();
00202 logentry.usertext=row["USERTEXT"].data<std::string>();
00203 logentry.iovtag=row["IOVTAG"].data<std::string>();
00204 logentry.iovtimetype=row["IOVTIMETYPE"].data<std::string>();
00205 logentry.payloadIdx=row["PAYLOADINDEX"].data<unsigned int>();
00206 logentry.lastSince=row["LASTSINCE"].data<unsigned long long>();
00207 logentry.payloadClass=row["PAYLOADCLASS"].data<std::string>();
00208 logentry.payloadToken=row["PAYLOADTOKEN"].data<std::string>();
00209 logentry.exectime=row["EXECTIME"].data<std::string>();
00210 logentry.execmessage=row["EXECMESSAGE"].data<std::string>();
00211 }
00212 }
00213 m_sessionHandle.transaction().commit();
00214 }
00215 void
00216 cond::Logger::LookupLastEntryByTag( const std::string& iovtag,
00217 const std::string & connectionStr,
00218 cond::LogDBEntry& logentry,
00219 bool filterFailedOp) const{
00220 coral::AttributeList BindVariableList;
00221 BindVariableList.extend("IOVTAG",typeid(std::string) );
00222 BindVariableList["IOVTAG"].data<std::string>()=iovtag;
00223 std::string whereClause("");
00224 whereClause+=std::string("IOVTAG=:IOVTAG");
00225 if(connectionStr!=""){
00226 whereClause+=std::string(" AND ");
00227 whereClause+=std::string("DESTINATIONDB=:DESTINATIONDB");
00228 BindVariableList.extend("DESTINATIONDB",typeid(std::string) );
00229 BindVariableList["DESTINATIONDB"].data<std::string>()=connectionStr;
00230 }
00231 if(filterFailedOp){
00232 whereClause+=std::string(" AND ");
00233 whereClause+=std::string("EXECMESSAGE=:EXECMESSAGE");
00234 BindVariableList.extend("EXECMESSAGE",typeid(std::string) );
00235 BindVariableList["EXECMESSAGE"].data<std::string>()="OK";
00236 }
00237 m_sessionHandle.transaction().start(true);
00238 {
00239 std::auto_ptr<coral::IQuery> query( m_sessionHandle.nominalSchema().tableHandle(cond::LogDBNames::LogTableName()).newQuery() );
00240
00241 query->addToOutputList( "LOGID" );
00242 query->defineOutputType( "LOGID", "unsigned long long" );
00243 query->addToOutputList( "DESTINATIONDB" );
00244 query->addToOutputList( "PROVENANCE" );
00245 query->addToOutputList( "USERTEXT" );
00246 query->addToOutputList( "IOVTAG" );
00247 query->addToOutputList( "IOVTIMETYPE" );
00248 query->addToOutputList( "PAYLOADINDEX" );
00249 query->defineOutputType( "PAYLOADINDEX", "unsigned int" );
00250 query->addToOutputList( "LASTSINCE" );
00251 query->defineOutputType( "LASTSINCE", "unsigned long long" );
00252 query->addToOutputList( "PAYLOADCLASS" );
00253 query->addToOutputList( "PAYLOADTOKEN" );
00254 query->addToOutputList( "EXECTIME" );
00255 query->addToOutputList( "EXECMESSAGE" );
00256
00257 query->setCondition( whereClause, BindVariableList );
00258 query->addToOrderList( "LOGID DESC" );
00259 query->limitReturnedRows();
00260 coral::ICursor& cursor = query->execute();
00261 if( cursor.next() ) {
00262 const coral::AttributeList& row = cursor.currentRow();
00263 logentry.logId=row["LOGID"].data<unsigned long long>();
00264 logentry.destinationDB=row["DESTINATIONDB"].data<std::string>();
00265 logentry.provenance=row["PROVENANCE"].data<std::string>();
00266 logentry.usertext=row["USERTEXT"].data<std::string>();
00267 logentry.iovtag=row["IOVTAG"].data<std::string>();
00268 logentry.iovtimetype=row["IOVTIMETYPE"].data<std::string>();
00269 logentry.payloadIdx=row["PAYLOADINDEX"].data<unsigned int>();
00270 logentry.lastSince=row["LASTSINCE"].data<unsigned long long>();
00271 logentry.payloadClass=row["PAYLOADCLASS"].data<std::string>();
00272 logentry.payloadToken=row["PAYLOADTOKEN"].data<std::string>();
00273 logentry.exectime=row["EXECTIME"].data<std::string>();
00274 logentry.execmessage=row["EXECMESSAGE"].data<std::string>();
00275
00276 }
00277 }
00278 m_sessionHandle.transaction().commit();
00279 }
00280 void
00281 cond::Logger::LookupLastEntryByTag( const std::string& iovtag,
00282 LogDBEntry& logentry,
00283 bool filterFailedOp ) const{
00284 LookupLastEntryByTag(iovtag,"",logentry,filterFailedOp);
00285 }
00286 void
00287 cond::Logger::insertLogRecord(unsigned long long logId,
00288 const std::string& utctime,
00289 const std::string& destDB,
00290 const std::string& payloadClass,
00291 const std::string& payloadToken,
00292 const cond::UserLogInfo& userLogInfo,
00293 const std::string& iovtag,
00294 const std::string& iovtimetype,
00295 unsigned int payloadIdx,
00296 unsigned long long lastSince,
00297 const std::string& exceptionMessage){
00298 try{
00299 coral::AttributeList rowData;
00300 rowData.extend<unsigned long long>("LOGID");
00301 rowData.extend<std::string>("EXECTIME");
00302 rowData.extend<std::string>("DESTINATIONDB");
00303 rowData.extend<std::string>("PAYLOADCLASS");
00304 rowData.extend<std::string>("PAYLOADTOKEN");
00305 rowData.extend<std::string>("PROVENANCE");
00306 rowData.extend<std::string>("USERTEXT");
00307 rowData.extend<std::string>("IOVTAG");
00308 rowData.extend<std::string>("IOVTIMETYPE");
00309 rowData.extend<unsigned int>("PAYLOADINDEX");
00310 rowData.extend<unsigned long long>("LASTSINCE");
00311 rowData.extend<std::string>("EXECMESSAGE");
00312 rowData["LOGID"].data< unsigned long long >() = logId;
00313 rowData["EXECTIME"].data< std::string >() = utctime;
00314 rowData["DESTINATIONDB"].data< std::string >() = destDB;
00315 rowData["PAYLOADCLASS"].data< std::string >() = payloadClass;
00316 std::string ptok = payloadToken;
00317 if( payloadToken.empty() ) ptok = "NA";
00318 rowData["PAYLOADTOKEN"].data< std::string >() = ptok;
00319 rowData["PROVENANCE"].data< std::string >() = userLogInfo.provenance;
00320 rowData["USERTEXT"].data< std::string >() = userLogInfo.usertext;
00321 rowData["IOVTAG"].data< std::string >() = iovtag;
00322 rowData["IOVTIMETYPE"].data< std::string >() = iovtimetype;
00323 rowData["PAYLOADINDEX"].data< unsigned int >() = payloadIdx;
00324 rowData["LASTSINCE"].data< unsigned long long >() = lastSince;
00325 rowData["EXECMESSAGE"].data< std::string >() = exceptionMessage;
00326 m_sessionHandle.nominalSchema().tableHandle(cond::LogDBNames::LogTableName()).dataEditor().insertRow(rowData);
00327 }catch(const std::exception& er){
00328 throw cond::Exception(std::string(er.what()));
00329 }
00330 }
00331
00332 cond::Logger::~Logger(){
00333 if( m_sequenceManager ){
00334 delete m_sequenceManager;
00335 m_sequenceManager=0;
00336 }
00337 }