[syslog-ng] [PATCH (3.4)] afsql: Add support for specifying custom SQL backend options.

Gergely Nagy algernon at balabit.hu
Wed Dec 7 12:11:12 CET 2011


When one is using an SQL backend that supports a set of options that
syslog-ng does not set itself, yet, one does want these options set,
there was previously no way to accomplish that without changing the
source.

This patch adds a new option: dbd-option(OPTION_NAME VALUE) (where
OPTION_NAME is always a string, and value can be either a string, or a
number). The options specified this way will always be set with libdbi
whenever we (re)connect to the database.

A simple use-case:

destination d_slow_sql_test {
  sql(type("null")
      dbd-option("null.sleep.connect" 1)
      dbd-option("null.sleep.query" 5)
      columns("dummy")
      values("1")
  );
};

Signed-off-by: Gergely Nagy <algernon at balabit.hu>
---
 modules/afsql/afsql-grammar.ym |    3 +++
 modules/afsql/afsql-parser.c   |    2 ++
 modules/afsql/afsql.c          |   40 ++++++++++++++++++++++++++++++++++++++++
 modules/afsql/afsql.h          |    4 ++++
 4 files changed, 49 insertions(+), 0 deletions(-)

diff --git a/modules/afsql/afsql-grammar.ym b/modules/afsql/afsql-grammar.ym
index 580fb80..d21a3bf 100644
--- a/modules/afsql/afsql-grammar.ym
+++ b/modules/afsql/afsql-grammar.ym
@@ -54,6 +54,7 @@ extern LogDriver *last_driver;
 
 %token KW_DEFAULT
 %token KW_RETRIES
+%token KW_DBD_OPTION
 
 %type   <ptr> dest_afsql
 %type   <ptr> dest_afsql_params
@@ -100,6 +101,8 @@ dest_afsql_option
             free($3);
           }
         | KW_USERNAME '(' string ')'		{ afsql_dd_set_user(last_driver, $3); free($3); }
+        | KW_DBD_OPTION '(' string LL_NUMBER ')' { afsql_dd_add_dbd_option_numeric(last_driver, $3, $4); free($3); }
+        | KW_DBD_OPTION '(' string string ')'    { afsql_dd_add_dbd_option(last_driver, $3, $4); free($3); free($4); }
         | KW_PASSWORD '(' string ')'		{ afsql_dd_set_password(last_driver, $3); free($3); }
         | KW_DATABASE '(' string ')'		{ afsql_dd_set_database(last_driver, $3); free($3); }
         | KW_TABLE '(' string ')'		{ afsql_dd_set_table(last_driver, $3); free($3); }
diff --git a/modules/afsql/afsql-parser.c b/modules/afsql/afsql-parser.c
index 877389a..291e495 100644
--- a/modules/afsql/afsql-parser.c
+++ b/modules/afsql/afsql-parser.c
@@ -55,6 +55,8 @@ static CfgLexerKeyword afsql_keywords[] = {
   { "flush_lines",        KW_FLUSH_LINES },
   { "flush_timeout",      KW_FLUSH_TIMEOUT },
   { "flags",              KW_FLAGS },
+
+  { "dbd_option",         KW_DBD_OPTION },
   { NULL }
 };
 
diff --git a/modules/afsql/afsql.c b/modules/afsql/afsql.c
index b3fec86..a327cdd 100644
--- a/modules/afsql/afsql.c
+++ b/modules/afsql/afsql.c
@@ -103,6 +103,9 @@ typedef struct _AFSqlDestDriver
   StatsCounterItem *dropped_messages;
   StatsCounterItem *stored_messages;
 
+  GHashTable *dbd_options;
+  GHashTable *dbd_options_numeric;
+
   /* shared by the main/db thread */
   GThread *db_thread;
   GMutex *db_thread_mutex;
@@ -127,6 +130,22 @@ static const char *s_freetds = "freetds";
 #define MAX_FAILED_ATTEMPTS 3
 
 void
+afsql_dd_add_dbd_option(LogDriver *s, const gchar *name, const gchar *value)
+{
+  AFSqlDestDriver *self = (AFSqlDestDriver *) s;
+
+  g_hash_table_insert(self->dbd_options, g_strdup(name), g_strdup(value));
+}
+
+void
+afsql_dd_add_dbd_option_numeric(LogDriver *s, const gchar *name, gint value)
+{
+  AFSqlDestDriver *self = (AFSqlDestDriver *) s;
+
+  g_hash_table_insert(self->dbd_options_numeric, g_strdup(name), GINT_TO_POINTER(value));
+}
+
+void
 afsql_dd_set_type(LogDriver *s, const gchar *type)
 {
   AFSqlDestDriver *self = (AFSqlDestDriver *) s;
@@ -608,6 +627,19 @@ afsql_dd_disconnect(AFSqlDestDriver *self)
   g_hash_table_remove_all(self->validated_tables);
 }
 
+static void
+afsql_dd_set_dbd_opt(gpointer key, gpointer value, gpointer user_data)
+{
+  dbi_conn_set_option((dbi_conn)user_data, (gchar *)key, (gchar *)value);
+}
+
+static void
+afsql_dd_set_dbd_opt_numeric(gpointer key, gpointer value, gpointer user_data)
+{
+  dbi_conn_set_option_numeric((dbi_conn)user_data, (gchar *)key,
+                              GPOINTER_TO_INT(value));
+}
+
 /**
  * afsql_dd_insert_db:
  *
@@ -645,6 +677,10 @@ afsql_dd_insert_db(AFSqlDestDriver *self)
           dbi_conn_set_option(self->dbi_ctx, "sqlite_dbdir", "");
           dbi_conn_set_option(self->dbi_ctx, "sqlite3_dbdir", "");
 
+          /* Set user-specified options */
+          g_hash_table_foreach(self->dbd_options, afsql_dd_set_dbd_opt, self->dbi_ctx);
+          g_hash_table_foreach(self->dbd_options_numeric, afsql_dd_set_dbd_opt_numeric, self->dbi_ctx);
+
           if (dbi_conn_connect(self->dbi_ctx) < 0)
             {
               const gchar *dbi_error;
@@ -1200,6 +1236,8 @@ afsql_dd_free(LogPipe *s)
   string_list_free(self->values);
   log_template_unref(self->table);
   g_hash_table_destroy(self->validated_tables);
+  g_hash_table_destroy(self->dbd_options);
+  g_hash_table_destroy(self->dbd_options_numeric);
   if(self->session_statements)
     string_list_free(self->session_statements);
   log_dest_driver_free(s);
@@ -1235,6 +1273,8 @@ afsql_dd_new(void)
   self->num_retries = MAX_FAILED_ATTEMPTS;
 
   self->validated_tables = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
+  self->dbd_options = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
+  self->dbd_options_numeric = g_hash_table_new_full(g_str_hash, g_int_equal, g_free, NULL);
 
   log_template_options_defaults(&self->template_options);
   init_sequence_number(&self->seq_num);
diff --git a/modules/afsql/afsql.h b/modules/afsql/afsql.h
index ee2ae68..ce2e18a 100644
--- a/modules/afsql/afsql.h
+++ b/modules/afsql/afsql.h
@@ -56,6 +56,8 @@ void afsql_dd_set_flags(LogDriver *s, gint flags);
 LogDriver *afsql_dd_new();
 gint afsql_dd_lookup_flag(const gchar *flag);
 void afsql_dd_set_retries(LogDriver *s, gint num_retries);
+void afsql_dd_add_dbd_option(LogDriver *s, const gchar *name, const gchar *value);
+void afsql_dd_add_dbd_option_numeric(LogDriver *s, const gchar *name, gint value);
 
 #else
 
@@ -69,6 +71,8 @@ void afsql_dd_set_retries(LogDriver *s, gint num_retries);
 #define afsql_dd_set_columns(s, c)
 #define afsql_dd_set_values(s, v)
 #define afsql_dd_set_null_value(s, v)
+#define afsql_dd_add_dbd_option(s, n, v)
+#define afsql_dd_add_dbd_option_numeric(s, n, v)
 
 #define afsql_dd_new() 0
 
-- 
1.7.7.3




More information about the syslog-ng mailing list