From: Lennart Poettering Date: Tue, 21 Apr 2020 08:25:50 +0000 (+0200) Subject: log-control-api: add generic D-Bus interface for querying/setting log level/target X-Git-Tag: v246-rc1~532^2~4 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=052740e2e35cf9bbb56e8809050faf0c6ee60cb4;p=thirdparty%2Fsystemd.git log-control-api: add generic D-Bus interface for querying/setting log level/target Let's define a new, generic bus interface that any daemon can implement for querying/setting the log level. We can turn this into something more powerful later on, but for now, only expose three properties: the log level, log target and the syslog identifier (with the former two being writable). This is supposed to be generic, so that it can be implemented by 3rd party daemons too, eventually. --- diff --git a/src/shared/bus-log-control-api.c b/src/shared/bus-log-control-api.c new file mode 100644 index 00000000000..ffc52c77745 --- /dev/null +++ b/src/shared/bus-log-control-api.c @@ -0,0 +1,123 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ + +#include "alloc-util.h" +#include "bus-log-control-api.h" +#include "bus-util.h" +#include "log.h" +#include "sd-bus.h" +#include "syslog-util.h" + +int bus_property_get_log_level( + sd_bus *bus, + const char *path, + const char *interface, + const char *property, + sd_bus_message *reply, + void *userdata, + sd_bus_error *error) { + + _cleanup_free_ char *t = NULL; + int r; + + assert(bus); + assert(reply); + + r = log_level_to_string_alloc(log_get_max_level(), &t); + if (r < 0) + return r; + + return sd_bus_message_append(reply, "s", t); +} + +int bus_property_set_log_level( + sd_bus *bus, + const char *path, + const char *interface, + const char *property, + sd_bus_message *value, + void *userdata, + sd_bus_error *error) { + + const char *t; + int r; + + assert(bus); + assert(value); + + r = sd_bus_message_read(value, "s", &t); + if (r < 0) + return r; + + r = log_level_from_string(t); + if (r < 0) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid log level '%s'", t); + + log_info("Setting log level to %s.", t); + log_set_max_level(r); + + return 0; +} + +BUS_DEFINE_PROPERTY_GET_GLOBAL(bus_property_get_log_target, "s", log_target_to_string(log_get_target())); + +int bus_property_set_log_target( + sd_bus *bus, + const char *path, + const char *interface, + const char *property, + sd_bus_message *value, + void *userdata, + sd_bus_error *error) { + + LogTarget target; + const char *t; + int r; + + assert(bus); + assert(value); + + r = sd_bus_message_read(value, "s", &t); + if (r < 0) + return r; + + target = log_target_from_string(t); + if (target < 0) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid log target '%s'", t); + + log_info("Setting log target to %s.", log_target_to_string(target)); + log_set_target(target); + log_open(); + + return 0; +} + +BUS_DEFINE_PROPERTY_GET_GLOBAL(bus_property_get_syslog_identifier, "s", program_invocation_short_name); + +static const sd_bus_vtable log_control_vtable[] = { + SD_BUS_VTABLE_START(0), + + SD_BUS_WRITABLE_PROPERTY("LogLevel", "s", bus_property_get_log_level, bus_property_set_log_level, 0, 0), + SD_BUS_WRITABLE_PROPERTY("LogTarget", "s", bus_property_get_log_target, bus_property_set_log_target, 0, 0), + SD_BUS_PROPERTY("SyslogIdentifier", "s", bus_property_get_syslog_identifier, 0, 0), + + /* One of those days we might want to add a similar, second interface to cover common service + * operations such as Reload(), Reexecute(), Exit() … and maybe some properties exposing version + * number and other meta-data of the service. */ + + SD_BUS_VTABLE_END, +}; + +int bus_log_control_api_register(sd_bus *bus) { + int r; + + r = sd_bus_add_object_vtable( + bus, + NULL, + "/org/freedesktop/LogControl1", + "org.freedesktop.LogControl1", + log_control_vtable, NULL); + if (r < 0) + return log_error_errno(r, "Failed to register service API object: %m"); + + return 0; +} diff --git a/src/shared/bus-log-control-api.h b/src/shared/bus-log-control-api.h new file mode 100644 index 00000000000..a6fb2757c5f --- /dev/null +++ b/src/shared/bus-log-control-api.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ + +#include "sd-bus.h" + +int bus_log_control_api_register(sd_bus *bus); + +int bus_property_get_log_level(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error); +int bus_property_set_log_level(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *value, void *userdata, sd_bus_error *error); + +int bus_property_get_log_target(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error); +int bus_property_set_log_target(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error); + +int bus_property_get_syslog_identifier(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error); diff --git a/src/shared/meson.build b/src/shared/meson.build index d1832a1f53f..483148492c8 100644 --- a/src/shared/meson.build +++ b/src/shared/meson.build @@ -23,14 +23,16 @@ shared_sources = files(''' bpf-program.h bridge-util.c bridge-util.h + bus-log-control-api.c + bus-log-control-api.h + bus-polkit.c + bus-polkit.h bus-unit-procs.c bus-unit-procs.h bus-unit-util.c bus-unit-util.h bus-util.c bus-util.h - bus-polkit.c - bus-polkit.h bus-wait-for-jobs.c bus-wait-for-jobs.h bus-wait-for-units.c