[syslog-ng] [PATCH (3.4)] afmongodb: Support connecting to unix sockets

Gergely Nagy algernon at balabit.hu
Fri Aug 17 10:27:44 CEST 2012


The next version of libmongo-client (0.1.6) will support connecting
via unix sockets, and the mongodb destination driver should follow. To
achieve this, the internal copy was updated to a version that already
supports this, and the minimum required version was also bumped to
0.1.6.

With that in place, the path() option is introduced, which, when set,
will tell the driver to connect via the specified path to a unix
socket. It does this by setting port to MONGO_CONN_LOCAL, that's how a
path is recognised by libmongo-client.

However, setting path() conflicts with host(), port() and servers():
the first cannot be used when any of the other three was previously
set, nor the other way around. The configuration grammar was updated
to notice this case, and bail out with an error if such a scenario is
detected.

Based on the work of Conrad Hoffmann <ch at bitfehler.net>.

Signed-off-by: Gergely Nagy <algernon at balabit.hu>
---
 configure.in                           |    2 +-
 modules/afmongodb/afmongodb-grammar.ym |   26 ++++++-
 modules/afmongodb/afmongodb-parser.c   |    1 +
 modules/afmongodb/afmongodb.c          |  118 +++++++++++++++++++++++---------
 modules/afmongodb/afmongodb.h          |    3 +
 modules/afmongodb/libmongo-client      |    2 +-
 6 files changed, 115 insertions(+), 37 deletions(-)

diff --git a/configure.in b/configure.in
index a0410ed..294066a 100644
--- a/configure.in
+++ b/configure.in
@@ -28,7 +28,7 @@ IVYKIS_MIN_VERSION="0.30.1"
 JSON_C_MIN_VERSION="0.9"
 JSON_GLIB_MIN_VERSION="0.12"
 PCRE_MIN_VERSION="6.1"
-LMC_MIN_VERSION="0.1.0"
+LMC_MIN_VERSION="0.1.6"
 
 dnl ***************************************************************************
 dnl Initial setup
diff --git a/modules/afmongodb/afmongodb-grammar.ym b/modules/afmongodb/afmongodb-grammar.ym
index 71dd46d..f108f26 100644
--- a/modules/afmongodb/afmongodb-grammar.ym
+++ b/modules/afmongodb/afmongodb-grammar.ym
@@ -52,6 +52,7 @@ extern ValuePairsTransformSet *last_vp_transset;
 %token KW_COLLECTION
 %token KW_SERVERS
 %token KW_SAFE_MODE
+%token KW_PATH
 
 %%
 
@@ -69,14 +70,33 @@ afmongodb_options
 	;
 
 afmongodb_option
-	: KW_SERVERS '(' string_list ')'	{ afmongodb_dd_set_servers(last_driver, $3); }
+	: KW_SERVERS '(' string_list ')'
+          {
+            CHECK_ERROR(afmongodb_dd_check_address(last_driver, FALSE), @3, "Can't mix path() & servers()");
+            afmongodb_dd_set_servers(last_driver, $3);
+          }
+        | KW_HOST '(' string ')'
+          {
+            CHECK_ERROR(afmongodb_dd_check_address(last_driver, FALSE), @3, "Can't mix path() & host()");
+            afmongodb_dd_set_host(last_driver, $3);
+            free($3);
+          }
+        | KW_PORT '(' LL_NUMBER ')'
+          {
+            CHECK_ERROR(afmongodb_dd_check_address(last_driver, FALSE), @3, "Can't mix path() & port()");
+            afmongodb_dd_set_port(last_driver, $3);
+          }
+        | KW_PATH '(' string ')'
+          {
+            CHECK_ERROR(afmongodb_dd_check_address(last_driver, TRUE), @3, "Can't mix path() with host() or server()");
+            afmongodb_dd_set_path(last_driver, $3);
+            free($3);
+          }
 	| KW_DATABASE '(' string ')'		{ afmongodb_dd_set_database(last_driver, $3); free($3); }
 	| KW_COLLECTION '(' string ')'		{ afmongodb_dd_set_collection(last_driver, $3); free($3); }
 	| KW_USERNAME '(' string ')'		{ afmongodb_dd_set_user(last_driver, $3); free($3); }
 	| KW_PASSWORD '(' string ')'		{ afmongodb_dd_set_password(last_driver, $3); free($3); }
 	| KW_SAFE_MODE '(' yesno ')'		{ afmongodb_dd_set_safe_mode(last_driver, $3); }
-        | KW_HOST '(' string ')'                { afmongodb_dd_set_host(last_driver, $3); free($3); }
-        | KW_PORT '(' LL_NUMBER ')'             { afmongodb_dd_set_port(last_driver, $3); }
 	| value_pair_option			{ afmongodb_dd_set_value_pairs(last_driver, $1); }
 	| dest_driver_option
         ;
diff --git a/modules/afmongodb/afmongodb-parser.c b/modules/afmongodb/afmongodb-parser.c
index 9d72878..8aa55c1 100644
--- a/modules/afmongodb/afmongodb-parser.c
+++ b/modules/afmongodb/afmongodb-parser.c
@@ -38,6 +38,7 @@ static CfgLexerKeyword afmongodb_keywords[] = {
   { "safe_mode",		KW_SAFE_MODE },
   { "host",                     KW_HOST },
   { "port",                     KW_PORT },
+  { "path",                     KW_PATH },
   { NULL }
 };
 
diff --git a/modules/afmongodb/afmongodb.c b/modules/afmongodb/afmongodb.c
index 5af34c9..aeed3d3 100644
--- a/modules/afmongodb/afmongodb.c
+++ b/modules/afmongodb/afmongodb.c
@@ -50,7 +50,7 @@ typedef struct
   gchar *coll;
 
   GList *servers;
-  gchar *host;
+  gchar *address;
   gint port;
 
   gboolean safe_mode;
@@ -116,8 +116,8 @@ afmongodb_dd_set_host(LogDriver *d, const gchar *host)
 {
   MongoDBDestDriver *self = (MongoDBDestDriver *)d;
 
-  g_free(self->host);
-  self->host = g_strdup(host);
+  g_free(self->address);
+  self->address = g_strdup(host);
 }
 
 void
@@ -138,6 +138,39 @@ afmongodb_dd_set_servers(LogDriver *d, GList *servers)
 }
 
 void
+afmongodb_dd_set_path(LogDriver *d, const gchar *path)
+{
+  MongoDBDestDriver *self = (MongoDBDestDriver *)d;
+
+  g_free(self->address);
+  self->address = g_strdup(path);
+  self->port = MONGO_CONN_LOCAL;
+}
+
+gboolean
+afmongodb_dd_check_address(LogDriver *d, gboolean local)
+{
+  MongoDBDestDriver *self = (MongoDBDestDriver *)d;
+
+  if (local)
+    {
+      if ((self->port != 0 ||
+           self->port != MONGO_CONN_LOCAL) &&
+          self->address != NULL)
+        return FALSE;
+      if (self->servers)
+        return FALSE;
+    }
+  else
+    {
+      if (self->port == MONGO_CONN_LOCAL &&
+          self->address != NULL)
+        return FALSE;
+    }
+  return TRUE;
+}
+
+void
 afmongodb_dd_set_database(LogDriver *d, const gchar *database)
 {
   MongoDBDestDriver *self = (MongoDBDestDriver *)d;
@@ -182,8 +215,12 @@ afmongodb_dd_format_stats_instance(MongoDBDestDriver *self)
 {
   static gchar persist_name[1024];
 
-  g_snprintf(persist_name, sizeof(persist_name),
-	     "mongodb,%s,%u,%s,%s", self->host, self->port, self->db, self->coll);
+  if (self->port == MONGO_CONN_LOCAL)
+    g_snprintf(persist_name, sizeof(persist_name),
+               "mongodb,%s,%s,%s", self->address, self->db, self->coll);
+  else
+    g_snprintf(persist_name, sizeof(persist_name),
+               "mongodb,%s,%u,%s,%s", self->address, self->port, self->db, self->coll);
   return persist_name;
 }
 
@@ -192,8 +229,12 @@ afmongodb_dd_format_persist_name(MongoDBDestDriver *self)
 {
   static gchar persist_name[1024];
 
-  g_snprintf(persist_name, sizeof(persist_name),
-	     "afmongodb(%s,%u,%s,%s)", self->host, self->port, self->db, self->coll);
+  if (self->port == MONGO_CONN_LOCAL)
+    g_snprintf(persist_name, sizeof(persist_name),
+               "afmongodb(%s,%s,%s)", self->address, self->db, self->coll);
+  else
+    g_snprintf(persist_name, sizeof(persist_name),
+               "afmongodb(%s,%u,%s,%s)", self->address, self->port, self->db, self->coll);
   return persist_name;
 }
 
@@ -221,7 +262,7 @@ afmongodb_dd_connect(MongoDBDestDriver *self, gboolean reconnect)
   if (reconnect && self->conn)
     return TRUE;
 
-  self->conn = mongo_sync_connect(self->host, self->port, FALSE);
+  self->conn = mongo_sync_connect(self->address, self->port, FALSE);
   if (!self->conn)
     {
       msg_error ("Error connecting to MongoDB", NULL);
@@ -467,31 +508,45 @@ afmongodb_dd_init(LogPipe *s)
       value_pairs_add_scope(self->vp, "nv-pairs");
     }
 
-  if (self->host)
-    {
-      gchar *srv = g_strdup_printf ("%s:%d", self->host,
-                                    (self->port) ? self->port : 27017);
-      self->servers = g_list_prepend (self->servers, srv);
-      g_free (self->host);
-    }
-
-  self->host = NULL;
-  self->port = 27017;
-  if (!mongo_util_parse_addr(g_list_nth_data(self->servers, 0), &self->host,
-			     &self->port))
+  if (self->port != MONGO_CONN_LOCAL)
     {
-      msg_error("Cannot parse the primary host",
-		evt_tag_str("primary", g_list_nth_data(self->servers, 0)),
-		NULL);
-      return FALSE;
+      if (self->address)
+        {
+          gchar *srv = g_strdup_printf ("%s:%d", self->address,
+                                        (self->port) ? self->port : 27017);
+          self->servers = g_list_prepend (self->servers, srv);
+          g_free (self->address);
+        }
+
+      if (!self->servers)
+        afmongodb_dd_set_servers((LogDriver *)self, g_list_append (NULL, g_strdup ("127.0.0.1:27017")));
+
+      self->address = NULL;
+      self->port = 27017;
+      if (!mongo_util_parse_addr(g_list_nth_data(self->servers, 0),
+                                 &self->address,
+                                 &self->port))
+        {
+          msg_error("Cannot parse the primary host",
+                    evt_tag_str("primary", g_list_nth_data(self->servers, 0)),
+                    NULL);
+          return FALSE;
+        }
     }
 
-  msg_verbose("Initializing MongoDB destination",
-	      evt_tag_str("host", self->host),
-	      evt_tag_int("port", self->port),
-	      evt_tag_str("database", self->db),
-	      evt_tag_str("collection", self->coll),
-	      NULL);
+  if (self->port == MONGO_CONN_LOCAL)
+    msg_verbose("Initializing MongoDB destination",
+                evt_tag_str("address", self->address),
+                evt_tag_str("database", self->db),
+                evt_tag_str("collection", self->coll),
+                NULL);
+  else
+    msg_verbose("Initializing MongoDB destination",
+                evt_tag_str("address", self->address),
+                evt_tag_int("port", self->port),
+                evt_tag_str("database", self->db),
+                evt_tag_str("collection", self->coll),
+                NULL);
 
   self->queue = log_dest_driver_acquire_queue(&self->super, afmongodb_dd_format_persist_name(self));
 
@@ -548,7 +603,7 @@ afmongodb_dd_free(LogPipe *d)
   g_free(self->coll);
   g_free(self->user);
   g_free(self->password);
-  g_free(self->host);
+  g_free(self->address);
   string_list_free(self->servers);
   if (self->vp)
     value_pairs_free(self->vp);
@@ -609,7 +664,6 @@ afmongodb_dd_new(void)
   self->super.super.super.queue = afmongodb_dd_queue;
   self->super.super.super.free_fn = afmongodb_dd_free;
 
-  afmongodb_dd_set_servers((LogDriver *)self, g_list_append (NULL, g_strdup ("127.0.0.1:27017")));
   afmongodb_dd_set_database((LogDriver *)self, "syslog");
   afmongodb_dd_set_collection((LogDriver *)self, "messages");
   afmongodb_dd_set_safe_mode((LogDriver *)self, FALSE);
diff --git a/modules/afmongodb/afmongodb.h b/modules/afmongodb/afmongodb.h
index e1f4b57..6a61616 100644
--- a/modules/afmongodb/afmongodb.h
+++ b/modules/afmongodb/afmongodb.h
@@ -38,5 +38,8 @@ void afmongodb_dd_set_user(LogDriver *d, const gchar *user);
 void afmongodb_dd_set_password(LogDriver *d, const gchar *password);
 void afmongodb_dd_set_value_pairs(LogDriver *d, ValuePairs *vp);
 void afmongodb_dd_set_safe_mode(LogDriver *d, gboolean state);
+void afmongodb_dd_set_path(LogDriver *d, const gchar *path);
+
+gboolean afmongodb_dd_check_address(LogDriver *d, gboolean local);
 
 #endif
diff --git a/modules/afmongodb/libmongo-client b/modules/afmongodb/libmongo-client
index 58f3814..7896ce7 160000
--- a/modules/afmongodb/libmongo-client
+++ b/modules/afmongodb/libmongo-client
@@ -1 +1 @@
-Subproject commit 58f3814cad94bcd78216c7ac971c8435d17a9242
+Subproject commit 7896ce7dbc239e4069787fee336875a9b9a6f6f5
-- 
1.7.10.4




More information about the syslog-ng mailing list