diff --git a/src/Listen.cxx b/src/Listen.cxx index 14e194099..34a9fe8d9 100644 --- a/src/Listen.cxx +++ b/src/Listen.cxx @@ -25,13 +25,16 @@ #include "config/Data.hxx" #include "config/Option.hxx" #include "config/Net.hxx" +#include "lib/fmt/ExceptionFormatter.hxx" +#include "lib/fmt/PathFormatter.hxx" #include "net/AllocatedSocketAddress.hxx" #include "net/UniqueSocketDescriptor.hxx" #include "net/SocketUtil.hxx" #include "system/Error.hxx" -#include "util/RuntimeError.hxx" #include "fs/AllocatedPath.hxx" #include "fs/XDG.hxx" +#include "util/Domain.hxx" +#include "util/RuntimeError.hxx" #include @@ -41,6 +44,10 @@ #define DEFAULT_PORT 6600 +#if defined(USE_XDG) && defined(HAVE_UN) +static constexpr Domain listen_domain("listen"); +#endif + int listen_port; #ifdef ENABLE_SYSTEMD_DAEMON @@ -98,9 +105,9 @@ ListenXdgRuntimeDir(ClientListener &listener) noexcept listener.AddFD(std::move(fd), std::move(address)); return true; } catch (...) { - FormatError(std::current_exception(), - "Failed to listen on '%s' (not fatal)", - socket_path.c_str()); + FmtError(listen_domain, + "Failed to listen on '{}' (not fatal): {}", + socket_path, std::current_exception()); return false; } #else diff --git a/src/Log.cxx b/src/Log.cxx index e174355e8..505ff3e4a 100644 --- a/src/Log.cxx +++ b/src/Log.cxx @@ -17,17 +17,12 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "LogV.hxx" +#include "Log.hxx" +#include "lib/fmt/ExceptionFormatter.hxx" #include "util/Domain.hxx" -#include "util/Exception.hxx" #include -#include - -#include -#include - static constexpr Domain exception_domain("exception"); void @@ -43,128 +38,14 @@ LogVFmt(LogLevel level, const Domain &domain, Log(level, domain, {buffer.data(), buffer.size()}); } -void -LogFormatV(LogLevel level, const Domain &domain, - const char *fmt, std::va_list ap) noexcept -{ - char msg[1024]; - vsnprintf(msg, sizeof(msg), fmt, ap); - Log(level, domain, msg); -} - -void -LogFormat(LogLevel level, const Domain &domain, const char *fmt, ...) noexcept -{ - std::va_list ap; - va_start(ap, fmt); - LogFormatV(level, domain, fmt, ap); - va_end(ap); -} - -void -FormatDebug(const Domain &domain, const char *fmt, ...) noexcept -{ - std::va_list ap; - va_start(ap, fmt); - LogFormatV(LogLevel::DEBUG, domain, fmt, ap); - va_end(ap); -} - -void -FormatWarning(const Domain &domain, const char *fmt, ...) noexcept -{ - std::va_list ap; - va_start(ap, fmt); - LogFormatV(LogLevel::WARNING, domain, fmt, ap); - va_end(ap); -} - -void -Log(LogLevel level, const std::exception &e) noexcept -{ - Log(level, exception_domain, GetFullMessage(e).c_str()); -} - -void -Log(LogLevel level, const std::exception &e, const char *msg) noexcept -{ - LogFormat(level, exception_domain, "%s: %s", msg, GetFullMessage(e).c_str()); -} - -void -LogFormat(LogLevel level, const std::exception &e, const char *fmt, ...) noexcept -{ - char msg[1024]; - std::va_list ap; - va_start(ap, fmt); - vsnprintf(msg, sizeof(msg), fmt, ap); - va_end(ap); - - Log(level, e, msg); -} - void Log(LogLevel level, const std::exception_ptr &ep) noexcept { - Log(level, exception_domain, GetFullMessage(ep).c_str()); + Log(level, exception_domain, GetFullMessage(ep)); } void Log(LogLevel level, const std::exception_ptr &ep, const char *msg) noexcept { - LogFormat(level, exception_domain, "%s: %s", msg, - GetFullMessage(ep).c_str()); -} - -void -LogFormat(LogLevel level, const std::exception_ptr &ep, const char *fmt, ...) noexcept -{ - char msg[1024]; - std::va_list ap; - va_start(ap, fmt); - vsnprintf(msg, sizeof(msg), fmt, ap); - va_end(ap); - - Log(level, ep, msg); -} - -void -LogErrno(const Domain &domain, int e, const char *msg) noexcept -{ - LogFormat(LogLevel::ERROR, domain, "%s: %s", msg, strerror(e)); -} - -void -LogErrno(const Domain &domain, const char *msg) noexcept -{ - LogErrno(domain, errno, msg); -} - -static void -FormatErrnoV(const Domain &domain, int e, const char *fmt, std::va_list ap) noexcept -{ - char msg[1024]; - vsnprintf(msg, sizeof(msg), fmt, ap); - - LogErrno(domain, e, msg); -} - -void -FormatErrno(const Domain &domain, int e, const char *fmt, ...) noexcept -{ - std::va_list ap; - va_start(ap, fmt); - FormatErrnoV(domain, e, fmt, ap); - va_end(ap); -} - -void -FormatErrno(const Domain &domain, const char *fmt, ...) noexcept -{ - const int e = errno; - - std::va_list ap; - va_start(ap, fmt); - FormatErrnoV(domain, e, fmt, ap); - va_end(ap); + LogFmt(level, exception_domain, "{}: {}", msg, ep); } diff --git a/src/Log.hxx b/src/Log.hxx index d276685cd..186131087 100644 --- a/src/Log.hxx +++ b/src/Log.hxx @@ -21,7 +21,6 @@ #define MPD_LOG_HXX #include "LogLevel.hxx" -#include "util/Compiler.h" #include #if FMT_VERSION < 70000 || FMT_VERSION >= 80000 @@ -97,45 +96,18 @@ FmtError(const Domain &domain, LogFmt(LogLevel::ERROR, domain, format_str, args...); } -gcc_printf(3,4) -void -LogFormat(LogLevel level, const Domain &domain, const char *fmt, ...) noexcept; - -void -Log(LogLevel level, const std::exception &e) noexcept; - -void -Log(LogLevel level, const std::exception &e, const char *msg) noexcept; - -gcc_printf(3,4) -void -LogFormat(LogLevel level, const std::exception &e, - const char *fmt, ...) noexcept; - void Log(LogLevel level, const std::exception_ptr &ep) noexcept; void Log(LogLevel level, const std::exception_ptr &ep, const char *msg) noexcept; -gcc_printf(3,4) -void -LogFormat(LogLevel level, const std::exception_ptr &ep, - const char *fmt, ...) noexcept; - static inline void LogDebug(const Domain &domain, const char *msg) noexcept { Log(LogLevel::DEBUG, domain, msg); } -gcc_printf(2,3) -void -FormatDebug(const Domain &domain, const char *fmt, ...) noexcept; - -void -FormatDebug(const Domain &domain, const char *fmt, ...) noexcept; - static inline void LogInfo(const Domain &domain, const char *msg) noexcept { @@ -154,35 +126,12 @@ LogWarning(const Domain &domain, const char *msg) noexcept Log(LogLevel::WARNING, domain, msg); } -gcc_printf(2,3) -void -FormatWarning(const Domain &domain, const char *fmt, ...) noexcept; - static inline void LogError(const Domain &domain, const char *msg) noexcept { Log(LogLevel::ERROR, domain, msg); } -inline void -LogError(const std::exception &e) noexcept -{ - Log(LogLevel::ERROR, e); -} - -inline void -LogError(const std::exception &e, const char *msg) noexcept -{ - Log(LogLevel::ERROR, e, msg); -} - -template -inline void -FormatError(const std::exception &e, const char *fmt, Args&&... args) noexcept -{ - LogFormat(LogLevel::ERROR, e, fmt, std::forward(args)...); -} - inline void LogError(const std::exception_ptr &ep) noexcept { @@ -195,26 +144,4 @@ LogError(const std::exception_ptr &ep, const char *msg) noexcept Log(LogLevel::ERROR, ep, msg); } -template -inline void -FormatError(const std::exception_ptr &ep, - const char *fmt, Args&&... args) noexcept -{ - LogFormat(LogLevel::ERROR, ep, fmt, std::forward(args)...); -} - -void -LogErrno(const Domain &domain, int e, const char *msg) noexcept; - -void -LogErrno(const Domain &domain, const char *msg) noexcept; - -gcc_printf(3,4) -void -FormatErrno(const Domain &domain, int e, const char *fmt, ...) noexcept; - -gcc_printf(2,3) -void -FormatErrno(const Domain &domain, const char *fmt, ...) noexcept; - #endif /* LOG_H */ diff --git a/src/LogV.hxx b/src/LogV.hxx deleted file mode 100644 index 312ea8cc8..000000000 --- a/src/LogV.hxx +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2003-2021 The Music Player Daemon Project - * http://www.musicpd.org - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef MPD_LOGV_HXX -#define MPD_LOGV_HXX - -#include "Log.hxx" // IWYU pragma: export - -#include - -void -LogFormatV(LogLevel level, const Domain &domain, - const char *fmt, std::va_list ap) noexcept; - -#endif /* LOG_H */ diff --git a/src/RemoteTagCache.cxx b/src/RemoteTagCache.cxx index 1e75c3a1f..4019326e4 100644 --- a/src/RemoteTagCache.cxx +++ b/src/RemoteTagCache.cxx @@ -19,10 +19,14 @@ #include "RemoteTagCache.hxx" #include "RemoteTagCacheHandler.hxx" +#include "lib/fmt/ExceptionFormatter.hxx" #include "input/ScanTags.hxx" #include "util/DeleteDisposer.hxx" +#include "util/Domain.hxx" #include "Log.hxx" +static constexpr Domain remote_tag_cache_domain("remote_tag_cache"); + RemoteTagCache::RemoteTagCache(EventLoop &event_loop, RemoteTagCacheHandler &_handler) noexcept :handler(_handler), @@ -60,9 +64,9 @@ RemoteTagCache::Lookup(const std::string &uri) noexcept item->scanner->Start(); } catch (...) { - FormatError(std::current_exception(), - "Failed to scan tags of '%s'", - uri.c_str()); + FmtError(remote_tag_cache_domain, + "Failed to scan tags of '{}': {}", + uri, std::current_exception()); item->scanner.reset(); @@ -128,7 +132,8 @@ RemoteTagCache::Item::OnRemoteTag(Tag &&_tag) noexcept void RemoteTagCache::Item::OnRemoteTagError(std::exception_ptr e) noexcept { - FormatError(e, "Failed to scan tags of '%s'", uri.c_str()); + FmtError(remote_tag_cache_domain, + "Failed to scan tags of '{}': {}", uri, e); scanner.reset(); diff --git a/src/decoder/plugins/FfmpegDecoderPlugin.cxx b/src/decoder/plugins/FfmpegDecoderPlugin.cxx index 3dfdee94f..c0ebc7b97 100644 --- a/src/decoder/plugins/FfmpegDecoderPlugin.cxx +++ b/src/decoder/plugins/FfmpegDecoderPlugin.cxx @@ -44,7 +44,7 @@ #include "util/ScopeExit.hxx" #include "util/ConstBuffer.hxx" #include "util/StringAPI.hxx" -#include "LogV.hxx" +#include "Log.hxx" extern "C" { #include diff --git a/src/event/Thread.cxx b/src/event/Thread.cxx index 0c7b5b8cc..b5d4127b8 100644 --- a/src/event/Thread.cxx +++ b/src/event/Thread.cxx @@ -21,8 +21,12 @@ #include "thread/Name.hxx" #include "thread/Slack.hxx" #include "thread/Util.hxx" +#include "lib/fmt/ExceptionFormatter.hxx" +#include "util/Domain.hxx" #include "Log.hxx" +static constexpr Domain event_domain("event"); + void EventThread::Start() { @@ -57,8 +61,9 @@ EventThread::Run() noexcept try { SetThreadRealtime(); } catch (...) { - Log(LogLevel::INFO, std::current_exception(), - "RTIOThread could not get realtime scheduling, continuing anyway"); + FmtInfo(event_domain, + "RTIOThread could not get realtime scheduling, continuing anyway: %s", + std::current_exception()); } } diff --git a/src/input/Init.cxx b/src/input/Init.cxx index 16f412193..97f96f8d3 100644 --- a/src/input/Init.cxx +++ b/src/input/Init.cxx @@ -25,6 +25,7 @@ #include "config/Block.hxx" #include "Log.hxx" #include "PluginUnavailable.hxx" +#include "util/Domain.hxx" #include "util/RuntimeError.hxx" #include @@ -35,6 +36,8 @@ #include "plugins/UringInputPlugin.hxx" #endif +static constexpr Domain input_domain("input"); + void input_stream_global_init(const ConfigData &config, EventLoop &event_loop) { @@ -67,14 +70,14 @@ input_stream_global_init(const ConfigData &config, EventLoop &event_loop) plugin->init(event_loop, *block); input_plugins_enabled[i] = true; } catch (const PluginUnconfigured &e) { - LogFormat(LogLevel::DEBUG, e, - "Input plugin '%s' is not configured", - plugin->name); + FmtDebug(input_domain, + "Input plugin '{}' is not configured: %s", + plugin->name, e.what()); continue; } catch (const PluginUnavailable &e) { - FormatError(e, - "Input plugin '%s' is unavailable", - plugin->name); + FmtDebug(input_domain, + "Input plugin '{}' is unavailable: %s", + plugin->name, e.what()); continue; } catch (...) { std::throw_with_nested(FormatRuntimeError("Failed to initialize input plugin '%s'", diff --git a/src/input/plugins/ArchiveInputPlugin.cxx b/src/input/plugins/ArchiveInputPlugin.cxx index 20a63b8f5..9f504168b 100644 --- a/src/input/plugins/ArchiveInputPlugin.cxx +++ b/src/input/plugins/ArchiveInputPlugin.cxx @@ -24,8 +24,13 @@ #include "../InputStream.hxx" #include "fs/LookupFile.hxx" #include "fs/Path.hxx" +#include "lib/fmt/ExceptionFormatter.hxx" +#include "lib/fmt/PathFormatter.hxx" +#include "util/Domain.hxx" #include "Log.hxx" +static constexpr Domain input_domain("input"); + InputStreamPtr OpenArchiveInputStream(Path path, Mutex &mutex) { @@ -38,8 +43,9 @@ OpenArchiveInputStream(Path path, Mutex &mutex) return nullptr; } } catch (...) { - LogFormat(LogLevel::DEBUG, std::current_exception(), - "not an archive, lookup %s failed", path.c_str()); + FmtDebug(input_domain, + "not an archive, lookup '{}' failed: {}", + path, std::current_exception()); return nullptr; } diff --git a/src/lib/ffmpeg/LogCallback.cxx b/src/lib/ffmpeg/LogCallback.cxx index d62c0e38c..6b2cb09f8 100644 --- a/src/lib/ffmpeg/LogCallback.cxx +++ b/src/lib/ffmpeg/LogCallback.cxx @@ -22,9 +22,9 @@ #include "LogCallback.hxx" #include "Domain.hxx" -#include "LogV.hxx" #include "util/Domain.hxx" #include "util/StringFormat.hxx" +#include "Log.hxx" extern "C" { #include @@ -60,6 +60,10 @@ FfmpegLogCallback(void *ptr, int level, const char *fmt, std::va_list vl) ffmpeg_domain.GetName(), cls->item_name(ptr)); const Domain d(domain); - LogFormatV(FfmpegImportLogLevel(level), d, fmt, vl); + + char msg[1024]; + vsnprintf(msg, sizeof(msg), fmt, vl); + + Log(FfmpegImportLogLevel(level), d, msg); } } diff --git a/src/lib/nfs/Manager.cxx b/src/lib/nfs/Manager.cxx index 9de7f3829..0056230ae 100644 --- a/src/lib/nfs/Manager.cxx +++ b/src/lib/nfs/Manager.cxx @@ -18,16 +18,21 @@ */ #include "Manager.hxx" +#include "lib/fmt/ExceptionFormatter.hxx" #include "event/Loop.hxx" -#include "Log.hxx" #include "util/DeleteDisposer.hxx" +#include "util/Domain.hxx" +#include "Log.hxx" #include +static constexpr Domain nfs_domain("nfs"); + void NfsManager::ManagedConnection::OnNfsConnectionError(std::exception_ptr &&e) noexcept { - FormatError(e, "NFS error on %s:%s", GetServer(), GetExportName()); + FmtError(nfs_domain, "NFS error on '{}:{}': {}", + GetServer(), GetExportName(), e); /* defer deletion so the caller (i.e. NfsConnection::OnSocketReady()) can still use this diff --git a/src/mixer/MixerAll.cxx b/src/mixer/MixerAll.cxx index d8dd78f66..f5e066706 100644 --- a/src/mixer/MixerAll.cxx +++ b/src/mixer/MixerAll.cxx @@ -21,11 +21,15 @@ #include "MixerControl.hxx" #include "MixerInternal.hxx" #include "MixerList.hxx" +#include "lib/fmt/ExceptionFormatter.hxx" #include "pcm/Volume.hxx" +#include "util/Domain.hxx" #include "Log.hxx" #include +static constexpr Domain mixer_domain("mixer"); + gcc_pure static int output_mixer_get_volume(const AudioOutputControl &ao) noexcept @@ -40,9 +44,9 @@ output_mixer_get_volume(const AudioOutputControl &ao) noexcept try { return mixer_get_volume(mixer); } catch (...) { - FormatError(std::current_exception(), - "Failed to read mixer for '%s'", - ao.GetName()); + FmtError(mixer_domain, + "Failed to read mixer for '{}': {}", + ao.GetName(), std::current_exception()); return -1; } } @@ -83,9 +87,9 @@ output_mixer_set_volume(AudioOutputControl &ao, unsigned volume) noexcept mixer_set_volume(mixer, volume); return true; } catch (...) { - FormatError(std::current_exception(), - "Failed to set mixer for '%s'", - ao.GetName()); + FmtError(mixer_domain, + "Failed to set mixer for '{}': {}", + ao.GetName(), std::current_exception()); return false; } } diff --git a/src/output/Thread.cxx b/src/output/Thread.cxx index 31797fd4d..4eb687cd2 100644 --- a/src/output/Thread.cxx +++ b/src/output/Thread.cxx @@ -434,8 +434,9 @@ AudioOutputControl::Task() noexcept try { SetThreadRealtime(); } catch (...) { - Log(LogLevel::INFO, std::current_exception(), - "OutputThread could not get realtime scheduling, continuing anyway"); + FmtInfo(output_domain, + "OutputThread could not get realtime scheduling, continuing anyway: %s", + std::current_exception()); } SetThreadTimerSlack(std::chrono::microseconds(100)); diff --git a/src/output/plugins/FifoOutputPlugin.cxx b/src/output/plugins/FifoOutputPlugin.cxx index ed42f7d74..f5f7e81c5 100644 --- a/src/output/plugins/FifoOutputPlugin.cxx +++ b/src/output/plugins/FifoOutputPlugin.cxx @@ -194,9 +194,9 @@ FifoOutput::Cancel() noexcept } while (bytes > 0 && errno != EINTR); if (bytes < 0 && errno != EAGAIN) { - FormatErrno(fifo_output_domain, - "Flush of FIFO \"%s\" failed", - path_utf8.c_str()); + FmtError(fifo_output_domain, + "Flush of FIFO \"{}\" failed: %s", + path_utf8, strerror(errno)); } } diff --git a/src/output/plugins/OssOutputPlugin.cxx b/src/output/plugins/OssOutputPlugin.cxx index c0a4cc0e5..6e310a9d1 100644 --- a/src/output/plugins/OssOutputPlugin.cxx +++ b/src/output/plugins/OssOutputPlugin.cxx @@ -186,9 +186,9 @@ oss_output_test_default_device() noexcept if (fd.Open(default_devices[i], O_WRONLY, 0)) return true; - FormatErrno(oss_output_domain, - "Error opening OSS device \"%s\"", - default_devices[i]); + FmtError(oss_output_domain, + "Error opening OSS device \"{}\": {}", + default_devices[i], strerror(errno)); } return false; @@ -233,8 +233,8 @@ oss_open_default( "{}: permission denied", dev); break; case OSS_STAT_OTHER: - FormatErrno(oss_output_domain, err[i], - "Error accessing %s", dev); + FmtError(oss_output_domain, "Error accessing {}: {}", + dev, strerror(err[i])); } } diff --git a/src/pcm/SoxrResampler.cxx b/src/pcm/SoxrResampler.cxx index 1b8c453e1..1547afbc7 100644 --- a/src/pcm/SoxrResampler.cxx +++ b/src/pcm/SoxrResampler.cxx @@ -227,25 +227,23 @@ SoxrPcmResampler::Open(AudioFormat &af, unsigned new_sample_rate) FmtDebug(soxr_domain, "soxr engine '{}'", soxr_engine(soxr)); if (soxr_use_custom_recipe) - FormatDebug(soxr_domain, - "soxr precision=%0.0f, phase_response=%0.2f, " - "passband_end=%0.2f, stopband_begin=%0.2f scale=%0.2f", - soxr_quality.precision, soxr_quality.phase_response, - soxr_quality.passband_end, soxr_quality.stopband_begin, - soxr_io_custom_recipe.scale); + FmtDebug(soxr_domain, + "soxr precision={:0.0}, phase_response={:0.2}, " + "passband_end={:0.2}, stopband_begin={:0.2} scale={:0.2}", + soxr_quality.precision, soxr_quality.phase_response, + soxr_quality.passband_end, soxr_quality.stopband_begin, + soxr_io_custom_recipe.scale); else - FormatDebug(soxr_domain, - "soxr precision=%0.0f, phase_response=%0.2f, " - "passband_end=%0.2f, stopband_begin=%0.2f", - soxr_quality.precision, soxr_quality.phase_response, - soxr_quality.passband_end, soxr_quality.stopband_begin); + FmtDebug(soxr_domain, + "soxr precision={:0.0}, phase_response={:0.2}, " + "passband_end={:0.2}, stopband_begin={:0.2}", + soxr_quality.precision, soxr_quality.phase_response, + soxr_quality.passband_end, soxr_quality.stopband_begin); channels = af.channels; ratio = float(new_sample_rate) / float(af.sample_rate); - FormatDebug(soxr_domain, - "samplerate conversion ratio to %.2lf", - double(ratio)); + FmtDebug(soxr_domain, "samplerate conversion ratio to {:.2}", ratio); /* libsoxr works with floating point samples */ af.format = SampleFormat::FLOAT; diff --git a/src/storage/plugins/UdisksStorage.cxx b/src/storage/plugins/UdisksStorage.cxx index 844d1d5dc..773b1ff8a 100644 --- a/src/storage/plugins/UdisksStorage.cxx +++ b/src/storage/plugins/UdisksStorage.cxx @@ -22,6 +22,7 @@ #include "storage/StoragePlugin.hxx" #include "storage/StorageInterface.hxx" #include "storage/FileInfo.hxx" +#include "lib/fmt/ExceptionFormatter.hxx" #include "lib/dbus/Glue.hxx" #include "lib/dbus/AsyncRequest.hxx" #include "lib/dbus/Message.hxx" @@ -35,12 +36,15 @@ #include "event/Call.hxx" #include "event/InjectEvent.hxx" #include "fs/AllocatedPath.hxx" +#include "util/Domain.hxx" #include "util/StringCompare.hxx" #include "util/RuntimeError.hxx" #include "Log.hxx" #include +static constexpr Domain udisks_domain("udisks"); + class UdisksStorage final : public Storage { const std::string base_uri; const std::string id; @@ -87,9 +91,9 @@ public: try { UnmountWait(); } catch (...) { - FormatError(std::current_exception(), - "Failed to unmount '%s'", - base_uri.c_str()); + FmtError(udisks_domain, + "Failed to unmount '{}': {}", + base_uri, std::current_exception()); } }