the log wrapper in C/C++ accepts formats
This commit is contained in:
75
pam-module/include/rust_backend_logging_cpp.h
Normal file
75
pam-module/include/rust_backend_logging_cpp.h
Normal file
@@ -0,0 +1,75 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// C++ stream-style wrappers for Rust logging FFI
|
||||
|
||||
#pragma once
|
||||
|
||||
// This header expects `rust_backend_ffi.h` to have been included first
|
||||
// so that `RustLogLevel` and `rust_log_event_with_level` are available.
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <ostream>
|
||||
|
||||
class RustLogStream {
|
||||
public:
|
||||
explicit RustLogStream(RustLogLevel level) noexcept : level_(level) {}
|
||||
|
||||
// Generic stream insertion
|
||||
template<typename T>
|
||||
RustLogStream& operator<<(const T& v) {
|
||||
try {
|
||||
oss_ << v;
|
||||
} catch (...) {
|
||||
// swallow; avoid exceptions crossing FFI
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Support manipulators like std::endl
|
||||
RustLogStream& operator<<(std::ostream& (*manip)(std::ostream&)) {
|
||||
try {
|
||||
manip(oss_);
|
||||
} catch (...) {
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Destructor emits buffered message
|
||||
~RustLogStream() noexcept {
|
||||
try {
|
||||
const std::string s = oss_.str();
|
||||
if (!s.empty()) {
|
||||
rust_log_event_with_level(s.c_str(), level_);
|
||||
}
|
||||
} catch (...) {
|
||||
// never throw
|
||||
}
|
||||
}
|
||||
|
||||
// Non-copyable
|
||||
RustLogStream(const RustLogStream&) = delete;
|
||||
RustLogStream& operator=(const RustLogStream&) = delete;
|
||||
|
||||
// Movable
|
||||
RustLogStream(RustLogStream&&) = default;
|
||||
RustLogStream& operator=(RustLogStream&&) = default;
|
||||
|
||||
private:
|
||||
RustLogLevel level_;
|
||||
std::ostringstream oss_;
|
||||
};
|
||||
|
||||
// Factories and macros
|
||||
inline RustLogStream rust_log_info_stream() { return RustLogStream(RUST_LOG_LEVEL_INFO); }
|
||||
inline RustLogStream rust_log_warn_stream() { return RustLogStream(RUST_LOG_LEVEL_WARN); }
|
||||
inline RustLogStream rust_log_error_stream() { return RustLogStream(RUST_LOG_LEVEL_ERROR); }
|
||||
inline RustLogStream rust_log_debug_stream() { return RustLogStream(RUST_LOG_LEVEL_DEBUG); }
|
||||
inline RustLogStream rust_log_trace_stream() { return RustLogStream(RUST_LOG_LEVEL_TRACE); }
|
||||
inline RustLogStream rust_log_fatal_stream() { return RustLogStream(RUST_LOG_LEVEL_FATAL); }
|
||||
|
||||
#define RUST_COUT() rust_log_info_stream()
|
||||
#define RUST_CERR() rust_log_error_stream()
|
||||
#define RUST_CDEBUG() rust_log_debug_stream()
|
||||
|
||||
// Usage example:
|
||||
// RUST_COUT() << "User=" << user << " logged in" << std::endl;
|
||||
Reference in New Issue
Block a user