Skip to content

Commit

Permalink
Merge pull request #2990 from furiel/generate-config-graph
Browse files Browse the repository at this point in the history
visualize config graph
  • Loading branch information
lbudai committed Nov 19, 2019
2 parents 367792c + 3ece1d2 commit 94fb0c8
Show file tree
Hide file tree
Showing 13 changed files with 365 additions and 0 deletions.
2 changes: 2 additions & 0 deletions contrib/Makefile.am
Expand Up @@ -84,6 +84,8 @@ EXTRA_DIST += \
contrib/systemd/syslog-ng@.service \
contrib/systemd/syslog-ng@default \
\
contrib/scripts/config-graph-json-to-dot.py \
\
contrib/valgrind/syslog-ng.supp

if ENABLE_SYSTEMD_UNIT_INSTALL
Expand Down
21 changes: 21 additions & 0 deletions contrib/scripts/config-graph-json-to-dot.py
@@ -0,0 +1,21 @@
#!/usr/bin/env python
import json, sys

j = None

if len(sys.argv) == 1:
j = json.loads(sys.stdin.read())
else:
file_name = sys.argv[1]
with open(file_name) as f:
j = json.loads(f.read())

nodes = j["nodes"]
arcs = j["arcs"]

print("digraph D {")
for node in nodes:
print(" Node{} [label=\"{} {}\"]".format(node["node"], node["node"], ", ".join(node["info"])))
for arc in arcs:
print(" Node{} -> Node{} [label=\"{}\"]".format(arc["from"], arc["to"], arc["type"]))
print("}")
2 changes: 2 additions & 0 deletions lib/CMakeLists.txt
Expand Up @@ -76,6 +76,7 @@ set (LIB_HEADERS
cfg-parser.h
cfg-path.h
cfg-tree.h
cfg-walker.h
children.h
crypto.h
dnscache.h
Expand Down Expand Up @@ -165,6 +166,7 @@ set(LIB_SOURCES
cfg-parser.c
cfg-path.c
cfg-tree.c
cfg-walker.c
children.c
dnscache.c
driver.c
Expand Down
2 changes: 2 additions & 0 deletions lib/Makefile.am
Expand Up @@ -111,6 +111,7 @@ pkginclude_HEADERS += \
lib/cfg-parser.h \
lib/cfg-path.h \
lib/cfg-tree.h \
lib/cfg-walker.h \
lib/children.h \
lib/crypto.h \
lib/dnscache.h \
Expand Down Expand Up @@ -198,6 +199,7 @@ lib_libsyslog_ng_la_SOURCES = \
lib/cfg-parser.c \
lib/cfg-path.c \
lib/cfg-tree.c \
lib/cfg-walker.c \
lib/children.c \
lib/dnscache.c \
lib/driver.c \
Expand Down
4 changes: 4 additions & 0 deletions lib/cfg-tree.c
Expand Up @@ -621,6 +621,7 @@ cfg_tree_new_pipe(CfgTree *self, LogExprNode *related_expr)
LogPipe *pipe = log_pipe_new(self->cfg);
pipe->expr_node = related_expr;
g_ptr_array_add(self->initialized_pipes, pipe);
log_pipe_add_info(pipe, "cfg_tree_pipe");
return pipe;
}

Expand Down Expand Up @@ -809,6 +810,7 @@ cfg_tree_compile_reference(CfgTree *self, LogExprNode *node,
if (!sub_pipe_tail->pipe_next)
{
mpx = cfg_tree_new_mpx(self, referenced_node);
log_pipe_add_info(&mpx->super, "mpx(source)");
log_pipe_append(sub_pipe_tail, &mpx->super);
}
else
Expand Down Expand Up @@ -849,6 +851,7 @@ cfg_tree_compile_reference(CfgTree *self, LogExprNode *node,
*/

mpx = cfg_tree_new_mpx(self, node);
log_pipe_add_info(&mpx->super, "mpx(destination-reference)");

if (sub_pipe_head)
{
Expand Down Expand Up @@ -1133,6 +1136,7 @@ cfg_tree_compile_junction(CfgTree *self,
if (!fork_mpx)
{
fork_mpx = cfg_tree_new_mpx(self, node);
log_pipe_add_info(&fork_mpx->super, "mpx(junction)");
*outer_pipe_head = &fork_mpx->super;
}
log_multiplexer_add_next_hop(fork_mpx, sub_pipe_head);
Expand Down
92 changes: 92 additions & 0 deletions lib/cfg-walker.c
@@ -0,0 +1,92 @@
/*
* Copyright (c) 2019 Balabit
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As an additional exemption you are allowed to compile & link against the
* OpenSSL libraries as published by the OpenSSL project. See the file
* COPYING for details.
*
*/

#include "cfg-walker.h"
#include "logpipe.h"

Arc *
arc_new(LogPipe *from, LogPipe *to, ArcType arc_type)
{
Arc *self = g_new0(Arc, 1);
self->from = from;
self->to = to;
self->arc_type = arc_type;

return self;
};

void
arc_free(Arc *self)
{
g_free(self);
}

static guint
arc_hash(Arc *arc)
{
return g_direct_hash(arc->from);
}

static gboolean
arc_equal(Arc *arc1, Arc *arc2)
{
return arc1->to == arc2->to;
}

static void walk_pipe(LogPipe *self, gpointer *user_data);

static void
_add_arc_and_walk(Arc *arc, gpointer *user_data)
{
GHashTable **arcs = user_data[1];
g_hash_table_insert(*arcs, arc, NULL);
walk_pipe(arc->to, user_data);
}

static void
walk_pipe(LogPipe *self, gpointer *user_data)
{

GHashTable **nodes = user_data[0];

if (g_hash_table_contains(*nodes, self))
return;

g_hash_table_insert(*nodes, self, NULL);

GList *new_arcs = log_pipe_get_arcs(self);
g_list_foreach(new_arcs, (GFunc)_add_arc_and_walk, user_data);
g_list_free(new_arcs);
}

void
cfg_walker_get_graph(GPtrArray *start_nodes, GHashTable **nodes, GHashTable **arcs)
{
*nodes = g_hash_table_new(g_direct_hash, g_direct_equal);
*arcs = g_hash_table_new_full((GHashFunc)arc_hash, (GEqualFunc)arc_equal, (GDestroyNotify)arc_free, NULL);

g_ptr_array_foreach(start_nodes, (GFunc)walk_pipe, (gpointer [])
{
nodes, arcs
});
}
46 changes: 46 additions & 0 deletions lib/cfg-walker.h
@@ -0,0 +1,46 @@
/*
* Copyright (c) 2019 Balabit
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As an additional exemption you are allowed to compile & link against the
* OpenSSL libraries as published by the OpenSSL project. See the file
* COPYING for details.
*
*/

#ifndef CFG_WALKER_H_INCLUDED
#define CFG_WALKER_H_INCLUDED

#include "syslog-ng.h"

typedef enum
{
ARC_TYPE_PIPE_NEXT,
ARC_TYPE_NEXT_HOP
} ArcType;

typedef struct
{
LogPipe *from;
LogPipe *to;
ArcType arc_type;
} Arc;

void cfg_walker_get_graph(GPtrArray *start_nodes, GHashTable **nodes, GHashTable **arcs);
Arc *arc_new(LogPipe *from, LogPipe *to, ArcType arc_type);
void arc_free(Arc *self);

#endif
27 changes: 27 additions & 0 deletions lib/logmpx.c
Expand Up @@ -23,6 +23,7 @@
*/

#include "logmpx.h"
#include "cfg-walker.h"


void
Expand Down Expand Up @@ -138,6 +139,30 @@ log_multiplexer_free(LogPipe *s)
log_pipe_free_method(s);
}

static void
_append(LogPipe *to, gpointer *user_data)
{
LogPipe *from = user_data[0];
GList **list = user_data[1];

Arc *arc = arc_new(from, to, ARC_TYPE_NEXT_HOP);
*list = g_list_append(*list, arc);
}

static GList *
_arcs(LogPipe *s)
{
LogMultiplexer *self = (LogMultiplexer *)s;
GList *list = NULL;
g_ptr_array_foreach(self->next_hops, (GFunc)_append, (gpointer[2])
{
self, &list
});
if (s->pipe_next)
list = g_list_append(list, arc_new((LogPipe *)self, s->pipe_next, ARC_TYPE_PIPE_NEXT));
return list;
};

LogMultiplexer *
log_multiplexer_new(GlobalConfig *cfg)
{
Expand All @@ -149,5 +174,7 @@ log_multiplexer_new(GlobalConfig *cfg)
self->super.queue = log_multiplexer_queue;
self->super.free_fn = log_multiplexer_free;
self->next_hops = g_ptr_array_new();
self->super.arcs = _arcs;
log_pipe_add_info(&self->super, "multiplexer");
return self;
}
18 changes: 18 additions & 0 deletions lib/logpipe.c
Expand Up @@ -24,6 +24,7 @@

#include "logpipe.h"
#include "cfg-tree.h"
#include "cfg-walker.h"

gboolean (*pipe_single_step_hook)(LogPipe *pipe, LogMessage *msg, const LogPathOptions *path_options);

Expand All @@ -47,6 +48,15 @@ void log_pipe_detach_expr_node(LogPipe *self)
self->expr_node = NULL;
}

static GList *
_arcs(LogPipe *self)
{
if (self->pipe_next)
return g_list_append(NULL, arc_new(self, self->pipe_next, ARC_TYPE_PIPE_NEXT));
else
return NULL;
}

void
log_pipe_init_instance(LogPipe *self, GlobalConfig *cfg)
{
Expand All @@ -63,6 +73,7 @@ log_pipe_init_instance(LogPipe *self, GlobalConfig *cfg)

self->queue = NULL;
self->free_fn = log_pipe_free_method;
self->arcs = _arcs;
}

LogPipe *
Expand Down Expand Up @@ -99,6 +110,7 @@ _free(LogPipe *self)
self->free_fn(self);
g_free((gpointer)self->persist_name);
g_free(self->plugin_name);
g_list_free_full(self->info, g_free);
g_free(self);
}

Expand Down Expand Up @@ -133,6 +145,12 @@ log_pipe_get_persist_name(const LogPipe *self)
: self->persist_name;
}

void
log_pipe_add_info(LogPipe *self, const gchar *info)
{
self->info = g_list_append(self->info, g_strdup(info));
}

#ifdef __linux__

void
Expand Down
9 changes: 9 additions & 0 deletions lib/logpipe.h
Expand Up @@ -231,6 +231,7 @@ struct _LogPipe
void (*post_deinit)(LogPipe *self);

const gchar *(*generate_persist_name)(const LogPipe *self);
GList *(*arcs)(LogPipe *self);

/* clone this pipe when used in multiple locations in the processing
* pipe-line. If it contains state, it should behave as if it was
Expand All @@ -240,6 +241,7 @@ struct _LogPipe

void (*free_fn)(LogPipe *self);
void (*notify)(LogPipe *self, gint notify_code, gpointer user_data);
GList *info;
};

/*
Expand Down Expand Up @@ -400,4 +402,11 @@ log_pipe_get_persist_name(const LogPipe *self);

void log_pipe_free_method(LogPipe *s);

static inline GList *
log_pipe_get_arcs(LogPipe *s)
{
return s->arcs(s);
}

void log_pipe_add_info(LogPipe *self, const gchar *info);
#endif
2 changes: 2 additions & 0 deletions lib/logwriter.c
Expand Up @@ -1416,6 +1416,8 @@ log_writer_init(LogPipe *s)
log_writer_postpone_mark_timer(self);
}

log_pipe_add_info(s, "writer");

return TRUE;
}

Expand Down

0 comments on commit 94fb0c8

Please sign in to comment.