mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-30 20:03:03 +01:00
333 lines
12 KiB
C++
333 lines
12 KiB
C++
/*
|
|
* PROGRAM: SQL Trace plugin
|
|
* MODULE: TracePluginImpl.h
|
|
* DESCRIPTION: Plugin implementation
|
|
*
|
|
* 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 Nickolay Samofatov
|
|
* for the Firebird Open Source RDBMS project.
|
|
*
|
|
* Copyright (c) 2004 Nickolay Samofatov <nickolay@broadviewsoftware.com>
|
|
* and all contributors signed below.
|
|
*
|
|
* All Rights Reserved.
|
|
* Contributor(s): ______________________________________.
|
|
*
|
|
* 2008 Khorsun Vladyslav
|
|
*/
|
|
|
|
#ifndef TRACEPLUGINIMPL_H
|
|
#define TRACEPLUGINIMPL_H
|
|
|
|
#include "../../jrd/ntrace.h"
|
|
#include "TracePluginConfig.h"
|
|
#include "../../jrd/intl_classes.h"
|
|
#include "../../jrd/evl_string.h"
|
|
#include "../../jrd/TextType.h"
|
|
#include "../../jrd/SimilarToMatcher.h"
|
|
#include "../../common/classes/rwlock.h"
|
|
#include "../../common/classes/GenericMap.h"
|
|
#include "../../common/classes/locks.h"
|
|
|
|
// Bring in off_t
|
|
#include <sys/types.h>
|
|
|
|
|
|
class TracePluginImpl
|
|
{
|
|
public:
|
|
// Create skeletal plugin (to report initialization error)
|
|
static TracePlugin* createSkeletalPlugin();
|
|
|
|
// Create trace plugin for particular database
|
|
static TracePlugin* createFullPlugin(const TracePluginConfig& configuration, TraceInitInfo* initInfo);
|
|
|
|
// Serialize exception to TLS buffer to return it to user
|
|
static void marshal_exception(const Firebird::Exception& ex);
|
|
|
|
// Data for tracked (active) connections
|
|
struct ConnectionData
|
|
{
|
|
int id;
|
|
Firebird::string* description;
|
|
|
|
// Deallocate memory used by objects hanging off this structure
|
|
void deallocate_references()
|
|
{
|
|
delete description;
|
|
description = NULL;
|
|
}
|
|
|
|
static const int& generate(const void* /*sender*/, const ConnectionData& item)
|
|
{
|
|
return item.id;
|
|
}
|
|
};
|
|
|
|
typedef Firebird::BePlusTree<ConnectionData, int, Firebird::MemoryPool, ConnectionData>
|
|
ConnectionsTree;
|
|
|
|
// Data for tracked (active) transactions
|
|
struct TransactionData
|
|
{
|
|
int id;
|
|
Firebird::string* description;
|
|
|
|
// Deallocate memory used by objects hanging off this structure
|
|
void deallocate_references()
|
|
{
|
|
delete description;
|
|
description = NULL;
|
|
}
|
|
|
|
static const int& generate(const void* /*sender*/, const TransactionData& item)
|
|
{
|
|
return item.id;
|
|
}
|
|
};
|
|
|
|
typedef Firebird::BePlusTree<TransactionData, int, Firebird::MemoryPool, TransactionData>
|
|
TransactionsTree;
|
|
|
|
// Data for tracked (active) statements
|
|
struct StatementData
|
|
{
|
|
unsigned int id;
|
|
Firebird::string* description; // NULL in this field indicates that tracing of this statement is not desired
|
|
|
|
static const unsigned int& generate(const void* /*sender*/, const StatementData& item)
|
|
{
|
|
return item.id;
|
|
}
|
|
};
|
|
|
|
typedef Firebird::BePlusTree<StatementData, unsigned int, Firebird::MemoryPool, StatementData>
|
|
StatementsTree;
|
|
|
|
struct ServiceData
|
|
{
|
|
ntrace_service_t id;
|
|
Firebird::string* description;
|
|
|
|
// Deallocate memory used by objects hanging off this structure
|
|
void deallocate_references()
|
|
{
|
|
delete description;
|
|
description = NULL;
|
|
}
|
|
|
|
static const ntrace_service_t& generate(const void* /*sender*/, const ServiceData& item)
|
|
{
|
|
return item.id;
|
|
}
|
|
};
|
|
|
|
typedef Firebird::BePlusTree<ServiceData, ntrace_service_t, Firebird::MemoryPool, ServiceData>
|
|
ServicesTree;
|
|
|
|
private:
|
|
TracePluginImpl(const TracePluginConfig& configuration, TraceInitInfo* initInfo);
|
|
~TracePluginImpl();
|
|
|
|
bool operational; // Set if plugin is fully initialized and is ready for logging
|
|
// Keep this member field first to ensure its correctness
|
|
// when destructor is called
|
|
const int session_id; // trace session ID, set by Firebird
|
|
Firebird::string session_name; // trace session name, set by Firebird
|
|
TraceLogWriter* logWriter;
|
|
TracePluginConfig config; // Immutable, thus thread-safe
|
|
Firebird::string record;
|
|
|
|
// Data for currently active connections, transactions, statements
|
|
Firebird::RWLock connectionsLock;
|
|
ConnectionsTree connections;
|
|
|
|
Firebird::RWLock transactionsLock;
|
|
TransactionsTree transactions;
|
|
|
|
Firebird::RWLock statementsLock;
|
|
StatementsTree statements;
|
|
|
|
Firebird::RWLock servicesLock;
|
|
ServicesTree services;
|
|
|
|
// Lock for log rotation
|
|
Firebird::RWLock renameLock;
|
|
|
|
charset cs;
|
|
texttype tt;
|
|
Firebird::AutoPtr<Jrd::CharSet> charSet;
|
|
Firebird::AutoPtr<Jrd::TextType> textType;
|
|
|
|
Firebird::AutoPtr<Firebird::SimilarToMatcher<Jrd::UpcaseConverter<Jrd::NullStrConverter>, UCHAR> >
|
|
include_matcher, exclude_matcher;
|
|
|
|
void appendGlobalCounts(const PerformanceInfo* info);
|
|
void appendTableCounts(const PerformanceInfo* info);
|
|
void appendParams(TraceParams* params);
|
|
void appendServiceQueryParams(size_t send_item_length, const ntrace_byte_t* send_items,
|
|
size_t recv_item_length, const ntrace_byte_t* recv_items);
|
|
void formatStringArgument(Firebird::string& result, const UCHAR* str, size_t len);
|
|
|
|
// register various objects
|
|
void register_connection(TraceConnection* connection);
|
|
void register_transaction(TraceTransaction* transaction);
|
|
void register_sql_statement(TraceSQLStatement* statement);
|
|
void register_blr_statement(TraceBLRStatement* statement);
|
|
void register_service(TraceService* service);
|
|
|
|
// 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,
|
|
TraceTransaction* transaction);
|
|
void logRecordProc(const char* action, TraceConnection* connection,
|
|
TraceTransaction* transaction, const char* proc_name);
|
|
void logRecordStmt(const char* action, TraceConnection* connection,
|
|
TraceTransaction* transaction, TraceStatement* statement,
|
|
bool isSQL);
|
|
void logRecordServ(const char* action, TraceService* service);
|
|
|
|
/* 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,
|
|
ntrace_result_t att_result);
|
|
void log_event_detach(
|
|
TraceConnection* connection, ntrace_boolean_t drop_db);
|
|
|
|
void log_event_transaction_start(
|
|
TraceConnection* 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,
|
|
ntrace_boolean_t commit, ntrace_boolean_t retain_context, ntrace_result_t tra_result);
|
|
|
|
void log_event_set_context(
|
|
TraceConnection* connection, TraceTransaction* transaction,
|
|
TraceContextVariable* variable);
|
|
|
|
void log_event_proc_execute(
|
|
TraceConnection* connection, TraceTransaction* transaction, TraceProcedure* procedure,
|
|
bool started, ntrace_result_t proc_result);
|
|
|
|
void log_event_trigger_execute(
|
|
TraceConnection* connection, TraceTransaction* transaction, TraceTrigger* trigger,
|
|
bool started, ntrace_result_t trig_result);
|
|
|
|
void log_event_dsql_prepare(
|
|
TraceConnection* 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);
|
|
void log_event_dsql_execute(
|
|
TraceConnection* connection, TraceTransaction* transaction, TraceSQLStatement* statement,
|
|
bool started, ntrace_result_t req_result);
|
|
|
|
void log_event_blr_compile(
|
|
TraceConnection* connection, TraceTransaction* transaction,
|
|
TraceBLRStatement* statement, ntrace_counter_t time_millis, ntrace_result_t req_result);
|
|
void log_event_blr_execute(
|
|
TraceConnection* connection, TraceTransaction* transaction,
|
|
TraceBLRStatement* statement, ntrace_result_t req_result);
|
|
|
|
void log_event_dyn_execute(
|
|
TraceConnection* 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,
|
|
ntrace_result_t start_result);
|
|
void log_event_service_query(TraceService* 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);
|
|
|
|
/* Finalize plugin. Called when database is closed by the engine */
|
|
static ntrace_boolean_t ntrace_shutdown(const TracePlugin* tpl_plugin);
|
|
|
|
/* Function to return error string for hook failure */
|
|
static const char* ntrace_get_error(const TracePlugin* tpl_plugin);
|
|
|
|
/* Create/close attachment */
|
|
static ntrace_boolean_t ntrace_event_attach(const TracePlugin* tpl_plugin,
|
|
TraceConnection* 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);
|
|
|
|
/* Start/end transaction */
|
|
static ntrace_boolean_t ntrace_event_transaction_start(const TracePlugin* tpl_plugin,
|
|
TraceConnection* 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,
|
|
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,
|
|
TraceContextVariable* variable);
|
|
|
|
/* Stored procedure executing */
|
|
static ntrace_boolean_t ntrace_event_proc_execute(const struct TracePlugin* tpl_plugin,
|
|
TraceConnection* 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,
|
|
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,
|
|
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);
|
|
static ntrace_boolean_t ntrace_event_dsql_execute(const TracePlugin* tpl_plugin,
|
|
TraceConnection* 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,
|
|
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,
|
|
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,
|
|
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);
|
|
static ntrace_boolean_t ntrace_event_service_start(const TracePlugin* tpl_plugin,
|
|
TraceService* 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,
|
|
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);
|
|
};
|
|
|
|
#endif // TRACEPLUGINIMPL_H
|