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