mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-24 09:23:03 +01:00
Backport improvements
CORE-5475 : Provide ability to filter out info and warnings from trace log, and CORE-4486 : Trace: provide filter to INCLUDE / EXCLUDE errors by their mnemonical names
This commit is contained in:
parent
e222ceaf25
commit
370572b2dd
@ -33,6 +33,7 @@
|
|||||||
#include "PluginLogWriter.h"
|
#include "PluginLogWriter.h"
|
||||||
#include "os/platform.h"
|
#include "os/platform.h"
|
||||||
#include "consts_pub.h"
|
#include "consts_pub.h"
|
||||||
|
#include "codetext.h"
|
||||||
#include "../../common/isc_f_proto.h"
|
#include "../../common/isc_f_proto.h"
|
||||||
#include "../../jrd/RuntimeStatistics.h"
|
#include "../../jrd/RuntimeStatistics.h"
|
||||||
#include "../../common/dsc.h"
|
#include "../../common/dsc.h"
|
||||||
@ -97,7 +98,9 @@ TracePluginImpl::TracePluginImpl(IPluginBase* plugin,
|
|||||||
transactions(getDefaultMemoryPool()),
|
transactions(getDefaultMemoryPool()),
|
||||||
statements(getDefaultMemoryPool()),
|
statements(getDefaultMemoryPool()),
|
||||||
services(getDefaultMemoryPool()),
|
services(getDefaultMemoryPool()),
|
||||||
unicodeCollation(*getDefaultMemoryPool())
|
unicodeCollation(*getDefaultMemoryPool()),
|
||||||
|
include_codes(*getDefaultMemoryPool()),
|
||||||
|
exclude_codes(*getDefaultMemoryPool())
|
||||||
{
|
{
|
||||||
const char* ses_name = initInfo->getTraceSessionName();
|
const char* ses_name = initInfo->getTraceSessionName();
|
||||||
session_name = ses_name && *ses_name ? ses_name : " ";
|
session_name = ses_name && *ses_name ? ses_name : " ";
|
||||||
@ -163,6 +166,13 @@ TracePluginImpl::TracePluginImpl(IPluginBase* plugin,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// parse filters for gds error codes
|
||||||
|
if (!config.include_gds_codes.isEmpty())
|
||||||
|
str2Array(config.include_gds_codes, include_codes);
|
||||||
|
|
||||||
|
if (!config.exclude_gds_codes.isEmpty())
|
||||||
|
str2Array(config.exclude_gds_codes, exclude_codes);
|
||||||
|
|
||||||
operational = true;
|
operational = true;
|
||||||
log_init();
|
log_init();
|
||||||
}
|
}
|
||||||
@ -548,6 +558,105 @@ void TracePluginImpl::formatStringArgument(string& result, const UCHAR* str, siz
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool TracePluginImpl::filterStatus(const ISC_STATUS* status, GdsCodesArray& arr)
|
||||||
|
{
|
||||||
|
FB_SIZE_T pos;
|
||||||
|
while (*status != isc_arg_end)
|
||||||
|
{
|
||||||
|
const ISC_STATUS s = *status;
|
||||||
|
switch (s)
|
||||||
|
{
|
||||||
|
case isc_arg_gds:
|
||||||
|
case isc_arg_warning:
|
||||||
|
if (arr.find(status[1], pos))
|
||||||
|
return true;
|
||||||
|
status += 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case isc_arg_cstring:
|
||||||
|
status += 3;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
status += 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class GdsName2CodeMap
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GdsName2CodeMap(MemoryPool& pool) :
|
||||||
|
m_map(pool)
|
||||||
|
{
|
||||||
|
for (int i = 0; codes[i].code_string; i++)
|
||||||
|
m_map.put(codes[i].code_string, codes[i].code_number);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool find(const char* name, ISC_STATUS& code) const
|
||||||
|
{
|
||||||
|
return m_map.get(name, code);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
class NocaseCmp
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static bool greaterThan(const char* i1, const char* i2)
|
||||||
|
{
|
||||||
|
return fb_utils::stricmp(i1, i2) > 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
GenericMap<Pair<NonPooled<const char*, ISC_STATUS> >, NocaseCmp > m_map;
|
||||||
|
};
|
||||||
|
|
||||||
|
}; // namespace
|
||||||
|
|
||||||
|
static InitInstance<GdsName2CodeMap> gdsNamesMap;
|
||||||
|
|
||||||
|
void TracePluginImpl::str2Array(const Firebird::string& str, GdsCodesArray& arr)
|
||||||
|
{
|
||||||
|
// input: string with comma-delimited list of gds codes values and\or gds codes names
|
||||||
|
// output: sorted array of gds codes values
|
||||||
|
|
||||||
|
const char *sep = " ,";
|
||||||
|
|
||||||
|
FB_SIZE_T p1 = 0, p2 = 0;
|
||||||
|
while (p2 < str.length())
|
||||||
|
{
|
||||||
|
p2 = str.find_first_of(sep, p1);
|
||||||
|
if (p2 == string::npos)
|
||||||
|
p2 = str.length();
|
||||||
|
|
||||||
|
string s = str.substr(p1, p2 - p1);
|
||||||
|
|
||||||
|
ISC_STATUS code = atol(s.c_str());
|
||||||
|
|
||||||
|
if (!code && !gdsNamesMap().find(s.c_str(), code))
|
||||||
|
fatal_exception::raiseFmt(
|
||||||
|
"Error parsing error codes filter: \n"
|
||||||
|
"\t%s\n"
|
||||||
|
"\tbad item is: %s, at position: %d",
|
||||||
|
str.c_str(), s.c_str(), p1 + 1);
|
||||||
|
|
||||||
|
// avoid duplicates
|
||||||
|
|
||||||
|
FB_SIZE_T ins_pos;
|
||||||
|
if (!arr.find(code, ins_pos))
|
||||||
|
arr.insert(ins_pos, code);
|
||||||
|
|
||||||
|
p1 = str.find_first_not_of(sep, p2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void TracePluginImpl::appendParams(ITraceParams* params)
|
void TracePluginImpl::appendParams(ITraceParams* params)
|
||||||
{
|
{
|
||||||
const FB_SIZE_T paramcount = params->getCount();
|
const FB_SIZE_T paramcount = params->getCount();
|
||||||
@ -931,14 +1040,20 @@ void TracePluginImpl::appendServiceQueryParams(size_t send_item_length,
|
|||||||
|
|
||||||
void TracePluginImpl::log_init()
|
void TracePluginImpl::log_init()
|
||||||
{
|
{
|
||||||
|
if (config.log_initfini)
|
||||||
|
{
|
||||||
record.printf("\tSESSION_%d %s" NEWLINE "\t%s" NEWLINE, session_id, session_name.c_str(), config.db_filename.c_str());
|
record.printf("\tSESSION_%d %s" NEWLINE "\t%s" NEWLINE, session_id, session_name.c_str(), config.db_filename.c_str());
|
||||||
logRecord("TRACE_INIT");
|
logRecord("TRACE_INIT");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TracePluginImpl::log_finalize()
|
void TracePluginImpl::log_finalize()
|
||||||
{
|
{
|
||||||
|
if (config.log_initfini)
|
||||||
|
{
|
||||||
record.printf("\tSESSION_%d %s" NEWLINE "\t%s" NEWLINE, session_id, session_name.c_str(), config.db_filename.c_str());
|
record.printf("\tSESSION_%d %s" NEWLINE "\t%s" NEWLINE, session_id, session_name.c_str(), config.db_filename.c_str());
|
||||||
logRecord("TRACE_FINI");
|
logRecord("TRACE_FINI");
|
||||||
|
}
|
||||||
|
|
||||||
logWriter->release();
|
logWriter->release();
|
||||||
logWriter = NULL;
|
logWriter = NULL;
|
||||||
@ -2037,14 +2152,31 @@ void TracePluginImpl::log_event_trigger_execute(ITraceDatabaseConnection* connec
|
|||||||
void TracePluginImpl::log_event_error(ITraceConnection* connection, ITraceStatusVector* status,
|
void TracePluginImpl::log_event_error(ITraceConnection* connection, ITraceStatusVector* status,
|
||||||
const char* function)
|
const char* function)
|
||||||
{
|
{
|
||||||
if (!config.log_errors)
|
string event_type;
|
||||||
|
if (config.log_errors && status->hasError())
|
||||||
|
{
|
||||||
|
const ISC_STATUS* errs = status->getStatus()->getErrors();
|
||||||
|
|
||||||
|
if (!include_codes.isEmpty() && !filterStatus(errs, include_codes))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!exclude_codes.isEmpty() && filterStatus(errs, exclude_codes))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
string event_type;
|
|
||||||
if (status->hasError())
|
|
||||||
event_type.printf("ERROR AT %s", function);
|
event_type.printf("ERROR AT %s", function);
|
||||||
else if (status->hasWarning())
|
}
|
||||||
|
else if (config.log_warnings && status->hasWarning())
|
||||||
|
{
|
||||||
|
const ISC_STATUS* warns = status->getStatus()->getWarnings();
|
||||||
|
|
||||||
|
if (!include_codes.isEmpty() && !filterStatus(warns, include_codes))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!exclude_codes.isEmpty() && filterStatus(warns, exclude_codes))
|
||||||
|
return;
|
||||||
|
|
||||||
event_type.printf("WARNING AT %s", function);
|
event_type.printf("WARNING AT %s", function);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -173,12 +173,19 @@ private:
|
|||||||
TraceSimilarToMatcher;
|
TraceSimilarToMatcher;
|
||||||
Firebird::AutoPtr<TraceSimilarToMatcher> include_matcher, exclude_matcher;
|
Firebird::AutoPtr<TraceSimilarToMatcher> include_matcher, exclude_matcher;
|
||||||
|
|
||||||
|
// Filters for gds error codes
|
||||||
|
typedef Firebird::SortedArray<ISC_STATUS> GdsCodesArray;
|
||||||
|
GdsCodesArray include_codes;
|
||||||
|
GdsCodesArray exclude_codes;
|
||||||
|
|
||||||
void appendGlobalCounts(const PerformanceInfo* info);
|
void appendGlobalCounts(const PerformanceInfo* info);
|
||||||
void appendTableCounts(const PerformanceInfo* info);
|
void appendTableCounts(const PerformanceInfo* info);
|
||||||
void appendParams(Firebird::ITraceParams* params);
|
void appendParams(Firebird::ITraceParams* params);
|
||||||
void appendServiceQueryParams(size_t send_item_length, const ntrace_byte_t* send_items,
|
void appendServiceQueryParams(size_t send_item_length, const ntrace_byte_t* send_items,
|
||||||
size_t recv_item_length, const ntrace_byte_t* recv_items);
|
size_t recv_item_length, const ntrace_byte_t* recv_items);
|
||||||
void formatStringArgument(Firebird::string& result, const UCHAR* str, size_t len);
|
void formatStringArgument(Firebird::string& result, const UCHAR* str, size_t len);
|
||||||
|
bool filterStatus(const ISC_STATUS* status, GdsCodesArray& arr);
|
||||||
|
void str2Array(const Firebird::string& str, GdsCodesArray& arr);
|
||||||
|
|
||||||
// register various objects
|
// register various objects
|
||||||
void register_connection(Firebird::ITraceDatabaseConnection* connection);
|
void register_connection(Firebird::ITraceDatabaseConnection* connection);
|
||||||
|
@ -95,6 +95,24 @@ database
|
|||||||
# Put errors happened
|
# Put errors happened
|
||||||
#log_errors = false
|
#log_errors = false
|
||||||
|
|
||||||
|
# Put warnings
|
||||||
|
#log_warnings = false
|
||||||
|
|
||||||
|
# Filters for errors and warnings GDS codes.
|
||||||
|
# Comma separated list of GDS codes values and\or names.
|
||||||
|
# For example: deadlock, req_sync, 335544321
|
||||||
|
|
||||||
|
# Include filter. If empty, trace all errors\warnings events.
|
||||||
|
# Else trace event if any code from list is found in status-vector.
|
||||||
|
#include_gds_codes
|
||||||
|
|
||||||
|
# Exclude filter. If empty, trace all errors\warnings events.
|
||||||
|
# Else trace event if no code from list is found in status-vector.
|
||||||
|
#exclude_gds_codes
|
||||||
|
|
||||||
|
# Put trace session init and finish messages
|
||||||
|
#log_initfini = true
|
||||||
|
|
||||||
# Sweep activity
|
# Sweep activity
|
||||||
#log_sweep = false
|
#log_sweep = false
|
||||||
|
|
||||||
@ -199,6 +217,24 @@ services
|
|||||||
|
|
||||||
# Put errors happened
|
# Put errors happened
|
||||||
#log_errors = false
|
#log_errors = false
|
||||||
|
|
||||||
|
# Put warnings
|
||||||
|
#log_warnings = false
|
||||||
|
|
||||||
|
# Filters for errors and warnings GDS codes.
|
||||||
|
# Comma separated list of GDS codes values and\or names.
|
||||||
|
# For example: deadlock, req_sync, 335544321
|
||||||
|
|
||||||
|
# Include filter. If empty, trace all errors\warnings events.
|
||||||
|
# Else trace event if any code from list is found in status-vector.
|
||||||
|
#include_gds_codes
|
||||||
|
|
||||||
|
# Exclude filter. If empty, trace all errors\warnings events.
|
||||||
|
# Else trace event if no code from list is found in status-vector.
|
||||||
|
#exclude_gds_codes
|
||||||
|
|
||||||
|
# Put trace session init and finish messages
|
||||||
|
#log_initfini = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -36,6 +36,10 @@ STR_PARAMETER(include_filter, "")
|
|||||||
STR_PARAMETER(exclude_filter, "")
|
STR_PARAMETER(exclude_filter, "")
|
||||||
PATH_PARAMETER(log_filename, "")
|
PATH_PARAMETER(log_filename, "")
|
||||||
BOOL_PARAMETER(log_errors, false)
|
BOOL_PARAMETER(log_errors, false)
|
||||||
|
BOOL_PARAMETER(log_warnings, false)
|
||||||
|
STR_PARAMETER(include_gds_codes, "")
|
||||||
|
STR_PARAMETER(exclude_gds_codes, "")
|
||||||
|
BOOL_PARAMETER(log_initfini, true)
|
||||||
BOOL_PARAMETER(enabled, false)
|
BOOL_PARAMETER(enabled, false)
|
||||||
UINT_PARAMETER(max_log_size, 0)
|
UINT_PARAMETER(max_log_size, 0)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user