MXS-2050 Move filter settings to a container

This commit is contained in:
Esa Korhonen
2019-02-07 12:18:15 +02:00
parent c09128111c
commit 19ab89144b
2 changed files with 85 additions and 79 deletions

View File

@ -29,6 +29,7 @@
#include <fcntl.h> #include <fcntl.h>
#include <time.h> #include <time.h>
#include <stdio.h> #include <stdio.h>
#include <inttypes.h>
#include <string.h> #include <string.h>
#include <sstream> #include <sstream>
#include <sys/time.h> #include <sys/time.h>
@ -38,6 +39,7 @@
#include <maxscale/alloc.h> #include <maxscale/alloc.h>
#include <maxbase/atomic.h> #include <maxbase/atomic.h>
#include <maxbase/format.hh>
#include <maxscale/modinfo.h> #include <maxscale/modinfo.h>
#include <maxscale/modutil.hh> #include <maxscale/modutil.hh>
#include <maxscale/service.hh> #include <maxscale/service.hh>
@ -112,22 +114,22 @@ static const MXS_ENUM_VALUE log_data_values[] =
QlaInstance::QlaInstance(const string& name, MXS_CONFIG_PARAMETER* params) QlaInstance::QlaInstance(const string& name, MXS_CONFIG_PARAMETER* params)
: m_name(name) : m_name(name)
, m_log_mode_flags(params->get_enum(PARAM_LOG_TYPE, log_type_values)) , m_settings(params)
, m_log_file_data_flags(params->get_enum(PARAM_LOG_DATA, log_data_values)) {
, m_filebase(params->get_string(PARAM_FILEBASE)) }
, m_unified_fp(NULL)
, m_flush_writes(params->get_bool(PARAM_FLUSH)) QlaInstance::Settings::Settings(MXS_CONFIG_PARAMETER* params)
, m_append(params->get_bool(PARAM_APPEND)) : log_mode_flags(params->get_enum(PARAM_LOG_TYPE, log_type_values))
, m_query_newline(params->get_string(PARAM_NEWLINE)) , log_file_data_flags(params->get_enum(PARAM_LOG_DATA, log_data_values))
, m_separator(params->get_string(PARAM_SEPARATOR)) , filebase(params->get_string(PARAM_FILEBASE))
, m_write_warning_given(false) , flush_writes(params->get_bool(PARAM_FLUSH))
, m_user_name(params->get_string(PARAM_USER)) , append(params->get_bool(PARAM_APPEND))
, m_source(params->get_string(PARAM_SOURCE)) , query_newline(params->get_string(PARAM_NEWLINE))
, m_match(params->get_string(PARAM_MATCH)) , separator(params->get_string(PARAM_SEPARATOR))
, m_exclude(params->get_string(PARAM_EXCLUDE)) , user_name(params->get_string(PARAM_USER))
, m_re_match(NULL) , source(params->get_string(PARAM_SOURCE))
, m_re_exclude(NULL) , match(params->get_string(PARAM_MATCH))
, m_ovec_size(0) , exclude(params->get_string(PARAM_EXCLUDE))
{ {
} }
@ -201,11 +203,11 @@ QlaInstance* QlaInstance::create(const std::string name, MXS_CONFIG_PARAMETER* p
my_instance->m_re_exclude = re_exclude; my_instance->m_re_exclude = re_exclude;
my_instance->m_ovec_size = ovec_size; my_instance->m_ovec_size = ovec_size;
// Try to open the unified log file // Try to open the unified log file
if (my_instance->m_log_mode_flags & CONFIG_FILE_UNIFIED) if (my_instance->m_settings.log_mode_flags & CONFIG_FILE_UNIFIED)
{ {
string unified_filename = my_instance->m_filebase + ".unified"; string unified_filename = my_instance->m_settings.filebase + ".unified";
// Open the file. It is only closed at program exit. // Open the file. It is only closed at program exit.
FILE* unified_fp = my_instance->open_log_file(my_instance->m_log_file_data_flags, FILE* unified_fp = my_instance->open_log_file(my_instance->m_settings.log_file_data_flags,
unified_filename.c_str()); unified_filename.c_str());
if (unified_fp != NULL) if (unified_fp != NULL)
{ {
@ -254,8 +256,8 @@ QlaFilterSession* QlaInstance::newSession(MXS_SESSION* session)
bool error = false; bool error = false;
mxb_assert(userName && remote); mxb_assert(userName && remote);
if ((!m_source.empty() && remote && m_source != remote) if ((!m_settings.source.empty() && remote && m_settings.source != remote)
|| (!m_user_name.empty() && userName && m_user_name != userName)) || (!m_settings.user_name.empty() && userName && m_settings.user_name != userName))
{ {
ses_active = false; ses_active = false;
} }
@ -272,14 +274,12 @@ QlaFilterSession* QlaInstance::newSession(MXS_SESSION* session)
} }
// Only open the session file if the corresponding mode setting is used // Only open the session file if the corresponding mode setting is used
if (!error && ses_active && m_log_mode_flags & CONFIG_FILE_SESSION) if (!error && ses_active && m_settings.log_mode_flags & CONFIG_FILE_SESSION)
{ {
std::stringstream filename_helper; filename = mxb::string_printf("%s.%" PRIu64, m_settings.filebase.c_str(), session->ses_id);
filename_helper << m_filebase << "." << session->ses_id;
filename = filename_helper.str();
// Session numbers are not printed to session files // Session numbers are not printed to session files
uint32_t data_flags = (m_log_file_data_flags & ~LOG_DATA_SESSION); uint32_t data_flags = (m_settings.log_file_data_flags & ~LOG_DATA_SESSION);
session_file = open_log_file(data_flags, filename.c_str()); session_file = open_log_file(data_flags, filename.c_str());
if (session_file == NULL) if (session_file == NULL)
@ -329,11 +329,11 @@ void QlaFilterSession::write_log_entries(const char* date_string, const char* qu
int elapsed_ms) int elapsed_ms)
{ {
bool write_error = false; bool write_error = false;
if (m_instance.m_log_mode_flags & CONFIG_FILE_SESSION) if (m_instance.m_settings.log_mode_flags & CONFIG_FILE_SESSION)
{ {
// In this case there is no need to write the session // In this case there is no need to write the session
// number into the files. // number into the files.
uint32_t data_flags = (m_instance.m_log_file_data_flags & ~LOG_DATA_SESSION); uint32_t data_flags = (m_instance.m_settings.log_file_data_flags & ~LOG_DATA_SESSION);
if (write_log_entry(m_logfile, if (write_log_entry(m_logfile,
data_flags, data_flags,
date_string, date_string,
@ -344,9 +344,9 @@ void QlaFilterSession::write_log_entries(const char* date_string, const char* qu
write_error = true; write_error = true;
} }
} }
if (m_instance.m_log_mode_flags & CONFIG_FILE_UNIFIED) if (m_instance.m_settings.log_mode_flags & CONFIG_FILE_UNIFIED)
{ {
uint32_t data_flags = m_instance.m_log_file_data_flags; uint32_t data_flags = m_instance.m_settings.log_file_data_flags;
if (write_log_entry(m_instance.m_unified_fp, if (write_log_entry(m_instance.m_unified_fp,
data_flags, data_flags,
date_string, date_string,
@ -376,7 +376,7 @@ int QlaFilterSession::routeQuery(GWBUF* queue)
query, query_len, query, query_len,
MXS_MODULE_NAME)) MXS_MODULE_NAME))
{ {
const uint32_t data_flags = m_instance.m_log_file_data_flags; const uint32_t data_flags = m_instance.m_settings.log_file_data_flags;
LogEventData& event = m_event_data; LogEventData& event = m_event_data;
if (data_flags & LOG_DATA_DATE) if (data_flags & LOG_DATA_DATE)
{ {
@ -419,7 +419,7 @@ int QlaFilterSession::clientReply(GWBUF* queue)
LogEventData& event = m_event_data; LogEventData& event = m_event_data;
if (event.has_message) if (event.has_message)
{ {
const uint32_t data_flags = m_instance.m_log_file_data_flags; const uint32_t data_flags = m_instance.m_settings.log_file_data_flags;
mxb_assert(data_flags & LOG_DATA_REPLY_TIME); mxb_assert(data_flags & LOG_DATA_REPLY_TIME);
char* query = NULL; char* query = NULL;
@ -463,36 +463,36 @@ static void diagnostic(MXS_FILTER* instance, MXS_FILTER_SESSION* fsession, DCB*
"\t\tLogging to file %s.\n", "\t\tLogging to file %s.\n",
my_session->m_filename.c_str()); my_session->m_filename.c_str());
} }
if (!my_instance->m_source.empty()) if (!my_instance->m_settings.source.empty())
{ {
dcb_printf(dcb, dcb_printf(dcb,
"\t\tLimit logging to connections from %s\n", "\t\tLimit logging to connections from %s\n",
my_instance->m_source.c_str()); my_instance->m_settings.source.c_str());
} }
if (!my_instance->m_user_name.empty()) if (!my_instance->m_settings.user_name.empty())
{ {
dcb_printf(dcb, dcb_printf(dcb,
"\t\tLimit logging to user %s\n", "\t\tLimit logging to user %s\n",
my_instance->m_user_name.c_str()); my_instance->m_settings.user_name.c_str());
} }
if (!my_instance->m_match.empty()) if (!my_instance->m_settings.match.empty())
{ {
dcb_printf(dcb, dcb_printf(dcb,
"\t\tInclude queries that match %s\n", "\t\tInclude queries that match %s\n",
my_instance->m_match.c_str()); my_instance->m_settings.match.c_str());
} }
if (!my_instance->m_exclude.empty()) if (!my_instance->m_settings.exclude.empty())
{ {
dcb_printf(dcb, dcb_printf(dcb,
"\t\tExclude queries that match %s\n", "\t\tExclude queries that match %s\n",
my_instance->m_exclude.c_str()); my_instance->m_settings.exclude.c_str());
} }
dcb_printf(dcb, dcb_printf(dcb,
"\t\tColumn separator %s\n", "\t\tColumn separator %s\n",
my_instance->m_separator.c_str()); my_instance->m_settings.separator.c_str());
dcb_printf(dcb, dcb_printf(dcb,
"\t\tNewline replacement %s\n", "\t\tNewline replacement %s\n",
my_instance->m_query_newline.c_str()); my_instance->m_settings.query_newline.c_str());
} }
/** /**
@ -517,27 +517,27 @@ static json_t* diagnostic_json(const MXS_FILTER* instance, const MXS_FILTER_SESS
json_object_set_new(rval, "session_filename", json_string(my_session->m_filename.c_str())); json_object_set_new(rval, "session_filename", json_string(my_session->m_filename.c_str()));
} }
if (!my_instance->m_source.empty()) if (!my_instance->m_settings.source.empty())
{ {
json_object_set_new(rval, PARAM_SOURCE, json_string(my_instance->m_source.c_str())); json_object_set_new(rval, PARAM_SOURCE, json_string(my_instance->m_settings.source.c_str()));
} }
if (!my_instance->m_user_name.empty()) if (!my_instance->m_settings.user_name.empty())
{ {
json_object_set_new(rval, PARAM_USER, json_string(my_instance->m_user_name.c_str())); json_object_set_new(rval, PARAM_USER, json_string(my_instance->m_settings.user_name.c_str()));
} }
if (!my_instance->m_match.empty()) if (!my_instance->m_settings.match.empty())
{ {
json_object_set_new(rval, PARAM_MATCH, json_string(my_instance->m_match.c_str())); json_object_set_new(rval, PARAM_MATCH, json_string(my_instance->m_settings.match.c_str()));
} }
if (!my_instance->m_exclude.empty()) if (!my_instance->m_settings.exclude.empty())
{ {
json_object_set_new(rval, PARAM_EXCLUDE, json_string(my_instance->m_exclude.c_str())); json_object_set_new(rval, PARAM_EXCLUDE, json_string(my_instance->m_settings.exclude.c_str()));
} }
json_object_set_new(rval, PARAM_SEPARATOR, json_string(my_instance->m_separator.c_str())); json_object_set_new(rval, PARAM_SEPARATOR, json_string(my_instance->m_settings.separator.c_str()));
json_object_set_new(rval, PARAM_NEWLINE, json_string(my_instance->m_query_newline.c_str())); json_object_set_new(rval, PARAM_NEWLINE, json_string(my_instance->m_settings.query_newline.c_str()));
return rval; return rval;
} }
@ -545,17 +545,15 @@ static json_t* diagnostic_json(const MXS_FILTER* instance, const MXS_FILTER_SESS
/** /**
* Open the log file and print a header if appropriate. * Open the log file and print a header if appropriate.
* *
* @param instance The filter instance
* @param data_flags Data save settings flags * @param data_flags Data save settings flags
* @param filename Target file path * @param filename Target file path
* @return A valid file on success, null otherwise. * @return A valid file on success, null otherwise.
*/ */
FILE* QlaInstance::open_log_file(uint32_t data_flags, const char* filename) FILE* QlaInstance::open_log_file(uint32_t data_flags, const char* filename)
{ {
auto instance = this;
bool file_existed = false; bool file_existed = false;
FILE* fp = NULL; FILE* fp = NULL;
if (instance->m_append == false) if (m_settings.append == false)
{ {
// Just open the file (possibly overwriting) and then print header. // Just open the file (possibly overwriting) and then print header.
fp = fopen(filename, "w"); fp = fopen(filename, "w");
@ -591,7 +589,7 @@ FILE* QlaInstance::open_log_file(uint32_t data_flags, const char* filename)
std::stringstream header; std::stringstream header;
string curr_sep; // Use empty string as the first separator string curr_sep; // Use empty string as the first separator
const string& real_sep = instance->m_separator; const string& real_sep = m_settings.separator;
if (data_flags & LOG_DATA_SERVICE) if (data_flags & LOG_DATA_SERVICE)
{ {
@ -627,7 +625,7 @@ FILE* QlaInstance::open_log_file(uint32_t data_flags, const char* filename)
// Finally, write the log header. // Finally, write the log header.
int written = fprintf(fp, "%s", header.str().c_str()); int written = fprintf(fp, "%s", header.str().c_str());
if ((written <= 0) || ((instance->m_flush_writes) && (fflush(fp) < 0))) if ((written <= 0) || ((m_settings.flush_writes) && (fflush(fp) < 0)))
{ {
// Weird error, file opened but a write failed. Best to stop. // Weird error, file opened but a write failed. Best to stop.
fclose(fp); fclose(fp);
@ -715,7 +713,7 @@ int QlaFilterSession::write_log_entry(FILE* logfile, uint32_t data_flags, const
* simultaneously, so we have to first print to a string. */ * simultaneously, so we have to first print to a string. */
std::stringstream output; std::stringstream output;
string curr_sep; // Use empty string as the first separator string curr_sep; // Use empty string as the first separator
const string& real_sep = m_instance.m_separator; const string& real_sep = m_instance.m_settings.separator;
if (data_flags & LOG_DATA_SERVICE) if (data_flags & LOG_DATA_SERVICE)
{ {
@ -745,10 +743,10 @@ int QlaFilterSession::write_log_entry(FILE* logfile, uint32_t data_flags, const
if (data_flags & LOG_DATA_QUERY) if (data_flags & LOG_DATA_QUERY)
{ {
output << curr_sep; output << curr_sep;
if (!m_instance.m_query_newline.empty()) if (!m_instance.m_settings.query_newline.empty())
{ {
print_string_replace_newlines(sql_string, sql_str_len, print_string_replace_newlines(sql_string, sql_str_len,
m_instance.m_query_newline.c_str(), m_instance.m_settings.query_newline.c_str(),
&output); &output);
} }
else else
@ -762,7 +760,7 @@ int QlaFilterSession::write_log_entry(FILE* logfile, uint32_t data_flags, const
// Finally, write the log event. // Finally, write the log event.
int written = fprintf(logfile, "%s", output.str().c_str()); int written = fprintf(logfile, "%s", output.str().c_str());
if ((!m_instance.m_flush_writes) || (written <= 0)) if ((!m_instance.m_settings.flush_writes) || (written <= 0))
{ {
return written; return written;
} }
@ -787,7 +785,7 @@ static bool cb_log(const MODULECMD_ARG* argv, json_t** output)
QlaInstance* instance = reinterpret_cast<QlaInstance*>(filter_def_get_instance(filter)); QlaInstance* instance = reinterpret_cast<QlaInstance*>(filter_def_get_instance(filter));
bool rval = false; bool rval = false;
if (instance->m_log_mode_flags & CONFIG_FILE_UNIFIED) if (instance->m_settings.log_mode_flags & CONFIG_FILE_UNIFIED)
{ {
mxb_assert(instance->m_unified_fp && !instance->m_unified_filename.empty()); mxb_assert(instance->m_unified_fp && !instance->m_unified_filename.empty());
std::ifstream file(instance->m_unified_filename); std::ifstream file(instance->m_unified_filename);

View File

@ -94,27 +94,35 @@ public:
const std::string m_name; /* Filter definition name */ const std::string m_name; /* Filter definition name */
uint32_t m_log_mode_flags; /* Log file mode settings */
uint32_t m_log_file_data_flags; /* What data is saved to the files */
std::string m_filebase; /* The filename base */
std::string m_unified_filename; /* Filename of the unified log file */ std::string m_unified_filename; /* Filename of the unified log file */
FILE* m_unified_fp {nullptr}; /* Unified log file. The pointer needs to be shared here
* to avoid garbled printing. */
FILE* m_unified_fp; /* Unified log file. The pointer needs to be shared here pcre2_code* m_re_match {nullptr}; /* Compiled regex text */
* to avoid garbled printing. */ pcre2_code* m_re_exclude {nullptr}; /* Compiled regex nomatch text */
bool m_flush_writes; /* Flush log file after every write? */ uint32_t m_ovec_size {0}; /* PCRE2 match data ovector size */
bool m_append; /* Open files in append-mode? */
std::string m_query_newline; /* Character(s) used to replace a newline within a query */
std::string m_separator; /* Character(s) used to separate elements */
bool m_write_warning_given;/* Avoid repeatedly printing some errors/warnings. */
std::string m_user_name; /* The user name to filter on */ bool m_write_warning_given {false}; /* Avoid repeatedly printing some errors/warnings. */
std::string m_source; /* The source of the client connection to filter on */
std::string m_match; /* Optional text to match against */ class Settings
std::string m_exclude; /* Optional text to match against for exclusion */ {
pcre2_code* m_re_match; /* Compiled regex text */ public:
pcre2_code* m_re_exclude; /* Compiled regex nomatch text */ Settings(MXS_CONFIG_PARAMETER* params);
uint32_t m_ovec_size; /* PCRE2 match data ovector size */
uint32_t log_mode_flags {0}; /* Log file mode settings */
uint32_t log_file_data_flags {0}; /* What data is saved to the files */
std::string filebase; /* The filename base */
bool flush_writes {false}; /* Flush log file after every write? */
bool append {false}; /* Open files in append-mode? */
std::string query_newline; /* Character(s) used to replace a newline within a query */
std::string separator; /* Character(s) used to separate elements */
std::string user_name; /* The user name to filter on */
std::string source; /* The source of the client connection to filter on */
std::string match; /* Optional text to match against */
std::string exclude; /* Optional text to match against for exclusion */
};
Settings m_settings;
private: private:
FILE* open_log_file(uint32_t, const char*); FILE* open_log_file(uint32_t, const char*);