8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-30 20:03:03 +01:00
firebird-mirror/src/utilities/ntrace/TracePluginImpl.h
2009-05-01 17:21:36 +00:00

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