| // 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 |