chromium/third_party/abseil-cpp/absl/log/internal/log_sink_set.cc

//
// Copyright 2022 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "absl/log/internal/log_sink_set.h"

#ifndef ABSL_HAVE_THREAD_LOCAL
#include <pthread.h>
#endif

#ifdef __ANDROID__
#include <android/log.h>
#endif

#ifdef _WIN32
#include <windows.h>
#endif

#include <algorithm>
#include <vector>

#include "absl/base/attributes.h"
#include "absl/base/call_once.h"
#include "absl/base/config.h"
#include "absl/base/internal/raw_logging.h"
#include "absl/base/log_severity.h"
#include "absl/base/no_destructor.h"
#include "absl/base/thread_annotations.h"
#include "absl/cleanup/cleanup.h"
#include "absl/log/globals.h"
#include "absl/log/internal/config.h"
#include "absl/log/internal/globals.h"
#include "absl/log/log_entry.h"
#include "absl/log/log_sink.h"
#include "absl/strings/string_view.h"
#include "absl/synchronization/mutex.h"
#include "absl/types/span.h"

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace log_internal {
namespace {

// Returns a mutable reference to a thread-local variable that should be true if
// a globally-registered `LogSink`'s `Send()` is currently being invoked on this
// thread.
bool& ThreadIsLoggingStatus() {}

class StderrLogSink final : public LogSink {};

#if defined(__ANDROID__)
class AndroidLogSink final : public LogSink {
 public:
  ~AndroidLogSink() override = default;

  void Send(const absl::LogEntry& entry) override {
    const int level = AndroidLogLevel(entry);
    const char* const tag = GetAndroidNativeTag();
    __android_log_write(level, tag,
                        entry.text_message_with_prefix_and_newline_c_str());
    if (entry.log_severity() == absl::LogSeverity::kFatal)
      __android_log_write(ANDROID_LOG_FATAL, tag, "terminating.\n");
  }

 private:
  static int AndroidLogLevel(const absl::LogEntry& entry) {
    switch (entry.log_severity()) {
      case absl::LogSeverity::kFatal:
        return ANDROID_LOG_FATAL;
      case absl::LogSeverity::kError:
        return ANDROID_LOG_ERROR;
      case absl::LogSeverity::kWarning:
        return ANDROID_LOG_WARN;
      default:
        if (entry.verbosity() >= 2) return ANDROID_LOG_VERBOSE;
        if (entry.verbosity() == 1) return ANDROID_LOG_DEBUG;
        return ANDROID_LOG_INFO;
    }
  }
};
#endif  // !defined(__ANDROID__)

#if defined(_WIN32)
class WindowsDebuggerLogSink final : public LogSink {
 public:
  ~WindowsDebuggerLogSink() override = default;

  void Send(const absl::LogEntry& entry) override {
    if (entry.log_severity() < absl::StderrThreshold() &&
        absl::log_internal::IsInitialized()) {
      return;
    }
    ::OutputDebugStringA(entry.text_message_with_prefix_and_newline_c_str());
  }
};
#endif  // !defined(_WIN32)

class GlobalLogSinkSet final {};

// Returns reference to the global LogSinks set.
GlobalLogSinkSet& GlobalSinks() {}

}  // namespace

bool ThreadIsLoggingToLogSink() {}

void LogToSinks(const absl::LogEntry& entry,
                absl::Span<absl::LogSink*> extra_sinks, bool extra_sinks_only) {}

void AddLogSink(absl::LogSink* sink) {}

void RemoveLogSink(absl::LogSink* sink) {}

void FlushLogSinks() {}

}  // namespace log_internal
ABSL_NAMESPACE_END
}  // namespace absl