diff --git a/NEWS b/NEWS index 09d540960..0e269aff6 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,7 @@ unreleased - optional support for BLE MIDI 1.0 profile as a GATT server - command line option to set real-time priority for IO threads +- command line option to filter log messages based on severity - allow to select individual extended controls in ALSA plug-in - codec-specific delay adjustment with ALSA control and persistency - fix for SBC codec and audio scaling on big-endian platforms diff --git a/doc/bluealsa-aplay.1.rst b/doc/bluealsa-aplay.1.rst index 4cb21a5f9..ced2bccfc 100644 --- a/doc/bluealsa-aplay.1.rst +++ b/doc/bluealsa-aplay.1.rst @@ -6,7 +6,7 @@ bluealsa-aplay a simple bluealsa player ------------------------ -:Date: September 2023 +:Date: February 2024 :Manual section: 1 :Manual group: General Commands Manual :Version: $VERSION$ @@ -41,6 +41,22 @@ OPTIONS Send output to system logger (``syslogd(8)``). By default, log output is sent to stderr. +--loglevel=LEVEL + Set the priority level threshold for log messages. Only messages of the + given level or higher are logged. The *LEVELs* are, in decreasing order: + + - **error** - error conditions + - **warning** - warning conditions + - **info** - informational messages + + If **bluealsa-aplay** was built with debug enabled, then an additional, + lowest, level is available: + + - **debug** - debug messages + + If this option is not given then the default is to use the lowest level + (i.e., all messages are logged). + -v, --verbose Make the output more verbose. diff --git a/doc/bluealsa.8.rst b/doc/bluealsa.8.rst index 7f9f12066..b99700a22 100644 --- a/doc/bluealsa.8.rst +++ b/doc/bluealsa.8.rst @@ -6,7 +6,7 @@ bluealsa Bluetooth Audio ALSA Backend ---------------------------- -:Date: January 2024 +:Date: February 2024 :Manual section: 8 :Manual group: System Manager's Manual :Version: $VERSION$ @@ -37,6 +37,22 @@ OPTIONS Send output to system logger (``syslogd(8)``). By default, log output is sent to stderr. +--loglevel=LEVEL + Set the priority level threshold for log messages. Only messages of the + given level or higher are logged. The *LEVELs* are, in decreasing order: + + - **error** - error conditions + - **warning** - warning conditions + - **info** - informational messages + + If **bluealsa** was built with debug enabled, then an additional, lowest, + level is available: + + - **debug** - debug messages + + If this option is not given then the default is to use the lowest level + (i.e., all messages are logged). + -B NAME, --dbus=NAME BlueALSA D-Bus service name suffix. Without this option, **bluealsa** registers itself as an "org.bluealsa" diff --git a/misc/bash-completion/bluealsa b/misc/bash-completion/bluealsa index ebc6f2dea..7f166976e 100644 --- a/misc/bash-completion/bluealsa +++ b/misc/bash-completion/bluealsa @@ -207,7 +207,7 @@ _bluealsa() { readarray -t COMPREPLY < <(compgen -P "$prefix" -W "${list[*]}" -- "$cur") return ;; - --sbc-quality|--aac-latm-version|--mp3-algorithm|--mp3-vbr-quality|--ldac-quality) + --loglevel|--sbc-quality|--aac-latm-version|--mp3-algorithm|--mp3-vbr-quality|--ldac-quality) readarray -t list < <(_bluealsa_enum_values "$1" "$prev") readarray -t COMPREPLY < <(compgen -W "${list[*]}" -- "$cur") return @@ -265,7 +265,7 @@ _bluealsa_aplay() { __ltrim_colon_completions "$cur" return ;; - --volume) + --loglevel|--volume) readarray -t list < <(_bluealsa_enum_values "$1" "$prev") readarray -t COMPREPLY < <(compgen -W "${list[*]}" -- "$cur") return diff --git a/src/main.c b/src/main.c index 7c8d69051..96db47380 100644 --- a/src/main.c +++ b/src/main.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -150,6 +151,7 @@ int main(int argc, char **argv) { { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, 'V' }, { "syslog", no_argument, NULL, 'S' }, + { "loglevel", required_argument, NULL, 23 }, { "dbus", required_argument, NULL, 'B' }, { "device", required_argument, NULL, 'i' }, { "profile", required_argument, NULL, 'p' }, @@ -203,6 +205,7 @@ int main(int argc, char **argv) { " -h, --help\t\t\tprint this help and exit\n" " -V, --version\t\t\tprint version and exit\n" " -S, --syslog\t\t\tsend output to syslog\n" + " --loglevel=LEVEL\t\tminimum message priority\n" " -B, --dbus=NAME\t\tD-Bus service name suffix\n" " -i, --device=hciX\t\tHCI device(s) to use\n" " -p, --profile=NAME\t\tset enabled BT profiles\n" @@ -287,6 +290,28 @@ int main(int argc, char **argv) { case 'S' /* --syslog */ : break; + case 23 /* --loglevel=LEVEL */ : { + + static const nv_entry_t values[] = { + { "error", .v.ui = LOG_ERR }, + { "warning", .v.ui = LOG_WARNING }, + { "info", .v.ui = LOG_INFO }, +#if DEBUG + { "debug", .v.ui = LOG_DEBUG }, +#endif + { 0 }, + }; + + const nv_entry_t *entry; + if ((entry = nv_find(values, optarg)) == NULL) { + error("Invalid loglevel {%s}: %s", nv_join_names(values), optarg); + return EXIT_FAILURE; + } + + log_set_min_priority(entry->v.ui); + break; + } + case 'B' /* --dbus=NAME */ : snprintf(dbus_service, sizeof(dbus_service), BLUEALSA_SERVICE ".%s", optarg); if (!g_dbus_is_name(dbus_service)) { diff --git a/src/shared/log.c b/src/shared/log.c index 0895e23c7..bb0fdb99c 100644 --- a/src/shared/log.c +++ b/src/shared/log.c @@ -1,6 +1,6 @@ /* * BlueALSA - log.c - * Copyright (c) 2016-2023 Arkadiusz Bokowy + * Copyright (c) 2016-2024 Arkadiusz Bokowy * * This file is a part of bluez-alsa. * @@ -9,7 +9,10 @@ */ #include "shared/log.h" -/* IWYU pragma: no_include "config.h" */ + +#if HAVE_CONFIG_H +# include +#endif #include #include @@ -36,6 +39,8 @@ static char *_ident = NULL; /* if true, system logging is enabled */ static bool _syslog = false; +/* minimum priority to be logged */ +static int _priority_limit = LOG_DEBUG; #if DEBUG_TIME @@ -59,6 +64,10 @@ void log_open(const char *ident, bool syslog) { } +void log_set_min_priority(int priority) { + _priority_limit = priority; +} + static const char *priority2str[] = { [LOG_EMERG] = "X", [LOG_ALERT] = "A", @@ -122,6 +131,8 @@ static void vlog(int priority, const char *format, va_list ap) { } void log_message(int priority, const char *format, ...) { + if (priority > _priority_limit) + return; va_list ap; va_start(ap, format); vlog(priority, format, ap); diff --git a/src/shared/log.h b/src/shared/log.h index 4ac0ab01f..e9a792ab7 100644 --- a/src/shared/log.h +++ b/src/shared/log.h @@ -1,6 +1,6 @@ /* * BlueALSA - log.h - * Copyright (c) 2016-2022 Arkadiusz Bokowy + * Copyright (c) 2016-2024 Arkadiusz Bokowy * * This file is a part of bluez-alsa. * @@ -23,6 +23,7 @@ #include "defs.h" void log_open(const char *ident, bool syslog); +void log_set_min_priority(int priority); void log_message(int priority, const char *format, ...) __attribute__ ((format(printf, 2, 3))); #if DEBUG diff --git a/test/test-utils-aplay.c b/test/test-utils-aplay.c index 052579481..32c78de2a 100644 --- a/test/test-utils-aplay.c +++ b/test/test-utils-aplay.c @@ -168,6 +168,7 @@ CK_START_TEST(test_play_all) { struct spawn_process sp_ba_aplay; ck_assert_int_ne(spawn_bluealsa_aplay(&sp_ba_aplay, + "--loglevel=debug", "--profile-a2dp", "--pcm=null", "-v", "-v", diff --git a/utils/aplay/aplay.c b/utils/aplay/aplay.c index e420a9a36..213c0d64b 100644 --- a/utils/aplay/aplay.c +++ b/utils/aplay/aplay.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -1010,6 +1011,7 @@ int main(int argc, char *argv[]) { { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, 'V' }, { "syslog", no_argument, NULL, 'S' }, + { "loglevel", required_argument, NULL, 9 }, { "verbose", no_argument, NULL, 'v' }, { "list-devices", no_argument, NULL, 'l' }, { "list-pcms", no_argument, NULL, 'L' }, @@ -1043,6 +1045,7 @@ int main(int argc, char *argv[]) { " -h, --help\t\t\tprint this help and exit\n" " -V, --version\t\t\tprint version and exit\n" " -S, --syslog\t\t\tsend output to syslog\n" + " --loglevel=LEVEL\t\tminimum message priority\n" " -v, --verbose\t\t\tmake output more verbose\n" " -l, --list-devices\t\tlist available BT audio devices\n" " -L, --list-pcms\t\tlist available BT audio PCMs\n" @@ -1091,6 +1094,28 @@ int main(int argc, char *argv[]) { case 'v' /* --verbose */ : break; + case 9 /* --loglevel=LEVEL */ : { + + static const nv_entry_t values[] = { + { "error", .v.ui = LOG_ERR }, + { "warning", .v.ui = LOG_WARNING }, + { "info", .v.ui = LOG_INFO }, +#if DEBUG + { "debug", .v.ui = LOG_DEBUG }, +#endif + { 0 }, + }; + + const nv_entry_t *entry; + if ((entry = nv_find(values, optarg)) == NULL) { + error("Invalid loglevel {%s}: %s", nv_join_names(values), optarg); + return EXIT_FAILURE; + } + + log_set_min_priority(entry->v.ui); + break; + } + case 'l' /* --list-devices */ : list_bt_devices = true; break;