wgtmac commented on code in PR #724: URL: https://github.com/apache/iceberg-cpp/pull/724#discussion_r3451181177
########## src/iceberg/logging/cerr_logger.h: ########## @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 + * + * http://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. + */ + +#pragma once + +/// \file iceberg/logging/cerr_logger.h +/// \brief Always-available std::cerr logging backend. + +#include <atomic> +#include <mutex> + +#include "iceberg/iceberg_export.h" +#include "iceberg/logging/log_level.h" +#include "iceberg/logging/logger.h" + +namespace iceberg { + +/// \brief Logger that writes one line per record to std::cerr. +/// +/// Line layout: `YYYY-MM-DDThh:mm:ss.mmmZ LEVEL [tid] file:line] message`. +/// The minimum level is held in a lock-free atomic; a mutex serializes the +/// whole-line write so concurrent records never interleave. Pure standard +/// library -- always compiled, regardless of ICEBERG_SPDLOG. +class ICEBERG_EXPORT CerrLogger : public Logger { Review Comment: CerrLogger is a formatting sink now, but it does not handle `kPatternProperty`. The public logger API says `pattern` is honored by CerrLogger. Please either implement `Initialize()` for the pattern here, or remove this promise until the later PR. A small test for `{"pattern", ...}` would help. ########## src/iceberg/logging/cerr_logger.cc: ########## @@ -0,0 +1,105 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 + * + * http://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 "iceberg/logging/cerr_logger.h" + +#include <chrono> +#include <cstdint> +#include <format> +#include <iostream> +#include <mutex> +#include <string> +#include <string_view> + +#if defined(_WIN32) +# include <windows.h> +#elif defined(__APPLE__) +# include <pthread.h> +#else +# include <unistd.h> + +# include <sys/syscall.h> +#endif + +namespace iceberg { + +namespace { + +/// \brief OS-native thread id, cached per thread to avoid a syscall per log. +/// +/// Matches the cross-process-correlatable id used by spdlog/glog (not the opaque +/// std::thread::id), and avoids the std::formatter<std::thread::id> (P2693) +/// minimum-toolchain dependency. +uint64_t OsThreadId() noexcept { + static thread_local uint64_t tid = []() -> uint64_t { +#if defined(_WIN32) + return static_cast<uint64_t>(::GetCurrentThreadId()); +#elif defined(__APPLE__) + uint64_t id = 0; + pthread_threadid_np(nullptr, &id); + return id; +#else + return static_cast<uint64_t>(::syscall(SYS_gettid)); +#endif + }(); + return tid; +} + +/// \brief Trailing path component of a source file path. +std::string_view Basename(std::string_view path) noexcept { + auto pos = path.find_last_of("/\\"); + return pos == std::string_view::npos ? path : path.substr(pos + 1); +} + +/// \brief Format a record into a single newline-terminated line. +std::string FormatLine(const LogMessage& message) { + auto now = + std::chrono::floor<std::chrono::milliseconds>(std::chrono::system_clock::now()); + return std::format("{:%Y-%m-%dT%H:%M:%S}Z {} [{}] {}:{}] {}\n", now, Review Comment: The format has `file:line]`, with a closing `]` but no opening `[`. This looks like a typo. Please use `[file:line]` or `file:line`, and add a test that checks this part of the layout. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected] --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
