Skip to content

Commit bdad94e

Browse files
committed
New logging API
1 parent 3ffe3a4 commit bdad94e

File tree

4 files changed

+52
-98
lines changed

4 files changed

+52
-98
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ keywords = ["couchbase"]
1111
categories = ["database"]
1212

1313
[dependencies]
14+
bitflags = "2.9.0"
1415
enum_primitive = "0.1.1"
1516

1617
[dev-dependencies]

src/error.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ use crate::c_api::{
2121
CBLError, CBLErrorDomain, CBLError_Message, FLError, kCBLDomain, kCBLFleeceDomain,
2222
kCBLNetworkDomain, kCBLPOSIXDomain, kCBLSQLiteDomain, kCBLWebSocketDomain,
2323
};
24-
use crate::error;
2524
use enum_primitive::FromPrimitive;
2625
use std::fmt;
2726

@@ -258,10 +257,7 @@ impl Error {
258257
unsafe {
259258
CBLError_Message(&self.as_cbl_error())
260259
.to_string()
261-
.unwrap_or_else(|| {
262-
error!("Generating the error message for error ({:?}) and internal info ({:?}) failed", self.code, self.internal_info);
263-
"Unknown error".to_string()
264-
})
260+
.unwrap_or_default()
265261
}
266262
}
267263
}

src/logging.rs

Lines changed: 49 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,14 @@
1515
// limitations under the License.
1616
//
1717

18+
use bitflags::bitflags;
1819
use crate::c_api::{
19-
CBLLogDomain, CBLLogLevel, CBLLog_SetCallback, CBLLog_SetCallbackLevel, CBLLog_SetConsoleLevel,
20-
CBL_Log, FLString,
20+
kCBLLogDomainMaskAll, kCBLLogDomainMaskDatabase, kCBLLogDomainMaskNetwork,
21+
kCBLLogDomainMaskQuery, kCBLLogDomainMaskReplicator, CBLConsoleLogSink, CBLCustomLogSink,
22+
CBLLogDomain, CBLLogLevel, CBLLogSinks_SetConsole, CBLLogSinks_SetCustom, FLString,
2123
};
2224

2325
use enum_primitive::FromPrimitive;
24-
use std::fmt;
25-
use std::ffi::CString;
2626

2727
enum_from_primitive! {
2828
/** Logging domains: subsystems that generate log messages. */
@@ -50,96 +50,65 @@ enum_from_primitive! {
5050
}
5151
}
5252

53-
pub type LogCallback = Option<fn(Domain, Level, &str)>;
53+
bitflags! {
54+
/** A bitmask representing a set of logging domains.
55+
*
56+
* Use this bitmask to specify one or more logging domains by combining the
57+
* constants with the bitwise OR operator (`|`). This is helpful for enabling
58+
* or filtering logs for specific domains. */
59+
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
60+
pub struct DomainMask: u32 {
61+
const DATABASE = kCBLLogDomainMaskDatabase;
62+
const QUERY = kCBLLogDomainMaskQuery;
63+
const REPLICATOR = kCBLLogDomainMaskReplicator;
64+
const NETWORK = kCBLLogDomainMaskNetwork;
65+
const ALL = kCBLLogDomainMaskAll;
66+
}
67+
}
5468

55-
/** Sets the detail level of console logging.
56-
Only messages whose level is ≥ the given level will be logged to the console.
57-
Default value is Info. */
58-
pub fn set_console_level(level: Level) {
59-
unsafe { CBLLog_SetConsoleLevel(level as u8) }
69+
/** Console log sink configuration for logging to the cosole. */
70+
pub struct ConsoleLogSink {
71+
// The minimum level of message to write (Required).
72+
pub level: Level,
73+
// Bitmask for enabled log domains.
74+
pub domains: DomainMask,
6075
}
6176

62-
/** Sets the detail level of logging to the registered callback (if any.)
63-
Only messages whose level is ≥ the given level will be logged to the callback.
64-
Default value is Info. */
65-
pub fn set_callback_level(level: Level) {
66-
unsafe { CBLLog_SetCallbackLevel(level as u8) }
77+
pub type LogCallback = Option<fn(Domain, Level, &str)>;
78+
79+
/** Custom log sink configuration for logging to a user-defined callback. */
80+
pub struct CustomLogSink {
81+
// The minimum level of message to write (Required).
82+
pub level: Level,
83+
// Custom log callback (Required).
84+
pub callback: LogCallback,
85+
// Bitmask for enabled log domains.
86+
pub domains: DomainMask,
6787
}
6888

69-
/** Registers a function that will receive log messages. */
70-
pub fn set_callback(callback: LogCallback) {
89+
/** Set the console log sink. To disable the console log sink, set the log level to None. */
90+
pub fn set_console_log_sink(log_sink: ConsoleLogSink) {
7191
unsafe {
72-
LOG_CALLBACK = callback;
73-
if callback.is_some() {
74-
CBLLog_SetCallback(Some(invoke_log_callback));
75-
} else {
76-
CBLLog_SetCallback(None);
77-
}
92+
CBLLogSinks_SetConsole(CBLConsoleLogSink {
93+
level: log_sink.level as u8,
94+
domains: log_sink.domains.bits() as u16,
95+
})
7896
}
7997
}
8098

81-
/** Writes a log message. */
82-
pub fn write(domain: Domain, level: Level, message: &str) {
99+
/** Set the custom log sink. To disable the custom log sink, set the log level to None. */
100+
pub fn set_custom_log_sink(log_sink: CustomLogSink) {
83101
unsafe {
84-
let cstr = CString::new(message).unwrap();
85-
CBL_Log(domain as u8, level as u8, cstr.as_ptr());
102+
LOG_CALLBACK = log_sink.callback;
86103

87-
// CBL_Log doesn't invoke the callback, so do it manually:
88-
if let Some(callback) = LOG_CALLBACK {
89-
//if CBLLog_WillLogToConsole(domain as u8, level as u8) {
90-
callback(domain, level, message);
91-
//}
92-
}
104+
CBLLogSinks_SetCustom(CBLCustomLogSink {
105+
level: log_sink.level as u8,
106+
callback: Some(invoke_log_callback),
107+
domains: log_sink.domains.bits() as u16,
108+
})
93109
}
94110
}
95111

96-
/** Writes a log message using the given format arguments. */
97-
pub fn write_args(domain: Domain, level: Level, args: fmt::Arguments) {
98-
write(domain, level, &format!("{:?}", args));
99-
}
100-
101-
//////// LOGGING MACROS:
102-
103-
/// A macro that writes a formatted Error-level log message.
104-
#[macro_export]
105-
macro_rules! error {
106-
($($arg:tt)*) => ($crate::logging::write_args(
107-
$crate::logging::Domain::Database, $crate::logging::Level::Error,
108-
format_args!($($arg)*)));
109-
}
110-
111-
/// A macro that writes a formatted Warning-level log message.
112-
#[macro_export]
113-
macro_rules! warn {
114-
($($arg:tt)*) => ($crate::logging::write_args(
115-
$crate::logging::Domain::Database, $crate::logging::Level::Warning,
116-
format_args!($($arg)*)));
117-
}
118-
119-
/// A macro that writes a formatted Info-level log message.
120-
#[macro_export]
121-
macro_rules! info {
122-
($($arg:tt)*) => ($crate::logging::write_args(
123-
$crate::logging::Domain::Database, $crate::logging::Level::Info,
124-
format_args!($($arg)*)));
125-
}
126-
127-
/// A macro that writes a formatted Verbose-level log message.
128-
#[macro_export]
129-
macro_rules! verbose {
130-
($($arg:tt)*) => ($crate::logging::write_args(
131-
$crate::logging::Domain::Database, $crate::logging::Level::Verbose,
132-
format_args!($($arg)*)));
133-
}
134-
135-
/// A macro that writes a formatted Debug-level log message.
136-
#[macro_export]
137-
macro_rules! debug {
138-
($($arg:tt)*) => ($crate::logging::write_args(
139-
$crate::logging::Domain::Database, $crate::logging::Level::Debug,
140-
format_args!($($arg)*)));
141-
}
142-
143112
//////// INTERNALS:
144113

145114
static mut LOG_CALLBACK: LogCallback = None;

src/replicator.rs

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ use crate::{
4747
};
4848
#[cfg(feature = "enterprise")]
4949
use crate::{
50-
CouchbaseLiteError, ErrorCode, error,
50+
CouchbaseLiteError, ErrorCode,
5151
c_api::{
5252
CBLEndpoint_CreateWithLocalDB, FLSlice, FLSliceResult, FLSliceResult_New, FLSlice_Copy,
5353
FLStringResult,
@@ -395,14 +395,12 @@ pub extern "C" fn c_default_collection_property_encryptor(
395395
Err(err) => {
396396
match err {
397397
EncryptionError::Temporary => {
398-
error!("Encryption callback returned with transient error");
399398
error = Error {
400399
code: ErrorCode::WebSocket(503),
401400
internal_info: None,
402401
};
403402
}
404403
EncryptionError::Permanent => {
405-
error!("Encryption callback returned with non transient error");
406404
error = Error::cbl_error(CouchbaseLiteError::Crypto);
407405
}
408406
}
@@ -411,7 +409,6 @@ pub extern "C" fn c_default_collection_property_encryptor(
411409
}
412410
});
413411
} else {
414-
error!("Encryption input is None");
415412
error = Error::cbl_error(CouchbaseLiteError::Crypto);
416413
}
417414

@@ -478,14 +475,12 @@ pub extern "C" fn c_collection_property_encryptor(
478475
Err(err) => {
479476
match err {
480477
EncryptionError::Temporary => {
481-
error!("Encryption callback returned with transient error");
482478
error = Error {
483479
code: ErrorCode::WebSocket(503),
484480
internal_info: None,
485481
};
486482
}
487483
EncryptionError::Permanent => {
488-
error!("Encryption callback returned with non transient error");
489484
error = Error::cbl_error(CouchbaseLiteError::Crypto);
490485
}
491486
}
@@ -494,7 +489,6 @@ pub extern "C" fn c_collection_property_encryptor(
494489
}
495490
});
496491
} else {
497-
error!("Encryption input is None");
498492
error = Error::cbl_error(CouchbaseLiteError::Crypto);
499493
}
500494

@@ -556,14 +550,12 @@ pub extern "C" fn c_default_collection_property_decryptor(
556550
Err(err) => {
557551
match err {
558552
EncryptionError::Temporary => {
559-
error!("Decryption callback returned with transient error");
560553
error = Error {
561554
code: ErrorCode::WebSocket(503),
562555
internal_info: None,
563556
};
564557
}
565558
EncryptionError::Permanent => {
566-
error!("Decryption callback returned with non transient error");
567559
error = Error::cbl_error(CouchbaseLiteError::Crypto);
568560
}
569561
}
@@ -572,7 +564,6 @@ pub extern "C" fn c_default_collection_property_decryptor(
572564
}
573565
});
574566
} else {
575-
error!("Decryption input is None");
576567
error = Error::cbl_error(CouchbaseLiteError::Crypto);
577568
}
578569

@@ -639,14 +630,12 @@ pub extern "C" fn c_collection_property_decryptor(
639630
Err(err) => {
640631
match err {
641632
EncryptionError::Temporary => {
642-
error!("Decryption callback returned with transient error");
643633
error = Error {
644634
code: ErrorCode::WebSocket(503),
645635
internal_info: None,
646636
};
647637
}
648638
EncryptionError::Permanent => {
649-
error!("Decryption callback returned with non transient error");
650639
error = Error::cbl_error(CouchbaseLiteError::Crypto);
651640
}
652641
}
@@ -655,7 +644,6 @@ pub extern "C" fn c_collection_property_decryptor(
655644
}
656645
});
657646
} else {
658-
error!("Decryption input is None");
659647
error = Error::cbl_error(CouchbaseLiteError::Crypto);
660648
}
661649

0 commit comments

Comments
 (0)