[systemd-devel] [PATCH] systemd-analyze: filter dot output with a regular expression
Zbigniew Jędrzejewski-Szmek
zbyszek at in.waw.pl
Sun Mar 24 10:33:07 PDT 2013
On Sun, Mar 24, 2013 at 01:32:41PM +0100, Łukasz Stelmach wrote:
> Make "systemd-analyze dot" output only lines matching a regular
> expression passed on the command line. Without the regular expression
> print everything.
> ---
>
> A graph created with the full output of dot is completely incomprehensible
> on a regular system. It thus makes perfect sense IMHO to add filtering
> to systemd-analyze instead of trying to use sed/grep/awk/perl to filter
> the dependencies but preserving the first and last line with the braces.
What regexps could one use?
Zbyszek
>
> This, of course, is the first attempt so any comments are more than
> welcome.
>
> src/analyze/systemd-analyze.c | 35 ++++++++++++++++++++++++++++-------
> 1 file changed, 28 insertions(+), 7 deletions(-)
>
> diff --git a/src/analyze/systemd-analyze.c b/src/analyze/systemd-analyze.c
> index 01bf55e..bddbeda 100644
> --- a/src/analyze/systemd-analyze.c
> +++ b/src/analyze/systemd-analyze.c
> @@ -25,6 +25,9 @@
> #include <getopt.h>
> #include <locale.h>
> #include <sys/utsname.h>
> +#include <sys/types.h>
> +#include <regex.h>
> +#include <string.h>
>
> #include "install.h"
> #include "log.h"
> @@ -578,7 +581,7 @@ static int analyze_time(DBusConnection *bus) {
> return 0;
> }
>
> -static int graph_one_property(const char *name, const char *prop, DBusMessageIter *iter) {
> +static int graph_one_property(const char *name, const char *prop, DBusMessageIter *iter, regex_t* regexp) {
>
> static const char * const colors[] = {
> "Requires", "[color=\"black\"]",
> @@ -591,6 +594,7 @@ static int graph_one_property(const char *name, const char *prop, DBusMessageIte
> "After", "[color=\"green\"]"
> };
>
> + char buf[1024];
> const char *c = NULL;
> unsigned i;
>
> @@ -624,14 +628,16 @@ static int graph_one_property(const char *name, const char *prop, DBusMessageIte
>
> assert(dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING);
> dbus_message_iter_get_basic(&sub, &s);
> - printf("\t\"%s\"->\"%s\" %s;\n", name, s, c);
> + snprintf(buf, sizeof(buf), "\t\"%s\"->\"%s\" %s;", name, s, c);
> + if (regexp == NULL || regexec(regexp, buf, 0, NULL, 0) == 0)
> + puts(buf);
> }
> }
>
> return 0;
> }
>
> -static int graph_one(DBusConnection *bus, const struct unit_info *u) {
> +static int graph_one(DBusConnection *bus, const struct unit_info *u, regex_t* regexp) {
> _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
> const char *interface = "org.freedesktop.systemd1.Unit";
> int r;
> @@ -675,7 +681,7 @@ static int graph_one(DBusConnection *bus, const struct unit_info *u) {
> }
>
> dbus_message_iter_recurse(&sub2, &sub3);
> - r = graph_one_property(u->id, prop, &sub3);
> + r = graph_one_property(u->id, prop, &sub3, regexp);
> if (r < 0)
> return r;
> }
> @@ -683,10 +689,12 @@ static int graph_one(DBusConnection *bus, const struct unit_info *u) {
> return 0;
> }
>
> -static int dot(DBusConnection *bus) {
> +static int dot(DBusConnection *bus, char* regexp_s) {
> _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
> DBusMessageIter iter, sub;
> int r;
> + regex_t regexp;
> + int use_regexp = 0;
>
> r = bus_method_call_with_reply(
> bus,
> @@ -707,6 +715,16 @@ static int dot(DBusConnection *bus) {
> return -EIO;
> }
>
> + memset(®exp, 0, sizeof(regexp));
> + if (regexp_s != NULL) {
> + r = regcomp(®exp, regexp_s, REG_NOSUB);
> + if (r != 0) {
> + log_error("Invalid regular expression.");
> + return -EINVAL;
> + }
> + use_regexp = 1;
> + }
> +
> printf("digraph systemd {\n");
>
> for (dbus_message_iter_recurse(&iter, &sub);
> @@ -718,13 +736,16 @@ static int dot(DBusConnection *bus) {
> if (r < 0)
> return -EIO;
>
> - r = graph_one(bus, &u);
> + r = graph_one(bus, &u, use_regexp ? ®exp : NULL);
> if (r < 0)
> return r;
> }
>
> printf("}\n");
>
> + if (use_regexp)
> + regfree(®exp);
> +
> log_info(" Color legend: black = Requires\n"
> " dark blue = Requisite\n"
> " dark grey = Wants\n"
> @@ -844,7 +865,7 @@ int main(int argc, char *argv[]) {
> else if (streq(argv[optind], "plot"))
> r = analyze_plot(bus);
> else if (streq(argv[optind], "dot"))
> - r = dot(bus);
> + r = dot(bus, argv[optind+1]);
> else
> log_error("Unknown operation '%s'.", argv[optind]);
>
> --
> 1.8.1.5
>
> _______________________________________________
> systemd-devel mailing list
> systemd-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/systemd-devel
>
More information about the systemd-devel
mailing list