/* * PROGRAM: Firebird Trace Services * MODULE: TraceObjects.h * DESCRIPTION: Trace API manager support * * The contents of this file are subject to the Initial * Developer's Public License Version 1.0 (the "License"); * you may not use this file except in compliance with the * License. You may obtain a copy of the License at * http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl. * * Software distributed under the License is distributed AS IS, * WITHOUT WARRANTY OF ANY KIND, either express or implied. * See the License for the specific language governing rights * and limitations under the License. * * The Original Code was created by Khorsun Vladyslav * for the Firebird Open Source RDBMS project. * * Copyright (c) 2009 Khorsun Vladyslav * and all contributors signed below. * * All Rights Reserved. * Contributor(s): ______________________________________. * */ #ifndef JRD_TRACE_OBJECTS_H #define JRD_TRACE_OBJECTS_H #include #include "../../common/classes/array.h" #include "../../common/classes/fb_string.h" #include "../../dsql/dsql.h" #include "../../jrd/ntrace.h" #include "../../common/dsc.h" #include "../../common/isc_s_proto.h" #include "../../jrd/req.h" #include "../../jrd/svc.h" #include "../../jrd/tra.h" #include "../../jrd/status.h" #include "../../jrd/Function.h" #include "../../jrd/RuntimeStatistics.h" #include "../../jrd/trace/TraceSession.h" #include "../../common/classes/ImplementHelper.h" #include "../../common/prett_proto.h" //// TODO: DDL triggers, packages and external procedures and functions support namespace Jrd { class Database; class Attachment; class jrd_tra; class TraceConnectionImpl : public Firebird::AutoIface > { public: TraceConnectionImpl(const Attachment* att) : m_att(att) {} // TraceConnection implementation unsigned getKind(); int getProcessID(); const char* getUserName(); const char* getRoleName(); const char* getCharSet(); const char* getRemoteProtocol(); const char* getRemoteAddress(); int getRemoteProcessID(); const char* getRemoteProcessName(); // TraceDatabaseConnection implementation int getConnectionID(); const char* getDatabaseName(); private: const Attachment* const m_att; }; class TraceTransactionImpl : public Firebird::AutoIface > { public: TraceTransactionImpl(const jrd_tra* tran, PerformanceInfo* perf = NULL) : m_tran(tran), m_perf(perf) {} // TraceTransaction implementation unsigned getTransactionID(); FB_BOOLEAN getReadOnly(); int getWait(); unsigned getIsolation(); PerformanceInfo* getPerf() { return m_perf; } private: const jrd_tra* const m_tran; PerformanceInfo* const m_perf; }; template class BLRPrinter : public Firebird::AutoIface > { public: BLRPrinter(const unsigned char* blr, unsigned length) : m_blr(blr), m_length(length), m_text(*getDefaultMemoryPool()) {} // TraceBLRStatement implementation const unsigned char* getData() { return m_blr; } unsigned getDataLength() { return m_length; } const char* getText() { if (m_text.empty() && getDataLength()) fb_print_blr(getData(), (ULONG) getDataLength(), print_blr, this, 0); return m_text.c_str(); } private: static void print_blr(void* arg, SSHORT offset, const char* line) { BLRPrinter* blr = (BLRPrinter*) arg; Firebird::string temp; temp.printf("%4d %s\n", offset, line); blr->m_text.append(temp); } const unsigned char* const m_blr; const unsigned m_length; Firebird::string m_text; }; class TraceBLRStatementImpl : public BLRPrinter { public: TraceBLRStatementImpl(const jrd_req* stmt, PerformanceInfo* perf) : BLRPrinter(stmt->getStatement()->blr.begin(), stmt->getStatement()->blr.getCount()), m_stmt(stmt), m_perf(perf) {} int getStmtID() { return m_stmt->req_id; } PerformanceInfo* getPerf() { return m_perf; } private: const jrd_req* const m_stmt; PerformanceInfo* const m_perf; }; class TraceFailedBLRStatement : public BLRPrinter { public: TraceFailedBLRStatement(const unsigned char* blr, unsigned length) : BLRPrinter(blr, length) {} int getStmtID() { return 0; } PerformanceInfo* getPerf() { return NULL; } }; class TraceSQLStatementImpl : public Firebird::AutoIface > { public: TraceSQLStatementImpl(const dsql_req* stmt, PerformanceInfo* perf) : m_stmt(stmt), m_perf(perf), m_planExplained(false), m_inputs(*getDefaultMemoryPool(), m_stmt) {} // TraceSQLStatement implementation int getStmtID(); PerformanceInfo* getPerf(); Firebird::ITraceParams* getInputs(); const char* getText(); const char* getPlan(); const char* getTextUTF8(); const char* getExplainedPlan(); private: class DSQLParamsImpl : public Firebird::AutoIface > { public: DSQLParamsImpl(Firebird::MemoryPool& pool, const dsql_req* const stmt) : m_stmt(stmt), m_params(NULL), m_descs(pool) { const dsql_msg* msg = m_stmt->getStatement()->getSendMsg(); if (msg) m_params = &msg->msg_parameters; } FB_SIZE_T getCount(); const dsc* getParam(FB_SIZE_T idx); private: void fillParams(); const dsql_req* const m_stmt; const Firebird::Array* m_params; Firebird::HalfStaticArray m_descs; }; void fillPlan(bool explained); const dsql_req* const m_stmt; PerformanceInfo* const m_perf; Firebird::string m_plan; bool m_planExplained; DSQLParamsImpl m_inputs; Firebird::string m_textUTF8; }; class TraceFailedSQLStatement : public Firebird::AutoIface > { public: TraceFailedSQLStatement(Firebird::string& text) : m_text(text) {} // TraceSQLStatement implementation int getStmtID() { return 0; } PerformanceInfo* getPerf() { return NULL; } Firebird::ITraceParams* getInputs() { return NULL; } const char* getText() { return m_text.c_str(); } const char* getPlan() { return ""; } const char* getTextUTF8(); const char* getExplainedPlan() { return ""; } private: Firebird::string& m_text; Firebird::string m_textUTF8; }; class TraceContextVarImpl : public Firebird::AutoIface > { public: TraceContextVarImpl(const char* ns, const char* name, const char* value) : m_namespace(ns), m_name(name), m_value(value) {} // TraceContextVariable implementation const char* getNameSpace() { return m_namespace; } const char* getVarName() { return m_name; } const char* getVarValue() { return m_value; } private: const char* const m_namespace; const char* const m_name; const char* const m_value; }; // forward declaration class TraceDescriptors; class TraceParamsImpl : public Firebird::AutoIface > { public: explicit TraceParamsImpl(TraceDescriptors *descs) : m_descs(descs) {} // TraceParams implementation FB_SIZE_T getCount(); const dsc* getParam(FB_SIZE_T idx); private: TraceDescriptors* m_descs; }; class TraceDescriptors { public: explicit TraceDescriptors(Firebird::MemoryPool& pool) : m_descs(pool), m_traceParams(this) { } FB_SIZE_T getCount() { fillParams(); return m_descs.getCount(); } const dsc* getParam(FB_SIZE_T idx) { fillParams(); if (/*idx >= 0 &&*/ idx < m_descs.getCount()) return &m_descs[idx]; return NULL; } operator Firebird::ITraceParams* () { return &m_traceParams; } protected: virtual void fillParams() = 0; Firebird::HalfStaticArray m_descs; private: TraceParamsImpl m_traceParams; }; class TraceDscFromValues : public TraceDescriptors { public: TraceDscFromValues(Firebird::MemoryPool& pool, jrd_req* request, const ValueListNode* params) : TraceDescriptors(pool), m_request(request), m_params(params) {} protected: void fillParams(); private: jrd_req* m_request; const ValueListNode* m_params; }; class TraceDscFromMsg : public TraceDescriptors { public: TraceDscFromMsg(Firebird::MemoryPool& pool, const Format* format, const UCHAR* inMsg, ULONG inMsgLength) : TraceDescriptors(pool), m_format(format), m_inMsg(inMsg), m_inMsgLength(inMsgLength) {} protected: void fillParams(); private: const Format* m_format; const UCHAR* m_inMsg; ULONG m_inMsgLength; }; class TraceDscFromDsc : public TraceDescriptors { public: TraceDscFromDsc(Firebird::MemoryPool& pool, const dsc* desc) : TraceDescriptors(pool) { if (desc) m_descs.add(*desc); else { m_descs.grow(1); m_descs[0].setNull(); } } protected: void fillParams() {} }; class TraceProcedureImpl : public Firebird::AutoIface > { public: TraceProcedureImpl(jrd_req* request, PerformanceInfo* perf) : m_request(request), m_perf(perf), m_inputs(*getDefaultMemoryPool(), request->req_proc_caller, request->req_proc_inputs), m_name(m_request->getStatement()->procedure->getName().toString()) {} // TraceProcedure implementation const char* getProcName() { return m_name.c_str(); } Firebird::ITraceParams* getInputs() { return m_inputs; } PerformanceInfo* getPerf() { return m_perf; }; private: jrd_req* const m_request; PerformanceInfo* const m_perf; TraceDscFromValues m_inputs; Firebird::string m_name; }; class TraceFunctionImpl : public Firebird::AutoIface > { public: TraceFunctionImpl(jrd_req* request, Firebird::ITraceParams* inputs, PerformanceInfo* perf, const dsc* value) : m_request(request), m_perf(perf), m_inputs(inputs), m_value(*getDefaultMemoryPool(), value), m_name(m_request->getStatement()->function->getName().toString()) {} // TraceFunction implementation const char* getFuncName() { return m_name.c_str(); } Firebird::ITraceParams* getInputs() { return m_inputs; } Firebird::ITraceParams* getResult() { return m_value; } PerformanceInfo* getPerf() { return m_perf; }; private: jrd_req* const m_request; PerformanceInfo* const m_perf; Firebird::ITraceParams* m_inputs; TraceDscFromDsc m_value; Firebird::string m_name; }; class TraceTriggerImpl : public Firebird::AutoIface > { public: TraceTriggerImpl(const jrd_req* trig, SSHORT which, PerformanceInfo* perf) : m_trig(trig), m_which(which), m_perf(perf) {} // TraceTrigger implementation const char* getTriggerName(); const char* getRelationName(); int getAction() { return m_trig->req_trigger_action; } int getWhich() { return m_which; } PerformanceInfo* getPerf() { return m_perf; } private: const jrd_req* const m_trig; const SSHORT m_which; PerformanceInfo* const m_perf; }; class TraceServiceImpl : public Firebird::AutoIface > { public: TraceServiceImpl(const Service* svc) : m_svc(svc) {} // TraceConnection implementation unsigned getKind(); const char* getUserName(); const char* getRoleName(); const char* getCharSet(); int getProcessID(); const char* getRemoteProtocol(); const char* getRemoteAddress(); int getRemoteProcessID(); const char* getRemoteProcessName(); // TraceServiceConnection implementation void* getServiceID(); const char* getServiceMgr(); const char* getServiceName(); private: const Service* const m_svc; }; class TraceRuntimeStats { public: TraceRuntimeStats(Attachment* att, RuntimeStatistics* baseline, RuntimeStatistics* stats, SINT64 clock, SINT64 records_fetched); PerformanceInfo* getPerf() { return &m_info; } private: PerformanceInfo m_info; TraceCountsArray m_counts; static SINT64 m_dummy_counts[RuntimeStatistics::TOTAL_ITEMS]; // Zero-initialized array with zero counts }; class TraceInitInfoImpl : public Firebird::AutoIface > { public: TraceInitInfoImpl(const Firebird::TraceSession& session, const Attachment* att, const char* filename) : m_session(session), m_trace_conn(att), m_filename(filename), m_attachment(att) { if (m_attachment && !m_attachment->att_filename.empty()) { m_filename = m_attachment->att_filename.c_str(); } } // TraceInitInfo implementation const char* getConfigText() { return m_session.ses_config.c_str(); } int getTraceSessionID() { return m_session.ses_id; } const char* getTraceSessionName() { return m_session.ses_name.c_str(); } const char* getFirebirdRootDirectory(); const char* getDatabaseName() { return m_filename; } Firebird::ITraceDatabaseConnection* getConnection() { if (m_attachment) return &m_trace_conn; return NULL; } Firebird::ITraceLogWriter* getLogWriter(); private: const Firebird::TraceSession& m_session; Firebird::RefPtr m_logWriter; TraceConnectionImpl m_trace_conn; const char* m_filename; const Attachment* const m_attachment; }; class TraceStatusVectorImpl : public Firebird::AutoIface > { public: enum Kind {TS_ERRORS, TS_WARNINGS}; TraceStatusVectorImpl(FbStatusVector* status, Kind k) : m_status(status), kind(k) { } FB_BOOLEAN hasError() { return m_status->getState() & Firebird::IStatus::STATE_ERRORS; } FB_BOOLEAN hasWarning() { return m_status->getState() & Firebird::IStatus::STATE_WARNINGS; } Firebird::IStatus* getStatus() { return m_status; } const char* getText(); private: Firebird::string m_error; FbStatusVector* m_status; Kind kind; }; class TraceSweepImpl : public Firebird::AutoIface > { public: TraceSweepImpl() { m_oit = 0; m_ost = 0; m_oat = 0; m_next = 0; m_perf = 0; } void update(const Ods::header_page* header) { m_oit = header->hdr_oldest_transaction; m_ost = header->hdr_oldest_snapshot; m_oat = header->hdr_oldest_active; m_next = header->hdr_next_transaction; } void setPerf(PerformanceInfo* perf) { m_perf = perf; } ISC_UINT64 getOIT() { return m_oit; }; ISC_UINT64 getOST() { return m_ost; }; ISC_UINT64 getOAT() { return m_oat; }; ISC_UINT64 getNext() { return m_next; }; PerformanceInfo* getPerf() { return m_perf; }; private: TraNumber m_oit; TraNumber m_ost; TraNumber m_oat; TraNumber m_next; PerformanceInfo* m_perf; }; } // namespace Jrd #endif // JRD_TRACE_OBJECTS_H