8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-24 00:03:03 +01:00

Improvement CORE-3539 : TRACE: add ability for logging ERRORs that occur in runtime (lock conflicts, PK/UK/FK violations et al)

This commit is contained in:
hvlad 2012-05-02 20:53:18 +00:00
parent 55344bea87
commit 1bcb480d8d
13 changed files with 1112 additions and 537 deletions

File diff suppressed because it is too large Load Diff

View File

@ -34,7 +34,7 @@
#include "../jrd/common.h"
/* Version of API, used for version fields in TracePlugin structure */
#define NTRACE_VERSION 2
#define NTRACE_VERSION 3
// plugin entry point
static const char* const NTRACE_ATTACH = "trace_create";
@ -43,11 +43,16 @@ static const char* const NTRACE_ATTACH = "trace_create";
struct PerformanceInfo;
class TraceConnection
enum ntrace_connection_kind_t
{
connection_database = 1,
connection_service
};
class TraceBaseConnection
{
public:
virtual int getConnectionID() = 0;
virtual const char* getDatabaseName() = 0;
virtual ntrace_connection_kind_t getKind() = 0;
virtual int getProcessID() = 0;
virtual const char* getUserName() = 0;
@ -57,8 +62,13 @@ public:
virtual const char* getRemoteAddress() = 0;
virtual int getRemoteProcessID() = 0;
virtual const char* getRemoteProcessName() = 0;
};
virtual ~TraceConnection() { }
class TraceDatabaseConnection : public TraceBaseConnection
{
public:
virtual int getConnectionID() = 0;
virtual const char* getDatabaseName() = 0;
};
enum ntrace_tra_isolation_t
@ -77,8 +87,6 @@ public:
virtual int getWait() = 0;
virtual ntrace_tra_isolation_t getIsolation() = 0;
virtual PerformanceInfo* getPerf() = 0;
virtual ~TraceTransaction() { }
};
typedef int ntrace_relation_t;
@ -88,8 +96,6 @@ class TraceParams
public:
virtual size_t getCount() = 0;
virtual const struct dsc* getParam(size_t idx) = 0;
virtual ~TraceParams() { }
};
class TraceStatement
@ -97,8 +103,6 @@ class TraceStatement
public:
virtual int getStmtID() = 0;
virtual PerformanceInfo* getPerf() = 0;
virtual ~TraceStatement() { }
};
class TraceSQLStatement : public TraceStatement
@ -124,8 +128,6 @@ public:
virtual const unsigned char* getData() = 0;
virtual size_t getDataLength() = 0;
virtual const char* getText() = 0;
virtual ~TraceDYNRequest() { }
};
class TraceContextVariable
@ -134,8 +136,6 @@ public:
virtual const char* getNameSpace() = 0;
virtual const char* getVarName() = 0;
virtual const char* getVarValue() = 0;
virtual ~TraceContextVariable() { }
};
class TraceProcedure
@ -144,8 +144,6 @@ public:
virtual const char* getProcName() = 0;
virtual TraceParams* getInputs() = 0;
virtual PerformanceInfo* getPerf() = 0;
virtual ~TraceProcedure() { }
};
class TraceTrigger
@ -156,30 +154,26 @@ public:
virtual int getAction() = 0;
virtual int getWhich() = 0;
virtual PerformanceInfo* getPerf() = 0;
virtual ~TraceTrigger() { }
};
typedef void* ntrace_service_t;
class TraceService
class TraceServiceConnection : public TraceBaseConnection
{
public:
virtual ntrace_service_t getServiceID() = 0;
virtual const char* getServiceMgr() = 0;
virtual const char* getServiceName() = 0;
virtual int getProcessID() = 0;
virtual const char* getUserName() = 0;
virtual const char* getRoleName() = 0;
virtual const char* getRemoteProtocol() = 0;
virtual const char* getRemoteAddress() = 0;
virtual int getRemoteProcessID() = 0;
virtual const char* getRemoteProcessName() = 0;
virtual ~TraceService() { }
};
class TraceStatusVector
{
public:
virtual bool hasError() = 0;
virtual bool hasWarning() = 0;
virtual const ISC_STATUS* getStatus() = 0;
virtual const char* getText() = 0;
};
/* Plugin-specific argument. Passed by the engine to each hook */
typedef void* ntrace_object_t;
@ -252,67 +246,71 @@ typedef ntrace_boolean_t (*ntrace_shutdown_t)(const struct TracePlugin* tpl_plug
/* Create/close attachment */
typedef ntrace_boolean_t (*ntrace_event_attach_t)(const struct TracePlugin* tpl_plugin,
TraceConnection* connection, ntrace_boolean_t create_db, ntrace_result_t att_result);
TraceDatabaseConnection* connection, ntrace_boolean_t create_db, ntrace_result_t att_result);
typedef ntrace_boolean_t (*ntrace_event_detach_t)(const struct TracePlugin* tpl_plugin,
TraceConnection* connection, ntrace_boolean_t drop_db);
TraceDatabaseConnection* connection, ntrace_boolean_t drop_db);
/* Start/end transaction */
typedef ntrace_boolean_t (*ntrace_event_transaction_start_t)(const struct TracePlugin* tpl_plugin,
TraceConnection* connection, TraceTransaction* transaction,
TraceDatabaseConnection* connection, TraceTransaction* transaction,
size_t tpb_length, const ntrace_byte_t* tpb, ntrace_result_t tra_result);
typedef ntrace_boolean_t (*ntrace_event_transaction_end_t)(const struct TracePlugin* tpl_plugin,
TraceConnection* connection, TraceTransaction* transaction,
TraceDatabaseConnection* connection, TraceTransaction* transaction,
ntrace_boolean_t commit, ntrace_boolean_t retain_context, ntrace_result_t tra_result);
/* Assignment to context variables */
typedef ntrace_boolean_t (*ntrace_event_set_context_t)(const struct TracePlugin* tpl_plugin,
TraceConnection* connection, TraceTransaction* transaction, TraceContextVariable* variable);
TraceDatabaseConnection* connection, TraceTransaction* transaction, TraceContextVariable* variable);
/* Stored procedure and triggers executing */
typedef ntrace_boolean_t (*ntrace_event_proc_execute_t)(const struct TracePlugin* tpl_plugin,
TraceConnection* connection, TraceTransaction* transaction, TraceProcedure* procedure,
TraceDatabaseConnection* connection, TraceTransaction* transaction, TraceProcedure* procedure,
bool started, ntrace_result_t proc_result);
typedef ntrace_boolean_t (*ntrace_event_trigger_execute_t)(const struct TracePlugin* tpl_plugin,
TraceConnection* connection, TraceTransaction* transaction, TraceTrigger* trigger,
TraceDatabaseConnection* connection, TraceTransaction* transaction, TraceTrigger* trigger,
bool started, ntrace_result_t trig_result);
/* DSQL statement lifecycle */
typedef ntrace_boolean_t (*ntrace_event_dsql_prepare_t)(const struct TracePlugin* tpl_plugin,
TraceConnection* connection, TraceTransaction* transaction,
TraceDatabaseConnection* connection, TraceTransaction* transaction,
TraceSQLStatement* statement, ntrace_counter_t time_millis, ntrace_result_t req_result);
typedef ntrace_boolean_t (*ntrace_event_dsql_free_t)(const struct TracePlugin* tpl_plugin,
TraceConnection* connection, TraceSQLStatement* statement, unsigned short option);
TraceDatabaseConnection* connection, TraceSQLStatement* statement, unsigned short option);
typedef ntrace_boolean_t (*ntrace_event_dsql_execute_t)(const struct TracePlugin* tpl_plugin,
TraceConnection* connection, TraceTransaction* transaction, TraceSQLStatement* statement,
TraceDatabaseConnection* connection, TraceTransaction* transaction, TraceSQLStatement* statement,
bool started, ntrace_result_t req_result);
/* BLR requests */
typedef ntrace_boolean_t (*ntrace_event_blr_compile_t)(const struct TracePlugin* tpl_plugin,
TraceConnection* connection, TraceTransaction* transaction,
TraceDatabaseConnection* connection, TraceTransaction* transaction,
TraceBLRStatement* statement, ntrace_counter_t time_millis, ntrace_result_t req_result);
typedef ntrace_boolean_t (*ntrace_event_blr_execute_t)(const struct TracePlugin* tpl_plugin,
TraceConnection* connection, TraceTransaction* transaction,
TraceDatabaseConnection* connection, TraceTransaction* transaction,
TraceBLRStatement* statement, ntrace_result_t req_result);
/* DYN requests */
typedef ntrace_boolean_t (*ntrace_event_dyn_execute_t)(const struct TracePlugin* tpl_plugin,
TraceConnection* connection, TraceTransaction* transaction,
TraceDatabaseConnection* connection, TraceTransaction* transaction,
TraceDYNRequest* request, ntrace_counter_t time_millis,
ntrace_result_t req_result);
/* Using the services */
typedef ntrace_boolean_t (*ntrace_event_service_attach_t)(const struct TracePlugin* tpl_plugin,
TraceService* service, ntrace_result_t att_result);
TraceServiceConnection* service, ntrace_result_t att_result);
typedef ntrace_boolean_t (*ntrace_event_service_start_t)(const struct TracePlugin* tpl_plugin,
TraceService* service, size_t switches_length, const char* switches,
TraceServiceConnection* service, size_t switches_length, const char* switches,
ntrace_result_t start_result);
typedef ntrace_boolean_t (*ntrace_event_service_query_t)(const struct TracePlugin* tpl_plugin,
TraceService* service, size_t send_item_length,
TraceServiceConnection* service, size_t send_item_length,
const ntrace_byte_t* send_items, size_t recv_item_length,
const ntrace_byte_t* recv_items, ntrace_result_t query_result);
typedef ntrace_boolean_t (*ntrace_event_service_detach_t)(const struct TracePlugin* tpl_plugin,
TraceService* service, ntrace_result_t detach_result);
TraceServiceConnection* service, ntrace_result_t detach_result);
/* Errors happened */
typedef ntrace_boolean_t (*ntrace_event_error_t)(const struct TracePlugin* tpl_plugin,
TraceBaseConnection* connection, TraceStatusVector* status, const char* function);
/* API of trace plugin. Used to deliver notifications for each database */
@ -353,9 +351,11 @@ struct TracePlugin
ntrace_event_service_query_t tpl_event_service_query;
ntrace_event_service_detach_t tpl_event_service_detach;
ntrace_event_error_t tpl_event_error;
/* Some space for future extension of Trace API interface,
must be zero-initialized by the plugin */
void* reserved_for_interface[24];
void* reserved_for_interface[23];
/* Some space which may be freely used by Trace API driver.
If driver needs more space it may allocate and return larger TracePlugin structure. */
@ -379,7 +379,7 @@ public:
virtual const char* getTraceSessionName() = 0;
virtual const char* getFirebirdRootDirectory() = 0;
virtual const char* getDatabaseName() = 0;
virtual TraceConnection* getConnection() = 0;
virtual TraceDatabaseConnection* getConnection() = 0;
virtual TraceLogWriter* getLogWriter() = 0;
virtual ~TraceInitInfo() { }

View File

@ -962,13 +962,24 @@ Service::Service(const TEXT* service_name, USHORT spb_length, const UCHAR* spb_d
else
trace_manager = FB_NEW(*getDefaultMemoryPool()) TraceManager(this);
if (trace_manager->needs().event_service_attach)
if (trace_manager->needs().event_service_attach ||
trace_manager->needs().event_error)
{
const ISC_LONG exc = ex.stuff_exception(status_vector);
const bool no_priv = (exc == isc_login || exc == isc_no_priv);
TraceServiceImpl service(this);
trace_manager->event_service_attach(&service, no_priv ? res_unauthorized : res_failed);
if (trace_manager->needs().event_service_attach)
{
trace_manager->event_service_attach(&service, no_priv ? res_unauthorized : res_failed);
}
if (trace_manager->needs().event_error)
{
TraceStatusVectorImpl traceStatus(status_vector);
trace_manager->event_error(&service, &traceStatus, "jrd8_service_attach");
}
}
if (!hasTrace)
@ -1611,19 +1622,38 @@ ISC_STATUS Service::query2(thread_db* tdbb,
{
ISC_STATUS_ARRAY status_vector;
if (svc_trace_manager->needs().event_service_query)
if (svc_trace_manager->needs().event_service_query ||
svc_trace_manager->needs().event_error)
{
const ISC_LONG exc = ex.stuff_exception(status_vector);
const bool no_priv = (exc == isc_login || exc == isc_no_priv ||
exc == isc_insufficient_svc_privileges);
TraceServiceImpl service(this);
svc_trace_manager->event_service_query(&service, send_item_length, send_items,
recv_item_length, recv_items, (no_priv ? res_unauthorized : res_failed));
if (svc_trace_manager->needs().event_service_query)
{
svc_trace_manager->event_service_query(&service, send_item_length, send_items,
recv_item_length, recv_items, (no_priv ? res_unauthorized : res_failed));
}
if (svc_trace_manager->needs().event_error)
{
TraceStatusVectorImpl traceStatus(status_vector);
svc_trace_manager->event_error(&service, &traceStatus, "jrd8_service_query");
}
}
throw;
}
if (svc_status[1] && svc_trace_manager->needs().event_error)
{
TraceServiceImpl service(this);
TraceStatusVectorImpl traceStatus(svc_status);
svc_trace_manager->event_error(&service, &traceStatus, "jrd8_service_query");
}
if (!(svc_flags & SVC_thd_running))
{
finish(SVC_finished);
@ -1997,15 +2027,26 @@ void Service::query(USHORT send_item_length,
{
ISC_STATUS_ARRAY status_vector;
if (svc_trace_manager->needs().event_service_query)
if (svc_trace_manager->needs().event_service_query ||
svc_trace_manager->needs().event_error)
{
const ISC_LONG exc = ex.stuff_exception(status_vector);
const bool no_priv = (exc == isc_login || exc == isc_no_priv);
// Report to Trace API that query failed
TraceServiceImpl service(this);
svc_trace_manager->event_service_query(&service, send_item_length, send_items,
recv_item_length, recv_items, (no_priv ? res_unauthorized : res_failed));
// Report to Trace API that query failed
if (svc_trace_manager->needs().event_service_query)
{
svc_trace_manager->event_service_query(&service, send_item_length, send_items,
recv_item_length, recv_items, (no_priv ? res_unauthorized : res_failed));
}
if (svc_trace_manager->needs().event_error)
{
TraceStatusVectorImpl traceStatus(status_vector);
svc_trace_manager->event_error(&service, &traceStatus, "jrd8_service_query");
}
}
throw;
}
@ -2202,16 +2243,27 @@ void Service::start(USHORT spb_length, const UCHAR* spb_data)
} // try
catch (const Firebird::Exception& ex)
{
if (svc_trace_manager->needs().event_service_start)
if (svc_trace_manager->needs().event_service_start ||
svc_trace_manager->needs().event_error)
{
ISC_STATUS_ARRAY status_vector;
const ISC_LONG exc = ex.stuff_exception(status_vector);
const bool no_priv = (exc == isc_login || exc == isc_no_priv);
TraceServiceImpl service(this);
svc_trace_manager->event_service_start(&service,
this->svc_switches.length(), this->svc_switches.c_str(),
no_priv ? res_unauthorized : res_failed);
if (svc_trace_manager->needs().event_service_start)
{
svc_trace_manager->event_service_start(&service,
this->svc_switches.length(), this->svc_switches.c_str(),
no_priv ? res_unauthorized : res_failed);
}
if (svc_trace_manager->needs().event_error)
{
TraceStatusVectorImpl traceStatus(status_vector);
svc_trace_manager->event_error(&service, &traceStatus, "jrd8_service_start");
}
}
throw;
}

View File

@ -147,7 +147,7 @@ public:
}
TraceRuntimeStats stats(m_attachment->att_database, m_request->req_fetch_baseline,
&m_request->req_request->req_stats,
&m_request->req_request ? &m_request->req_request->req_stats : NULL,
fb_utils::query_performance_counter() - m_start_clock,
m_request->req_fetch_rowcount);
@ -211,7 +211,8 @@ public:
}
TraceRuntimeStats stats(m_attachment->att_database, m_request->req_fetch_baseline,
&m_request->req_request->req_stats, m_request->req_fetch_elapsed,
m_request->req_request ? &m_request->req_request->req_stats : NULL,
m_request->req_fetch_elapsed,
m_request->req_fetch_rowcount);
TraceSQLStatementImpl stmt(m_request, stats.getPerf());

View File

@ -322,6 +322,8 @@ void TraceManager::update_session(const TraceSession& session)
trace_needs.event_service_detach = true;
if (plugin->tpl_event_trigger_execute)
trace_needs.event_trigger_execute = true;
if (plugin->tpl_event_error)
trace_needs.event_error = true;
}
}
}
@ -387,19 +389,19 @@ void TraceManager::event_dsql_execute(Attachment* att, jrd_tra* transaction,
}
void TraceManager::event_attach(TraceConnection* connection,
void TraceManager::event_attach(TraceDatabaseConnection* connection,
bool create_db, ntrace_result_t att_result)
{
EXECUTE_HOOKS(tpl_event_attach,
(plug_info->plugin, connection, create_db, att_result));
}
void TraceManager::event_detach(TraceConnection* connection, bool drop_db)
void TraceManager::event_detach(TraceDatabaseConnection* connection, bool drop_db)
{
EXECUTE_HOOKS(tpl_event_detach, (plug_info->plugin, connection, drop_db));
}
void TraceManager::event_transaction_start(TraceConnection* connection,
void TraceManager::event_transaction_start(TraceDatabaseConnection* connection,
TraceTransaction* transaction, size_t tpb_length, const ntrace_byte_t* tpb,
ntrace_result_t tra_result)
{
@ -407,7 +409,7 @@ void TraceManager::event_transaction_start(TraceConnection* connection,
(plug_info->plugin, connection, transaction, tpb_length, tpb, tra_result));
}
void TraceManager::event_transaction_end(TraceConnection* connection,
void TraceManager::event_transaction_end(TraceDatabaseConnection* connection,
TraceTransaction* transaction, bool commit, bool retain_context,
ntrace_result_t tra_result)
{
@ -415,28 +417,28 @@ void TraceManager::event_transaction_end(TraceConnection* connection,
(plug_info->plugin, connection, transaction, commit, retain_context, tra_result));
}
void TraceManager::event_set_context(TraceConnection* connection,
void TraceManager::event_set_context(TraceDatabaseConnection* connection,
TraceTransaction* transaction, TraceContextVariable* variable)
{
EXECUTE_HOOKS(tpl_event_set_context,
(plug_info->plugin, connection, transaction, variable));
}
void TraceManager::event_proc_execute(TraceConnection* connection, TraceTransaction* transaction,
void TraceManager::event_proc_execute(TraceDatabaseConnection* connection, TraceTransaction* transaction,
TraceProcedure* procedure, bool started, ntrace_result_t proc_result)
{
EXECUTE_HOOKS(tpl_event_proc_execute,
(plug_info->plugin, connection, transaction, procedure, started, proc_result));
}
void TraceManager::event_trigger_execute(TraceConnection* connection, TraceTransaction* transaction,
void TraceManager::event_trigger_execute(TraceDatabaseConnection* connection, TraceTransaction* transaction,
TraceTrigger* trigger, bool started, ntrace_result_t trig_result)
{
EXECUTE_HOOKS(tpl_event_trigger_execute,
(plug_info->plugin, connection, transaction, trigger, started, trig_result));
}
void TraceManager::event_dsql_prepare(TraceConnection* connection, TraceTransaction* transaction,
void TraceManager::event_dsql_prepare(TraceDatabaseConnection* connection, TraceTransaction* transaction,
TraceSQLStatement* statement, ntrace_counter_t time_millis, ntrace_result_t req_result)
{
EXECUTE_HOOKS(tpl_event_dsql_prepare,
@ -444,14 +446,14 @@ void TraceManager::event_dsql_prepare(TraceConnection* connection, TraceTransact
time_millis, req_result));
}
void TraceManager::event_dsql_free(TraceConnection* connection,
void TraceManager::event_dsql_free(TraceDatabaseConnection* connection,
TraceSQLStatement* statement, unsigned short option)
{
EXECUTE_HOOKS(tpl_event_dsql_free,
(plug_info->plugin, connection, statement, option));
}
void TraceManager::event_dsql_execute(TraceConnection* connection, TraceTransaction* transaction,
void TraceManager::event_dsql_execute(TraceDatabaseConnection* connection, TraceTransaction* transaction,
TraceSQLStatement* statement, bool started, ntrace_result_t req_result)
{
EXECUTE_HOOKS(tpl_event_dsql_execute,
@ -459,7 +461,7 @@ void TraceManager::event_dsql_execute(TraceConnection* connection, TraceTransact
}
void TraceManager::event_blr_compile(TraceConnection* connection,
void TraceManager::event_blr_compile(TraceDatabaseConnection* connection,
TraceTransaction* transaction, TraceBLRStatement* statement,
ntrace_counter_t time_millis, ntrace_result_t req_result)
{
@ -468,7 +470,7 @@ void TraceManager::event_blr_compile(TraceConnection* connection,
time_millis, req_result));
}
void TraceManager::event_blr_execute(TraceConnection* connection,
void TraceManager::event_blr_execute(TraceDatabaseConnection* connection,
TraceTransaction* transaction, TraceBLRStatement* statement,
ntrace_result_t req_result)
{
@ -476,7 +478,7 @@ void TraceManager::event_blr_execute(TraceConnection* connection,
(plug_info->plugin, connection, transaction, statement, req_result));
}
void TraceManager::event_dyn_execute(TraceConnection* connection,
void TraceManager::event_dyn_execute(TraceDatabaseConnection* connection,
TraceTransaction* transaction, TraceDYNRequest* request,
ntrace_counter_t time_millis, ntrace_result_t req_result)
{
@ -485,13 +487,13 @@ void TraceManager::event_dyn_execute(TraceConnection* connection,
req_result));
}
void TraceManager::event_service_attach(TraceService* service, ntrace_result_t att_result)
void TraceManager::event_service_attach(TraceServiceConnection* service, ntrace_result_t att_result)
{
EXECUTE_HOOKS(tpl_event_service_attach,
(plug_info->plugin, service, att_result));
}
void TraceManager::event_service_start(TraceService* service,
void TraceManager::event_service_start(TraceServiceConnection* service,
size_t switches_length, const char* switches,
ntrace_result_t start_result)
{
@ -499,7 +501,7 @@ void TraceManager::event_service_start(TraceService* service,
(plug_info->plugin, service, switches_length, switches, start_result));
}
void TraceManager::event_service_query(TraceService* service,
void TraceManager::event_service_query(TraceServiceConnection* service,
size_t send_item_length, const ntrace_byte_t* send_items,
size_t recv_item_length, const ntrace_byte_t* recv_items,
ntrace_result_t query_result)
@ -509,10 +511,17 @@ void TraceManager::event_service_query(TraceService* service,
recv_item_length, recv_items, query_result));
}
void TraceManager::event_service_detach(TraceService* service, ntrace_result_t detach_result)
void TraceManager::event_service_detach(TraceServiceConnection* service, ntrace_result_t detach_result)
{
EXECUTE_HOOKS(tpl_event_service_detach,
(plug_info->plugin, service, detach_result));
}
void TraceManager::event_error(TraceBaseConnection* connection, TraceStatusVector* status, const char* function)
{
EXECUTE_HOOKS(tpl_event_error,
(plug_info->plugin, connection, status, function));
}
}

View File

@ -62,51 +62,53 @@ public:
static size_t pluginsCount()
{ return modules->getCount(); }
void event_attach(TraceConnection* connection, bool create_db,
void event_attach(TraceDatabaseConnection* connection, bool create_db,
ntrace_result_t att_result);
void event_detach(TraceConnection* connection, bool drop_db);
void event_detach(TraceDatabaseConnection* connection, bool drop_db);
/* Start/end transaction */
void event_transaction_start(TraceConnection* connection, TraceTransaction* transaction,
void event_transaction_start(TraceDatabaseConnection* connection, TraceTransaction* transaction,
size_t tpb_length, const ntrace_byte_t* tpb, ntrace_result_t tra_result);
void event_transaction_end(TraceConnection* connection, TraceTransaction* transaction,
void event_transaction_end(TraceDatabaseConnection* connection, TraceTransaction* transaction,
bool commit, bool retain_context, ntrace_result_t tra_result);
void event_set_context(TraceConnection* connection,
void event_set_context(TraceDatabaseConnection* connection,
TraceTransaction* transaction, TraceContextVariable* variable);
void event_proc_execute(TraceConnection* connection, TraceTransaction* transaction,
void event_proc_execute(TraceDatabaseConnection* connection, TraceTransaction* transaction,
TraceProcedure* procedure, bool started, ntrace_result_t proc_result);
void event_trigger_execute(TraceConnection* connection, TraceTransaction* transaction,
void event_trigger_execute(TraceDatabaseConnection* connection, TraceTransaction* transaction,
TraceTrigger* trigger, bool started, ntrace_result_t trig_result);
void event_blr_compile(TraceConnection* connection,
void event_blr_compile(TraceDatabaseConnection* connection,
TraceTransaction* transaction, TraceBLRStatement* statement,
ntrace_counter_t time_millis, ntrace_result_t req_result);
void event_blr_execute(TraceConnection* connection,
void event_blr_execute(TraceDatabaseConnection* connection,
TraceTransaction* transaction, TraceBLRStatement* statement,
ntrace_result_t req_result);
void event_dyn_execute(TraceConnection* connection,
void event_dyn_execute(TraceDatabaseConnection* connection,
TraceTransaction* transaction, TraceDYNRequest* request,
ntrace_counter_t time_millis, ntrace_result_t req_result);
void event_service_attach(TraceService* service, ntrace_result_t att_result);
void event_service_attach(TraceServiceConnection* service, ntrace_result_t att_result);
void event_service_start(TraceService* service,
void event_service_start(TraceServiceConnection* service,
size_t switches_length, const char* switches,
ntrace_result_t start_result);
void event_service_query(TraceService* service,
void event_service_query(TraceServiceConnection* service,
size_t send_item_length, const ntrace_byte_t* send_items,
size_t recv_item_length, const ntrace_byte_t* recv_items,
ntrace_result_t query_result);
void event_service_detach(TraceService* service, ntrace_result_t detach_result);
void event_service_detach(TraceServiceConnection* service, ntrace_result_t detach_result);
void event_error(TraceBaseConnection* connection, TraceStatusVector* status, const char* function);
struct NotificationNeeds
{
@ -128,6 +130,7 @@ public:
bool event_service_start;
bool event_service_query;
bool event_service_detach;
bool event_error;
};
inline const NotificationNeeds& needs()
@ -194,14 +197,14 @@ private:
bool check_result(const TracePlugin* plugin, const char* module, const char* function, bool result);
/* DSQL statement lifecycle. To be moved to public and used directly when DSQL becomes a part of JRD */
void event_dsql_prepare(TraceConnection* connection, TraceTransaction* transaction,
void event_dsql_prepare(TraceDatabaseConnection* connection, TraceTransaction* transaction,
TraceSQLStatement* statement,
ntrace_counter_t time_millis, ntrace_result_t req_result);
void event_dsql_free(TraceConnection* connection,
void event_dsql_free(TraceDatabaseConnection* connection,
TraceSQLStatement* statement, unsigned short option);
void event_dsql_execute(TraceConnection* connection, TraceTransaction* transaction,
void event_dsql_execute(TraceDatabaseConnection* connection, TraceTransaction* transaction,
TraceSQLStatement* statement,
bool started, ntrace_result_t req_result);

View File

@ -71,6 +71,11 @@ int TraceConnectionImpl::getProcessID()
return getpid();
}
ntrace_connection_kind_t TraceConnectionImpl::getKind()
{
return connection_database;
}
const char* TraceConnectionImpl::getDatabaseName()
{
return m_att->att_filename.c_str();
@ -553,6 +558,11 @@ const char* TraceServiceImpl::getServiceName()
return m_svc->getServiceName();
}
ntrace_connection_kind_t TraceServiceImpl::getKind()
{
return connection_service;
}
int TraceServiceImpl::getProcessID()
{
return getpid();
@ -568,6 +578,11 @@ const char* TraceServiceImpl::getRoleName()
return NULL;
}
const char* TraceServiceImpl::getCharSet()
{
return NULL;
}
const char* TraceServiceImpl::getRemoteProtocol()
{
return m_svc->getNetworkProtocol().c_str();
@ -607,6 +622,38 @@ TraceRuntimeStats::TraceRuntimeStats(Database* dbb, RuntimeStatistics* baseline,
}
}
SINT64 TraceRuntimeStats::m_dummy_counts[DBB_max_dbb_count] = {0};
SINT64 TraceRuntimeStats::m_dummy_counts[RuntimeStatistics::TOTAL_ITEMS] = {0};
/// TraceStatusVectorImpl
const char* TraceStatusVectorImpl::getText()
{
if (m_error.isEmpty() && (hasError() || hasWarning()))
{
char buff[1024];
const ISC_STATUS* p = m_status;
const ISC_STATUS* end = m_status + ISC_STATUS_LENGTH;
while (p < end - 1)
{
if (p[0] == isc_arg_gds && p[1] == 0)
{
p += 2;
continue;
}
const ISC_STATUS code = *p ? p[1] : 0;
if (!fb_interpret(buff, sizeof(buff), &p))
break;
string s;
s.printf("%9lu : %s\n", code, buff);
m_error += s;
}
}
return m_error.c_str();
}
} // namespace Jrd

View File

@ -47,7 +47,7 @@ class Database;
class Attachment;
class jrd_tra;
class TraceConnectionImpl : public TraceConnection
class TraceConnectionImpl : public TraceDatabaseConnection
{
public:
TraceConnectionImpl(const Attachment* att) :
@ -56,6 +56,8 @@ public:
virtual int getConnectionID();
virtual int getProcessID();
virtual ntrace_connection_kind_t getKind();
virtual const char* getDatabaseName();
virtual const char* getUserName();
virtual const char* getRoleName();
@ -311,7 +313,7 @@ private:
};
class TraceServiceImpl : public TraceService
class TraceServiceImpl : public TraceServiceConnection
{
public:
TraceServiceImpl(const Service* svc) :
@ -321,9 +323,12 @@ public:
virtual ntrace_service_t getServiceID();
virtual const char* getServiceMgr();
virtual const char* getServiceName();
virtual ntrace_connection_kind_t getKind();
virtual int getProcessID();
virtual const char* getUserName();
virtual const char* getRoleName();
virtual int getProcessID();
virtual const char* getCharSet();
virtual const char* getRemoteProtocol();
virtual const char* getRemoteAddress();
virtual int getRemoteProcessID();
@ -345,7 +350,7 @@ public:
private:
PerformanceInfo m_info;
TraceCountsArray m_counts;
static SINT64 m_dummy_counts[DBB_max_dbb_count]; // Zero-initialized array with zero counts
static SINT64 m_dummy_counts[RuntimeStatistics::TOTAL_ITEMS]; // Zero-initialized array with zero counts
};
@ -372,7 +377,7 @@ public:
virtual const char* getFirebirdRootDirectory();
virtual const char* getDatabaseName() { return m_filename; }
virtual TraceConnection* getConnection()
virtual TraceDatabaseConnection* getConnection()
{
if (m_attachment)
return &m_trace_conn;
@ -391,6 +396,36 @@ private:
};
class TraceStatusVectorImpl : public TraceStatusVector
{
public:
TraceStatusVectorImpl(const ISC_STATUS* status) :
m_status(status)
{
}
virtual bool hasError()
{
return m_status && (m_status[1] != 0);
}
virtual bool hasWarning()
{
return m_status && (m_status[1] == 0) && (m_status[2] == isc_arg_warning);
}
virtual const ISC_STATUS* getStatus()
{
return m_status;
}
virtual const char* getText();
private:
const ISC_STATUS* m_status;
Firebird::string m_error;
};
} // namespace Jrd
#endif // JRD_TRACE_OBJECTS_H

View File

@ -91,6 +91,8 @@ TracePlugin* TracePluginImpl::createFullPlugin(const TracePluginConfig& configur
plugin_ptr->tpl_event_service_start = ntrace_event_service_start;
plugin_ptr->tpl_event_service_query = ntrace_event_service_query;
plugin_ptr->tpl_event_service_detach = ntrace_event_service_detach;
plugin_ptr->tpl_event_error = ntrace_event_error;
}
catch(const Firebird::Exception&)
{
@ -266,7 +268,7 @@ void TracePluginImpl::logRecord(const char* action)
record = "";
}
void TracePluginImpl::logRecordConn(const char* action, TraceConnection* connection)
void TracePluginImpl::logRecordConn(const char* action, TraceDatabaseConnection* connection)
{
// Lookup connection description
const int conn_id = connection->getConnectionID();
@ -312,7 +314,7 @@ void TracePluginImpl::logRecordConn(const char* action, TraceConnection* connect
logRecord(action);
}
void TracePluginImpl::logRecordTrans(const char* action, TraceConnection* connection,
void TracePluginImpl::logRecordTrans(const char* action, TraceDatabaseConnection* connection,
TraceTransaction* transaction)
{
const int tra_id = transaction->getTransactionID();
@ -345,7 +347,7 @@ void TracePluginImpl::logRecordTrans(const char* action, TraceConnection* connec
logRecordConn(action, connection);
}
void TracePluginImpl::logRecordProc(const char* action, TraceConnection* connection,
void TracePluginImpl::logRecordProc(const char* action, TraceDatabaseConnection* connection,
TraceTransaction* transaction, const char* proc_name)
{
string temp;
@ -360,7 +362,7 @@ void TracePluginImpl::logRecordProc(const char* action, TraceConnection* connect
}
}
void TracePluginImpl::logRecordStmt(const char* action, TraceConnection* connection,
void TracePluginImpl::logRecordStmt(const char* action, TraceDatabaseConnection* connection,
TraceTransaction* transaction, TraceStatement* statement, bool isSQL)
{
const int stmt_id = statement->getStmtID();
@ -430,7 +432,7 @@ void TracePluginImpl::logRecordStmt(const char* action, TraceConnection* connect
}
}
void TracePluginImpl::logRecordServ(const char* action, TraceService* service)
void TracePluginImpl::logRecordServ(const char* action, TraceServiceConnection* service)
{
const ntrace_service_t svc_id = service->getServiceID();
bool reg = false;
@ -464,6 +466,34 @@ void TracePluginImpl::logRecordServ(const char* action, TraceService* service)
logRecord(action);
}
void TracePluginImpl::logRecordError(const char* action, TraceBaseConnection* connection,
TraceStatusVector* status)
{
const char* err = status->getText();
record = "";
record.insert(0, err);
if (connection)
{
switch (connection->getKind())
{
case connection_database:
logRecordConn(action, (TraceDatabaseConnection*) connection);
break;
case connection_service:
logRecordServ(action, (TraceServiceConnection*) connection);
break;
default:
break;
}
}
else
logRecord(action);
}
void TracePluginImpl::appendGlobalCounts(const PerformanceInfo* info)
{
string temp;
@ -497,6 +527,24 @@ void TracePluginImpl::appendGlobalCounts(const PerformanceInfo* info)
record.append(temp);
}
if ((cnt = info->pin_counters[RuntimeStatistics::SORTS]) != 0)
{
temp.printf(", %"QUADFORMAT"d sort(s)", cnt);
record.append(temp);
}
if ((cnt = info->pin_counters[RuntimeStatistics::SORT_GETS]) != 0)
{
temp.printf(", %"QUADFORMAT"d sort get(s)", cnt);
record.append(temp);
}
if ((cnt = info->pin_counters[RuntimeStatistics::SORT_PUTS]) != 0)
{
temp.printf(", %"QUADFORMAT"d sort put(s)", cnt);
record.append(temp);
}
record.append(NEWLINE);
}
@ -939,7 +987,7 @@ void TracePluginImpl::log_finalize()
logWriter = NULL;
}
void TracePluginImpl::register_connection(TraceConnection* connection)
void TracePluginImpl::register_connection(TraceDatabaseConnection* connection)
{
ConnectionData conn_data;
conn_data.id = connection->getConnectionID();
@ -997,7 +1045,7 @@ void TracePluginImpl::register_connection(TraceConnection* connection)
}
}
void TracePluginImpl::log_event_attach(TraceConnection* connection,
void TracePluginImpl::log_event_attach(TraceDatabaseConnection* connection,
ntrace_boolean_t create_db, ntrace_result_t att_result)
{
if (config.log_connections)
@ -1024,7 +1072,7 @@ void TracePluginImpl::log_event_attach(TraceConnection* connection,
}
}
void TracePluginImpl::log_event_detach(TraceConnection* connection, ntrace_boolean_t drop_db)
void TracePluginImpl::log_event_detach(TraceDatabaseConnection* connection, ntrace_boolean_t drop_db)
{
if (config.log_connections)
{
@ -1100,7 +1148,7 @@ void TracePluginImpl::register_transaction(TraceTransaction* transaction)
}
void TracePluginImpl::log_event_transaction_start(TraceConnection* connection,
void TracePluginImpl::log_event_transaction_start(TraceDatabaseConnection* connection,
TraceTransaction* transaction, size_t /*tpb_length*/,
const ntrace_byte_t* /*tpb*/, ntrace_result_t tra_result)
{
@ -1126,7 +1174,7 @@ void TracePluginImpl::log_event_transaction_start(TraceConnection* connection,
}
}
void TracePluginImpl::log_event_transaction_end(TraceConnection* connection,
void TracePluginImpl::log_event_transaction_end(TraceDatabaseConnection* connection,
TraceTransaction* transaction, ntrace_boolean_t commit,
ntrace_boolean_t retain_context, ntrace_result_t tra_result)
{
@ -1176,7 +1224,7 @@ void TracePluginImpl::log_event_transaction_end(TraceConnection* connection,
}
}
void TracePluginImpl::log_event_set_context(TraceConnection* connection,
void TracePluginImpl::log_event_set_context(TraceDatabaseConnection* connection,
TraceTransaction* transaction, TraceContextVariable* variable)
{
const char* ns = variable->getNameSpace();
@ -1199,7 +1247,7 @@ void TracePluginImpl::log_event_set_context(TraceConnection* connection,
}
}
void TracePluginImpl::log_event_proc_execute(TraceConnection* connection, TraceTransaction* transaction,
void TracePluginImpl::log_event_proc_execute(TraceDatabaseConnection* connection, TraceTransaction* transaction,
TraceProcedure* procedure, bool started, ntrace_result_t proc_result)
{
if (!config.log_procedure_start && started)
@ -1342,7 +1390,7 @@ void TracePluginImpl::register_sql_statement(TraceSQLStatement* statement)
}
}
void TracePluginImpl::log_event_dsql_prepare(TraceConnection* connection,
void TracePluginImpl::log_event_dsql_prepare(TraceDatabaseConnection* connection,
TraceTransaction* transaction, TraceSQLStatement* statement,
ntrace_counter_t time_millis, ntrace_result_t req_result)
{
@ -1369,7 +1417,7 @@ void TracePluginImpl::log_event_dsql_prepare(TraceConnection* connection,
}
}
void TracePluginImpl::log_event_dsql_free(TraceConnection* connection,
void TracePluginImpl::log_event_dsql_free(TraceDatabaseConnection* connection,
TraceSQLStatement* statement, unsigned short option)
{
if (config.log_statement_free)
@ -1389,7 +1437,7 @@ void TracePluginImpl::log_event_dsql_free(TraceConnection* connection,
}
}
void TracePluginImpl::log_event_dsql_execute(TraceConnection* connection,
void TracePluginImpl::log_event_dsql_execute(TraceDatabaseConnection* connection,
TraceTransaction* transaction, TraceSQLStatement* statement,
bool started, ntrace_result_t req_result)
{
@ -1486,7 +1534,7 @@ void TracePluginImpl::register_blr_statement(TraceBLRStatement* statement)
statements.add(stmt_data);
}
void TracePluginImpl::log_event_blr_compile(TraceConnection* connection,
void TracePluginImpl::log_event_blr_compile(TraceDatabaseConnection* connection,
TraceTransaction* transaction, TraceBLRStatement* statement,
ntrace_counter_t time_millis, ntrace_result_t req_result)
{
@ -1522,7 +1570,7 @@ void TracePluginImpl::log_event_blr_compile(TraceConnection* connection,
}
}
void TracePluginImpl::log_event_blr_execute(TraceConnection* connection,
void TracePluginImpl::log_event_blr_execute(TraceDatabaseConnection* connection,
TraceTransaction* transaction, TraceBLRStatement* statement,
ntrace_result_t req_result)
{
@ -1558,7 +1606,7 @@ void TracePluginImpl::log_event_blr_execute(TraceConnection* connection,
}
}
void TracePluginImpl::log_event_dyn_execute(TraceConnection* connection,
void TracePluginImpl::log_event_dyn_execute(TraceDatabaseConnection* connection,
TraceTransaction* transaction, TraceDYNRequest* request,
ntrace_counter_t time_millis, ntrace_result_t req_result)
{
@ -1617,7 +1665,7 @@ void TracePluginImpl::log_event_dyn_execute(TraceConnection* connection,
}
void TracePluginImpl::register_service(TraceService* service)
void TracePluginImpl::register_service(TraceServiceConnection* service)
{
string username(service->getUserName());
string remote_address;
@ -1660,7 +1708,7 @@ void TracePluginImpl::register_service(TraceService* service)
}
bool TracePluginImpl::checkServiceFilter(TraceService* service, bool started)
bool TracePluginImpl::checkServiceFilter(TraceServiceConnection* service, bool started)
{
ReadLockGuard lock(servicesLock);
@ -1698,7 +1746,7 @@ bool TracePluginImpl::checkServiceFilter(TraceService* service, bool started)
}
void TracePluginImpl::log_event_service_attach(TraceService* service,
void TracePluginImpl::log_event_service_attach(TraceServiceConnection* service,
ntrace_result_t att_result)
{
if (config.log_services)
@ -1724,7 +1772,7 @@ void TracePluginImpl::log_event_service_attach(TraceService* service,
}
}
void TracePluginImpl::log_event_service_start(TraceService* service,
void TracePluginImpl::log_event_service_start(TraceServiceConnection* service,
size_t switches_length, const char* switches, ntrace_result_t start_result)
{
if (config.log_services)
@ -1776,7 +1824,7 @@ void TracePluginImpl::log_event_service_start(TraceService* service,
}
}
void TracePluginImpl::log_event_service_query(TraceService* service,
void TracePluginImpl::log_event_service_query(TraceServiceConnection* service,
size_t send_item_length, const ntrace_byte_t* send_items,
size_t recv_item_length, const ntrace_byte_t* recv_items,
ntrace_result_t query_result)
@ -1814,7 +1862,7 @@ void TracePluginImpl::log_event_service_query(TraceService* service,
}
}
void TracePluginImpl::log_event_service_detach(TraceService* service, ntrace_result_t detach_result)
void TracePluginImpl::log_event_service_detach(TraceServiceConnection* service, ntrace_result_t detach_result)
{
if (config.log_services)
{
@ -1848,7 +1896,7 @@ void TracePluginImpl::log_event_service_detach(TraceService* service, ntrace_res
}
}
void TracePluginImpl::log_event_trigger_execute(TraceConnection* connection, TraceTransaction* transaction,
void TracePluginImpl::log_event_trigger_execute(TraceDatabaseConnection* connection, TraceTransaction* transaction,
TraceTrigger* trigger, bool started, ntrace_result_t trig_result)
{
if (!config.log_trigger_start && started)
@ -1953,6 +2001,22 @@ void TracePluginImpl::log_event_trigger_execute(TraceConnection* connection, Tra
logRecordTrans(event_type, connection, transaction);
}
void TracePluginImpl::log_event_error(TraceBaseConnection* connection, TraceStatusVector* status, const char* function)
{
if (!config.log_errors)
return;
string event_type;
if (status->hasError())
event_type.printf("ERROR AT %s", function);
else if (status->hasWarning())
event_type.printf("WARNING AT %s", function);
else
return;
logRecordError(event_type.c_str(), connection, status);
}
//***************************** PLUGIN INTERFACE ********************************
ntrace_boolean_t TracePluginImpl::ntrace_shutdown(const TracePlugin* tpl_plugin)
@ -1975,7 +2039,7 @@ const char* TracePluginImpl::ntrace_get_error(const TracePlugin* /*tpl_plugin*/)
// Create/close attachment
ntrace_boolean_t TracePluginImpl::ntrace_event_attach(const TracePlugin* tpl_plugin,
TraceConnection* connection, ntrace_boolean_t create_db,
TraceDatabaseConnection* connection, ntrace_boolean_t create_db,
ntrace_result_t att_result)
{
try
@ -1992,7 +2056,7 @@ ntrace_boolean_t TracePluginImpl::ntrace_event_attach(const TracePlugin* tpl_plu
}
ntrace_boolean_t TracePluginImpl::ntrace_event_detach(const TracePlugin* tpl_plugin,
TraceConnection* connection, ntrace_boolean_t drop_db)
TraceDatabaseConnection* connection, ntrace_boolean_t drop_db)
{
try
{
@ -2008,7 +2072,7 @@ ntrace_boolean_t TracePluginImpl::ntrace_event_detach(const TracePlugin* tpl_plu
// Start/end transaction
ntrace_boolean_t TracePluginImpl::ntrace_event_transaction_start(const TracePlugin* tpl_plugin,
TraceConnection* connection, TraceTransaction* transaction,
TraceDatabaseConnection* connection, TraceTransaction* transaction,
size_t tpb_length, const ntrace_byte_t* tpb, ntrace_result_t tra_result)
{
try
@ -2025,7 +2089,7 @@ ntrace_boolean_t TracePluginImpl::ntrace_event_transaction_start(const TracePlug
}
ntrace_boolean_t TracePluginImpl::ntrace_event_transaction_end(const TracePlugin* tpl_plugin,
TraceConnection* connection, TraceTransaction* transaction,
TraceDatabaseConnection* connection, TraceTransaction* transaction,
ntrace_boolean_t commit, ntrace_boolean_t retain_context, ntrace_result_t tra_result)
{
try
@ -2043,7 +2107,7 @@ ntrace_boolean_t TracePluginImpl::ntrace_event_transaction_end(const TracePlugin
// Assignment to context variables
ntrace_boolean_t TracePluginImpl::ntrace_event_set_context(const struct TracePlugin* tpl_plugin,
TraceConnection* connection, TraceTransaction* transaction,
TraceDatabaseConnection* connection, TraceTransaction* transaction,
TraceContextVariable* variable)
{
try
@ -2061,7 +2125,7 @@ ntrace_boolean_t TracePluginImpl::ntrace_event_set_context(const struct TracePlu
// Stored procedure executing
ntrace_boolean_t TracePluginImpl::ntrace_event_proc_execute(const struct TracePlugin* tpl_plugin,
TraceConnection* connection, TraceTransaction* transaction, TraceProcedure* procedure,
TraceDatabaseConnection* connection, TraceTransaction* transaction, TraceProcedure* procedure,
bool started, ntrace_result_t proc_result)
{
try
@ -2078,7 +2142,7 @@ ntrace_boolean_t TracePluginImpl::ntrace_event_proc_execute(const struct TracePl
}
ntrace_boolean_t TracePluginImpl::ntrace_event_trigger_execute(const TracePlugin* tpl_plugin,
TraceConnection* connection, TraceTransaction* transaction, TraceTrigger* trigger,
TraceDatabaseConnection* connection, TraceTransaction* transaction, TraceTrigger* trigger,
bool started, ntrace_result_t trig_result)
{
try
@ -2097,7 +2161,7 @@ ntrace_boolean_t TracePluginImpl::ntrace_event_trigger_execute(const TracePlugin
// DSQL statement lifecycle
ntrace_boolean_t TracePluginImpl::ntrace_event_dsql_prepare(const TracePlugin* tpl_plugin,
TraceConnection* connection, TraceTransaction* transaction,
TraceDatabaseConnection* connection, TraceTransaction* transaction,
TraceSQLStatement* statement, ntrace_counter_t time_millis, ntrace_result_t req_result)
{
try
@ -2114,7 +2178,7 @@ ntrace_boolean_t TracePluginImpl::ntrace_event_dsql_prepare(const TracePlugin* t
}
ntrace_boolean_t TracePluginImpl::ntrace_event_dsql_free(const TracePlugin* tpl_plugin,
TraceConnection* connection, TraceSQLStatement* statement, unsigned short option)
TraceDatabaseConnection* connection, TraceSQLStatement* statement, unsigned short option)
{
try
{
@ -2130,7 +2194,7 @@ ntrace_boolean_t TracePluginImpl::ntrace_event_dsql_free(const TracePlugin* tpl_
}
ntrace_boolean_t TracePluginImpl::ntrace_event_dsql_execute(const TracePlugin* tpl_plugin,
TraceConnection* connection, TraceTransaction* transaction, TraceSQLStatement* statement,
TraceDatabaseConnection* connection, TraceTransaction* transaction, TraceSQLStatement* statement,
bool started, ntrace_result_t req_result)
{
try
@ -2149,7 +2213,7 @@ ntrace_boolean_t TracePluginImpl::ntrace_event_dsql_execute(const TracePlugin* t
// BLR requests
ntrace_boolean_t TracePluginImpl::ntrace_event_blr_compile(const TracePlugin* tpl_plugin,
TraceConnection* connection, TraceTransaction* transaction,
TraceDatabaseConnection* connection, TraceTransaction* transaction,
TraceBLRStatement* statement, ntrace_counter_t time_millis, ntrace_result_t req_result)
{
try
@ -2166,7 +2230,7 @@ ntrace_boolean_t TracePluginImpl::ntrace_event_blr_compile(const TracePlugin* tp
}
ntrace_boolean_t TracePluginImpl::ntrace_event_blr_execute(const TracePlugin* tpl_plugin,
TraceConnection* connection, TraceTransaction* transaction,
TraceDatabaseConnection* connection, TraceTransaction* transaction,
TraceBLRStatement* statement, ntrace_result_t req_result)
{
try
@ -2184,7 +2248,7 @@ ntrace_boolean_t TracePluginImpl::ntrace_event_blr_execute(const TracePlugin* tp
// DYN requests
ntrace_boolean_t TracePluginImpl::ntrace_event_dyn_execute(const TracePlugin* tpl_plugin,
TraceConnection* connection, TraceTransaction* transaction,
TraceDatabaseConnection* connection, TraceTransaction* transaction,
TraceDYNRequest* request, ntrace_counter_t time_millis, ntrace_result_t req_result)
{
try
@ -2202,7 +2266,7 @@ ntrace_boolean_t TracePluginImpl::ntrace_event_dyn_execute(const TracePlugin* tp
// Using the services
ntrace_boolean_t TracePluginImpl::ntrace_event_service_attach(const TracePlugin* tpl_plugin,
TraceService* service, ntrace_result_t att_result)
TraceServiceConnection* service, ntrace_result_t att_result)
{
try
{
@ -2218,7 +2282,7 @@ ntrace_boolean_t TracePluginImpl::ntrace_event_service_attach(const TracePlugin*
}
ntrace_boolean_t TracePluginImpl::ntrace_event_service_start(const TracePlugin* tpl_plugin,
TraceService* service, size_t switches_length, const char* switches,
TraceServiceConnection* service, size_t switches_length, const char* switches,
ntrace_result_t start_result)
{
try
@ -2235,7 +2299,7 @@ ntrace_boolean_t TracePluginImpl::ntrace_event_service_start(const TracePlugin*
}
ntrace_boolean_t TracePluginImpl::ntrace_event_service_query(const TracePlugin* tpl_plugin,
TraceService* service, size_t send_item_length,
TraceServiceConnection* service, size_t send_item_length,
const ntrace_byte_t* send_items, size_t recv_item_length,
const ntrace_byte_t* recv_items, ntrace_result_t query_result)
{
@ -2255,7 +2319,7 @@ ntrace_boolean_t TracePluginImpl::ntrace_event_service_query(const TracePlugin*
}
ntrace_boolean_t TracePluginImpl::ntrace_event_service_detach(const TracePlugin* tpl_plugin,
TraceService* service, ntrace_result_t detach_result)
TraceServiceConnection* service, ntrace_result_t detach_result)
{
try
{
@ -2269,3 +2333,19 @@ ntrace_boolean_t TracePluginImpl::ntrace_event_service_detach(const TracePlugin*
return false;
}
}
ntrace_boolean_t TracePluginImpl::ntrace_event_error(const TracePlugin* tpl_plugin,
TraceBaseConnection* connection, TraceStatusVector* status, const char* function)
{
try
{
static_cast<TracePluginImpl*>(tpl_plugin->tpl_object)->log_event_error(
connection, status, function);
return true;
}
catch(const Firebird::Exception& ex)
{
marshal_exception(ex);
return false;
}
}

View File

@ -178,83 +178,86 @@ private:
void formatStringArgument(Firebird::string& result, const UCHAR* str, size_t len);
// register various objects
void register_connection(TraceConnection* connection);
void register_connection(TraceDatabaseConnection* connection);
void register_transaction(TraceTransaction* transaction);
void register_sql_statement(TraceSQLStatement* statement);
void register_blr_statement(TraceBLRStatement* statement);
void register_service(TraceService* service);
void register_service(TraceServiceConnection* service);
bool checkServiceFilter(TraceService* service, bool started);
bool checkServiceFilter(TraceServiceConnection* service, bool started);
// Write message to text log file
void logRecord(const char* action);
void logRecordConn(const char* action, TraceConnection* connection);
void logRecordTrans(const char* action, TraceConnection* connection,
void logRecordConn(const char* action, TraceDatabaseConnection* connection);
void logRecordTrans(const char* action, TraceDatabaseConnection* connection,
TraceTransaction* transaction);
void logRecordProc(const char* action, TraceConnection* connection,
void logRecordProc(const char* action, TraceDatabaseConnection* connection,
TraceTransaction* transaction, const char* proc_name);
void logRecordStmt(const char* action, TraceConnection* connection,
void logRecordStmt(const char* action, TraceDatabaseConnection* connection,
TraceTransaction* transaction, TraceStatement* statement,
bool isSQL);
void logRecordServ(const char* action, TraceService* service);
void logRecordServ(const char* action, TraceServiceConnection* service);
void logRecordError(const char* action, TraceBaseConnection* connection, TraceStatusVector* status);
/* Methods which do logging of events to file */
void log_init();
void log_finalize();
void log_event_attach(
TraceConnection* connection, ntrace_boolean_t create_db,
TraceDatabaseConnection* connection, ntrace_boolean_t create_db,
ntrace_result_t att_result);
void log_event_detach(
TraceConnection* connection, ntrace_boolean_t drop_db);
TraceDatabaseConnection* connection, ntrace_boolean_t drop_db);
void log_event_transaction_start(
TraceConnection* connection, TraceTransaction* transaction,
TraceDatabaseConnection* connection, TraceTransaction* transaction,
size_t tpb_length, const ntrace_byte_t* tpb, ntrace_result_t tra_result);
void log_event_transaction_end(
TraceConnection* connection, TraceTransaction* transaction,
TraceDatabaseConnection* connection, TraceTransaction* transaction,
ntrace_boolean_t commit, ntrace_boolean_t retain_context, ntrace_result_t tra_result);
void log_event_set_context(
TraceConnection* connection, TraceTransaction* transaction,
TraceDatabaseConnection* connection, TraceTransaction* transaction,
TraceContextVariable* variable);
void log_event_proc_execute(
TraceConnection* connection, TraceTransaction* transaction, TraceProcedure* procedure,
TraceDatabaseConnection* connection, TraceTransaction* transaction, TraceProcedure* procedure,
bool started, ntrace_result_t proc_result);
void log_event_trigger_execute(
TraceConnection* connection, TraceTransaction* transaction, TraceTrigger* trigger,
TraceDatabaseConnection* connection, TraceTransaction* transaction, TraceTrigger* trigger,
bool started, ntrace_result_t trig_result);
void log_event_dsql_prepare(
TraceConnection* connection, TraceTransaction* transaction,
TraceDatabaseConnection* connection, TraceTransaction* transaction,
TraceSQLStatement* statement, ntrace_counter_t time_millis, ntrace_result_t req_result);
void log_event_dsql_free(
TraceConnection* connection, TraceSQLStatement* statement, unsigned short option);
TraceDatabaseConnection* connection, TraceSQLStatement* statement, unsigned short option);
void log_event_dsql_execute(
TraceConnection* connection, TraceTransaction* transaction, TraceSQLStatement* statement,
TraceDatabaseConnection* connection, TraceTransaction* transaction, TraceSQLStatement* statement,
bool started, ntrace_result_t req_result);
void log_event_blr_compile(
TraceConnection* connection, TraceTransaction* transaction,
TraceDatabaseConnection* connection, TraceTransaction* transaction,
TraceBLRStatement* statement, ntrace_counter_t time_millis, ntrace_result_t req_result);
void log_event_blr_execute(
TraceConnection* connection, TraceTransaction* transaction,
TraceDatabaseConnection* connection, TraceTransaction* transaction,
TraceBLRStatement* statement, ntrace_result_t req_result);
void log_event_dyn_execute(
TraceConnection* connection, TraceTransaction* transaction,
TraceDatabaseConnection* connection, TraceTransaction* transaction,
TraceDYNRequest* request, ntrace_counter_t time_millis,
ntrace_result_t req_result);
void log_event_service_attach(TraceService* service, ntrace_result_t att_result);
void log_event_service_start(TraceService* service, size_t switches_length, const char* switches,
void log_event_service_attach(TraceServiceConnection* service, ntrace_result_t att_result);
void log_event_service_start(TraceServiceConnection* service, size_t switches_length, const char* switches,
ntrace_result_t start_result);
void log_event_service_query(TraceService* service, size_t send_item_length,
void log_event_service_query(TraceServiceConnection* service, size_t send_item_length,
const ntrace_byte_t* send_items, size_t recv_item_length,
const ntrace_byte_t* recv_items, ntrace_result_t query_result);
void log_event_service_detach(TraceService* service, ntrace_result_t detach_result);
void log_event_service_detach(TraceServiceConnection* service, ntrace_result_t detach_result);
void log_event_error(TraceBaseConnection* connection, TraceStatusVector* status, const char* function);
/* Finalize plugin. Called when database is closed by the engine */
static ntrace_boolean_t ntrace_shutdown(const TracePlugin* tpl_plugin);
@ -264,69 +267,72 @@ private:
/* Create/close attachment */
static ntrace_boolean_t ntrace_event_attach(const TracePlugin* tpl_plugin,
TraceConnection* connection, ntrace_boolean_t create_db,
TraceDatabaseConnection* connection, ntrace_boolean_t create_db,
ntrace_result_t att_result);
static ntrace_boolean_t ntrace_event_detach(const TracePlugin* tpl_plugin,
TraceConnection* connection, ntrace_boolean_t drop_db);
TraceDatabaseConnection* connection, ntrace_boolean_t drop_db);
/* Start/end transaction */
static ntrace_boolean_t ntrace_event_transaction_start(const TracePlugin* tpl_plugin,
TraceConnection* connection, TraceTransaction* transaction,
TraceDatabaseConnection* connection, TraceTransaction* transaction,
size_t tpb_length, const ntrace_byte_t* tpb, ntrace_result_t tra_result);
static ntrace_boolean_t ntrace_event_transaction_end(const TracePlugin* tpl_plugin,
TraceConnection* connection, TraceTransaction* transaction,
TraceDatabaseConnection* connection, TraceTransaction* transaction,
ntrace_boolean_t commit, ntrace_boolean_t retain_context, ntrace_result_t tra_result);
/* Assignment to context variables */
static ntrace_boolean_t ntrace_event_set_context(const struct TracePlugin* tpl_plugin,
TraceConnection* connection, TraceTransaction* transaction,
TraceDatabaseConnection* connection, TraceTransaction* transaction,
TraceContextVariable* variable);
/* Stored procedure executing */
static ntrace_boolean_t ntrace_event_proc_execute(const struct TracePlugin* tpl_plugin,
TraceConnection* connection, TraceTransaction* transaction, TraceProcedure* procedure,
TraceDatabaseConnection* connection, TraceTransaction* transaction, TraceProcedure* procedure,
bool started, ntrace_result_t proc_result);
static ntrace_boolean_t ntrace_event_trigger_execute(const TracePlugin* tpl_plugin,
TraceConnection* connection, TraceTransaction* transaction, TraceTrigger* trigger,
TraceDatabaseConnection* connection, TraceTransaction* transaction, TraceTrigger* trigger,
bool started, ntrace_result_t trig_result);
/* DSQL statement lifecycle */
static ntrace_boolean_t ntrace_event_dsql_prepare(const TracePlugin* tpl_plugin,
TraceConnection* connection, TraceTransaction* transaction,
TraceDatabaseConnection* connection, TraceTransaction* transaction,
TraceSQLStatement* statement, ntrace_counter_t time_millis, ntrace_result_t req_result);
static ntrace_boolean_t ntrace_event_dsql_free(const TracePlugin* tpl_plugin,
TraceConnection* connection, TraceSQLStatement* statement, unsigned short option);
TraceDatabaseConnection* connection, TraceSQLStatement* statement, unsigned short option);
static ntrace_boolean_t ntrace_event_dsql_execute(const TracePlugin* tpl_plugin,
TraceConnection* connection, TraceTransaction* transaction, TraceSQLStatement* statement,
TraceDatabaseConnection* connection, TraceTransaction* transaction, TraceSQLStatement* statement,
bool started, ntrace_result_t req_result);
/* BLR requests */
static ntrace_boolean_t ntrace_event_blr_compile(const TracePlugin* tpl_plugin,
TraceConnection* connection, TraceTransaction* transaction,
TraceDatabaseConnection* connection, TraceTransaction* transaction,
TraceBLRStatement* statement, ntrace_counter_t time_millis, ntrace_result_t req_result);
static ntrace_boolean_t ntrace_event_blr_execute(const TracePlugin* tpl_plugin,
TraceConnection* connection, TraceTransaction* transaction,
TraceDatabaseConnection* connection, TraceTransaction* transaction,
TraceBLRStatement* statement, ntrace_result_t req_result);
/* DYN requests */
static ntrace_boolean_t ntrace_event_dyn_execute(const TracePlugin* tpl_plugin,
TraceConnection* connection, TraceTransaction* transaction,
TraceDatabaseConnection* connection, TraceTransaction* transaction,
TraceDYNRequest* request, ntrace_counter_t time_millis,
ntrace_result_t req_result);
/* Using the services */
static ntrace_boolean_t ntrace_event_service_attach(const TracePlugin* tpl_plugin,
TraceService* service, ntrace_result_t att_result);
TraceServiceConnection* service, ntrace_result_t att_result);
static ntrace_boolean_t ntrace_event_service_start(const TracePlugin* tpl_plugin,
TraceService* service, size_t switches_length, const char* switches,
TraceServiceConnection* service, size_t switches_length, const char* switches,
ntrace_result_t start_result);
static ntrace_boolean_t ntrace_event_service_query(const TracePlugin* tpl_plugin,
TraceService* service, size_t send_item_length,
TraceServiceConnection* service, size_t send_item_length,
const ntrace_byte_t* send_items, size_t recv_item_length,
const ntrace_byte_t* recv_items, ntrace_result_t query_result);
static ntrace_boolean_t ntrace_event_service_detach(const TracePlugin* tpl_plugin,
TraceService* service, ntrace_result_t detach_result);
TraceServiceConnection* service, ntrace_result_t detach_result);
static ntrace_boolean_t ntrace_event_error(const struct TracePlugin* tpl_plugin,
TraceBaseConnection* connection, TraceStatusVector* status, const char* function);
};
#endif // TRACEPLUGINIMPL_H

View File

@ -84,6 +84,9 @@
# Put context variable change records (RDB$SET_CONTEXT)
#log_context false
# Put errors happened
#log_errors false
# Print access path (plan) with sql statement
print_plan false
@ -178,6 +181,9 @@
# Put service query records
log_service_query false
# Put errors happened
#log_errors false
</services>

View File

@ -35,6 +35,7 @@
STR_PARAMETER(include_filter, "")
STR_PARAMETER(exclude_filter, "")
PATH_PARAMETER(log_filename, "")
BOOL_PARAMETER(log_errors, false)
BOOL_PARAMETER(enabled, false)
UINT_PARAMETER(max_log_size, 0)

View File

@ -45,7 +45,7 @@ FB_DLL_EXPORT ntrace_boolean_t trace_create(TraceInitInfo* initInfo, const Trace
dbname ? dbname : "",
config);
TraceConnection* connection = initInfo->getConnection();
TraceDatabaseConnection* connection = initInfo->getConnection();
if (!config.enabled ||
(config.connection_id && connection && (connection->getConnectionID() != config.connection_id)))
{