From 7ac30b7624de4cd3c028e7b8c524c1fcb0304c83 Mon Sep 17 00:00:00 2001 From: Guogang Li Date: Thu, 29 May 2025 19:28:46 -0700 Subject: [PATCH] Add OS Log sink for iOS PiperOrigin-RevId: 764981349 --- connections/c/nc.cc | 1 + internal/platform/implementation/apple/BUILD | 17 ++++++ .../apple/nearby_logger_writer.h | 6 ++ .../apple/nearby_logger_writer.mm | 11 ++++ .../implementation/apple/os_log_sink.h | 41 +++++++++++++ .../implementation/apple/os_log_sink.mm | 57 +++++++++++++++++++ 6 files changed, 133 insertions(+) create mode 100644 internal/platform/implementation/apple/os_log_sink.h create mode 100644 internal/platform/implementation/apple/os_log_sink.mm diff --git a/connections/c/nc.cc b/connections/c/nc.cc index 882928b2..2fa93aff 100644 --- a/connections/c/nc.cc +++ b/connections/c/nc.cc @@ -229,6 +229,7 @@ NC_INSTANCE NcCreateService() { absl::SetGlobalVLogLevel(1); #endif // DEBUG ::nearby::apple::EnableNearbyLoggerWriter(); + ::nearby::apple::EnableOsLog("com.google.nearby.connections"); #endif // TARGET_OS_IOS #if defined(NC_IOS_SDK) diff --git a/internal/platform/implementation/apple/BUILD b/internal/platform/implementation/apple/BUILD index 3d5f96fd..db511888 100644 --- a/internal/platform/implementation/apple/BUILD +++ b/internal/platform/implementation/apple/BUILD @@ -164,6 +164,22 @@ objc_library( ], ) +objc_library( + name = "os_log_sink", + srcs = [ + "os_log_sink.mm", + ], + hdrs = [ + "os_log_sink.h", + ], + # Prevent Objective-C++ headers from being pulled into swift. + aspect_hints = ["//tools/build_defs/swift:no_module"], + deps = [ + "//internal/platform:logging", + "@com_google_absl//absl/strings", + ], +) + objc_library( name = "logger_writer", srcs = [ @@ -175,6 +191,7 @@ objc_library( # Prevent Objective-C++ headers from being pulled into swift. aspect_hints = ["//tools/build_defs/swift:no_module"], deps = [ + ":os_log_sink", "//internal/platform:logging", "//third_party/objective_c/google_toolbox_for_mac:GTM_Logger", ], diff --git a/internal/platform/implementation/apple/nearby_logger_writer.h b/internal/platform/implementation/apple/nearby_logger_writer.h index 80ad9c40..6a7f55a5 100644 --- a/internal/platform/implementation/apple/nearby_logger_writer.h +++ b/internal/platform/implementation/apple/nearby_logger_writer.h @@ -15,6 +15,8 @@ #ifndef PLATFORM_IMPL_APPLE_NEARBY_LOGGER_WRITER_H_ #define PLATFORM_IMPL_APPLE_NEARBY_LOGGER_WRITER_H_ +#include + namespace nearby { namespace apple { @@ -23,6 +25,10 @@ namespace apple { // connections. void EnableNearbyLoggerWriter(); +// Enables the OS log output as the given subsystem. The method should be called +// once during the application lifetime. +void EnableOsLog(const std::string& subsystem); + } // namespace apple } // namespace nearby diff --git a/internal/platform/implementation/apple/nearby_logger_writer.mm b/internal/platform/implementation/apple/nearby_logger_writer.mm index 26e3aaa1..f3ce1d9e 100644 --- a/internal/platform/implementation/apple/nearby_logger_writer.mm +++ b/internal/platform/implementation/apple/nearby_logger_writer.mm @@ -17,6 +17,7 @@ #include #include +#include "internal/platform/implementation/apple/os_log_sink.h" #include "internal/platform/logging.h" #import "GoogleToolboxForMac/GTMLogger.h" @@ -162,6 +163,14 @@ NS_ASSUME_NONNULL_END namespace nearby { namespace apple { +namespace { + +OsLogSink *GetOsLogSink(const std::string &subsystem) { + static OsLogSink *sink = new OsLogSink(subsystem); + return sink; +} + +} // namespace void EnableNearbyLoggerWriter() { NSMutableArray *tupleArray = [[NSMutableArray alloc] init]; @@ -171,5 +180,7 @@ void EnableNearbyLoggerWriter() { filter:nil]; } +void EnableOsLog(const std::string &subsystem) { absl::AddLogSink(GetOsLogSink(subsystem)); } + } // namespace apple } // namespace nearby diff --git a/internal/platform/implementation/apple/os_log_sink.h b/internal/platform/implementation/apple/os_log_sink.h new file mode 100644 index 00000000..b76e4309 --- /dev/null +++ b/internal/platform/implementation/apple/os_log_sink.h @@ -0,0 +1,41 @@ +// Copyright 2025 Google LLC +// +// 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. + +#ifndef PLATFORM_IMPL_APPLE_OS_LOG_SINK_H_ +#define PLATFORM_IMPL_APPLE_OS_LOG_SINK_H_ + +#include + +#include "internal/platform/logging.h" + +namespace nearby { +namespace apple { + +// OsLogSink is a LogSink that sends logs to the OS log. +class OsLogSink : public absl::LogSink { + public: + explicit OsLogSink(const std::string& subsystem); + ~OsLogSink() override = default; + + // Sends the log entry to the OS log. + void Send(const absl::LogEntry& entry) override; + + private: + os_log_t log_; +}; + +} // namespace apple +} // namespace nearby + +#endif // PLATFORM_IMPL_APPLE_OS_LOG_SINK_H_ diff --git a/internal/platform/implementation/apple/os_log_sink.mm b/internal/platform/implementation/apple/os_log_sink.mm new file mode 100644 index 00000000..d1232d78 --- /dev/null +++ b/internal/platform/implementation/apple/os_log_sink.mm @@ -0,0 +1,57 @@ +// Copyright 2025 Google LLC +// +// 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 "internal/platform/implementation/apple/os_log_sink.h" + +#include + +#include "absl/strings/str_cat.h" +#include "internal/platform/logging.h" + +namespace nearby { +namespace apple { + +OsLogSink::OsLogSink(const std::string& subsystem) + : log_(os_log_create(subsystem.c_str(), "default")) {} + +void OsLogSink::Send(const absl::LogEntry& entry) { + os_log_type_t type = OS_LOG_TYPE_DEFAULT; + switch (entry.log_severity()) { + case absl::LogSeverity::kInfo: + type = OS_LOG_TYPE_INFO; + break; + case absl::LogSeverity::kWarning: + type = OS_LOG_TYPE_DEFAULT; // OSLog doesn't have a distinct 'Warning' level + break; + case absl::LogSeverity::kError: + type = OS_LOG_TYPE_ERROR; + break; + case absl::LogSeverity::kFatal: + type = OS_LOG_TYPE_FAULT; + break; + } + + if (entry.verbosity() == 1) { + type = OS_LOG_TYPE_DEBUG; + } + + // Format and send the log message to OSLog. + std::string message = absl::StrCat("[", entry.source_basename(), ":", entry.source_line(), "] ", + entry.text_message()); + + os_log_with_type(log_, type, "%s", message.c_str()); +} + +} // namespace apple +} // namespace nearby