Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

visualize config graph #2990

Merged
merged 11 commits into from Nov 19, 2019
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 @@ -1108,6 +1111,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