Skip to content

Commit 2df59da

Browse files
authored
Add API for context-less logging (#106)
- It is sometimes useful to log messages to the Redis logs from code that does not take a context object. The Redis modules API allows for this by specifying a NULL context, but the Rust wrapper previously prevented taking advantage of this ability. - Added a log_* method for each supported log level to the context object. - Used `strum` to make translating the LogLevel enum to a string more efficient. This now uses static strings generated at compile-time, rather than allocating and formatting them dynamically at runtime on each log call. - Replaced outdated `#[macro_use] statements with `use`. Leaving the `#[macro_use] extern crate redis_module` as-it-is in the examples code, since it makes more sense to pull in all macros from the redis_module crate rather than trying to pick-and-choose.
1 parent 85da232 commit 2df59da

File tree

5 files changed

+61
-10
lines changed

5 files changed

+61
-10
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ bitflags = "1.2"
4646
libc = "0.2"
4747
enum-primitive-derive = "^0.1"
4848
num-traits = "^0.2"
49+
strum_macros = "0.19"
4950
#failure = "0.1"
5051

5152
[build-dependencies]

src/context/mod.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,25 @@ impl Context {
3434
}
3535

3636
pub fn log(&self, level: LogLevel, message: &str) {
37-
let level = CString::new(format!("{:?}", level).to_lowercase()).unwrap();
38-
let fmt = CString::new(message).unwrap();
39-
unsafe { raw::RedisModule_Log.unwrap()(self.ctx, level.as_ptr(), fmt.as_ptr()) }
37+
crate::logging::log_internal(self.ctx, level, message);
4038
}
4139

4240
pub fn log_debug(&self, message: &str) {
41+
self.log(LogLevel::Debug, message);
42+
}
43+
44+
pub fn log_notice(&self, message: &str) {
4345
self.log(LogLevel::Notice, message);
4446
}
4547

48+
pub fn log_verbose(&self, message: &str) {
49+
self.log(LogLevel::Verbose, message);
50+
}
51+
52+
pub fn log_warning(&self, message: &str) {
53+
self.log(LogLevel::Warning, message);
54+
}
55+
4656
pub fn auto_memory(&self) {
4757
unsafe {
4858
raw::RedisModule_AutoMemory.unwrap()(self.ctx);

src/lib.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,8 @@
22

33
use std::os::raw::c_char;
44
use std::str::Utf8Error;
5+
use strum_macros::AsRefStr;
56

6-
#[macro_use]
7-
extern crate bitflags;
8-
#[macro_use]
9-
extern crate enum_primitive_derive;
107
extern crate num_traits;
118

129
use libc::size_t;
@@ -20,10 +17,10 @@ mod redismodule;
2017
pub mod redisraw;
2118
pub mod redisvalue;
2219

23-
#[macro_use]
24-
mod macros;
2520
mod context;
2621
mod key;
22+
pub mod logging;
23+
mod macros;
2724

2825
#[cfg(feature = "experimental-api")]
2926
pub use crate::context::thread_safe::ThreadSafeContext;
@@ -39,7 +36,8 @@ pub use crate::redismodule::*;
3936
static ALLOC: crate::alloc::RedisAlloc = crate::alloc::RedisAlloc;
4037

4138
/// `LogLevel` is a level of logging to be specified with a Redis log directive.
42-
#[derive(Clone, Copy, Debug)]
39+
#[derive(Clone, Copy, Debug, AsRefStr)]
40+
#[strum(serialize_all = "snake_case")]
4341
pub enum LogLevel {
4442
Debug,
4543
Notice,

src/logging.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
use crate::LogLevel;
2+
use crate::raw;
3+
use std::ffi::CString;
4+
use std::ptr;
5+
6+
pub(crate) fn log_internal(ctx: *mut raw::RedisModuleCtx, level: LogLevel, message: &str) {
7+
if cfg!(feature = "test") {
8+
return;
9+
}
10+
let level = CString::new(level.as_ref()).unwrap();
11+
let fmt = CString::new(message).unwrap();
12+
unsafe { raw::RedisModule_Log.unwrap()(ctx, level.as_ptr(), fmt.as_ptr()) }
13+
}
14+
15+
/// Log a message to the Redis log with the given log level, without
16+
/// requiring a context. This prevents Redis from including the module
17+
/// name in the logged message.
18+
pub fn log(level: LogLevel, message: &str) {
19+
log_internal(ptr::null_mut(), level, message);
20+
}
21+
22+
/// Log a message to the Redis log with DEBUG log level.
23+
pub fn log_debug(message: &str) {
24+
log(LogLevel::Debug, message);
25+
}
26+
27+
/// Log a message to the Redis log with NOTICE log level.
28+
pub fn log_notice(message: &str) {
29+
log(LogLevel::Debug, message);
30+
}
31+
32+
/// Log a message to the Redis log with VERBOSE log level.
33+
pub fn log_verbose(message: &str) {
34+
log(LogLevel::Debug, message);
35+
}
36+
37+
/// Log a message to the Redis log with WARNING log level.
38+
pub fn log_warning(message: &str) {
39+
log(LogLevel::Debug, message);
40+
}

src/raw.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ extern crate enum_primitive_derive;
88
extern crate libc;
99
extern crate num_traits;
1010

11+
use bitflags::bitflags;
12+
use enum_primitive_derive::Primitive;
1113
use libc::size_t;
1214
use num_traits::FromPrimitive;
1315
use std::ffi::CString;

0 commit comments

Comments
 (0)