blob: e5225220e84354a30816269e8e2a2d5df745b8e4 [file] [log] [blame]
// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "fuchsia_logger.h"
#include <lib/syslog/global.h>
#include <zircon/status.h>
// TODO (see note on fuchsia_logger.h)
namespace syslog {
namespace internal {
LogMessage::LogMessage(fx_log_severity_t severity, const char* file, int line, const char* tag,
zx_status_t status, const char* condition)
: severity_(severity), file_(file), line_(line), tag_(tag), status_(status) {
if (condition)
stream_ << "Check failed: " << condition << ": ";
}
void FxLogFatal() { abort(); }
LogMessage::~LogMessage() {
fx_logger_t* logger = fx_log_get_logger();
if (logger) {
if (status_ != INT32_MAX) {
stream_ << ": " << status_ << " (" << zx_status_get_string(status_) << ")";
}
fx_logger_log_with_source(logger, severity_, tag_, file_, line_, stream_.str().c_str());
} else if (severity_ == FX_LOG_FATAL) {
// FX_LOG_FATAL should abort regardless of whether a logger exists
FxLogFatal();
}
}
// Note that this implementation allows a data race on counter_, but
// we consider that harmless because, as specified by the comments on
// FX_LOGS_FIRST_N, we allow for the possibility that the message might get
// logged more than |n| times if a single callsite of that macro is invoked by
// multiple threads.
bool LogFirstNState::ShouldLog(int n) {
const int32_t counter_value = counter_.load(std::memory_order_relaxed);
if (counter_value < n) {
counter_.store(counter_value + 1, std::memory_order_relaxed);
return true;
}
return false;
}
} // namespace internal
} // namespace syslog