Fixes #350.
static void
initialize(Context& ctx, const char* const* argv, bool masquerading_as_compiler)
{
- LOG("=== CCACHE {} STARTED =========================================",
- CCACHE_VERSION);
-
- LOG("Configuration file: {}", ctx.config.config_path());
- LOG("System configuration file: {}", ctx.config.system_config_path());
-
- if (!ctx.config.log_file().empty() || ctx.config.debug()) {
- ctx.config.visit_items([&ctx](const std::string& key,
- const std::string& value,
- const std::string& origin) {
+ if (util::logging::enabled()) {
+ util::logging::BulkLogger logger;
+
+ BULK_LOG(logger,
+ "=== CCACHE {} STARTED =========================================",
+ CCACHE_VERSION);
+ BULK_LOG(logger, "Configuration file: {}", ctx.config.config_path());
+ BULK_LOG(
+ logger, "System configuration file: {}", ctx.config.system_config_path());
+
+ ctx.config.visit_items([&](const std::string& key,
+ const std::string& value,
+ const std::string& origin) {
const auto& log_value =
key == "remote_storage"
? ctx.storage.get_remote_storage_config_for_logging()
: value;
- BULK_LOG("Config: ({}) {} = {}", origin, key, log_value);
+ BULK_LOG(logger, "Config: ({}) {} = {}", origin, key, log_value);
});
- }
- LOG("Command line: {}", util::format_argv_for_logging(argv));
- LOG("Hostname: {}", util::get_hostname());
- LOG("Working directory: {}", ctx.actual_cwd);
- if (ctx.apparent_cwd != ctx.actual_cwd) {
- LOG("Apparent working directory: {}", ctx.apparent_cwd);
+ BULK_LOG(logger, "Command line: {}", util::format_argv_for_logging(argv));
+ BULK_LOG(logger, "Hostname: {}", util::get_hostname());
+ BULK_LOG(logger, "Working directory: {}", ctx.actual_cwd);
+ if (ctx.apparent_cwd != ctx.actual_cwd) {
+ BULK_LOG(logger, "Apparent working directory: {}", ctx.apparent_cwd);
+ }
}
ctx.storage.initialize();
{
static char prefix[200];
- if (!bulk) {
+ if (!bulk || prefix[0] == '\0') {
char timestamp[100];
auto now = util::TimePoint::now();
auto tm = util::localtime(now);
static_cast<int>(getpid()));
}
- if (logfile
- && (fputs(prefix, *logfile) == EOF
- || fwrite(message.data(), message.length(), 1, *logfile) != 1
- || fputc('\n', *logfile) == EOF
- || (!bulk && fflush(*logfile) == EOF))) {
- print_fatal_error_and_exit();
+ if (logfile) {
+ util::FileLock lock(fileno(*logfile));
+ if (!bulk) {
+ std::ignore = lock.acquire(); // Garbled logs are better than no logs
+ }
+ if (fputs(prefix, *logfile) == EOF
+ || fwrite(message.data(), message.length(), 1, *logfile) != 1
+ || fputc('\n', *logfile) == EOF || fflush(*logfile) == EOF) {
+ print_fatal_error_and_exit();
+ }
}
#ifdef HAVE_SYSLOG
if (use_syslog) {
do_log(message, false);
}
-void
-bulk_log(std::string_view message)
-{
- if (!enabled()) {
- return;
- }
- do_log(message, true);
-}
-
void
dump_log(const fs::path& path)
{
}
}
+BulkLogger::BulkLogger() : m_file_lock(logfile ? fileno(*logfile) : -1)
+{
+ if (logfile) {
+ std::ignore = m_file_lock.acquire(); // Garbled logs are better than no logs
+ }
+}
+
+void
+BulkLogger::log(std::string_view message)
+{
+ if (!enabled()) {
+ return;
+ }
+ do_log(message, true);
+}
+
} // namespace util::logging
#pragma once
+#include <ccache/util/filelock.hpp>
+
#include <fmt/core.h>
#include <fmt/format.h>
// Log a message (plus a newline character) described by a format string with at
// least one placeholder without flushing and with a reused timestamp. `format`
// is checked at compile time.
-#define BULK_LOG(format_, ...) \
- do { \
- if (util::logging::enabled()) { \
- util::logging::bulk_log(fmt::format(FMT_STRING(format_), __VA_ARGS__)); \
- } \
- } while (false)
+#define BULK_LOG(logger_, format_, ...) \
+ logger_.log(fmt::format(FMT_STRING(format_), __VA_ARGS__));
namespace util::logging {
// Log `message` (plus a newline character).
void log(std::string_view message);
-// Log `message` (plus a newline character) without flushing and with a reused
-// timestamp.
-void bulk_log(std::string_view message);
-
// Write the current log memory buffer to `path`.
void dump_log(const std::filesystem::path& path);
+class BulkLogger
+{
+public:
+ BulkLogger();
+
+ // Log `message` (plus a newline character) with a reused timestamp.
+ void log(std::string_view message);
+
+private:
+ util::FileLock m_file_lock;
+};
+
} // namespace util::logging