5
5
use std:: ffi:: CStr ;
6
6
use std:: fmt;
7
7
8
- use crate :: ffi:: { self , ngx_err_t, ngx_log_error_core, ngx_log_t, ngx_uint_t} ;
8
+ use crate :: ffi:: { self , ngx_conf_log_error, ngx_err_t, ngx_log_error_core, ngx_log_t, ngx_uint_t} ;
9
+
10
+ /// Checks if the message of the specified level should be logged with this logger.
11
+ ///
12
+ /// # Safety
13
+ ///
14
+ /// The function should be called with a valid target pointer.
15
+ #[ inline]
16
+ pub unsafe fn should_log < T : LogTarget > ( target : * const T , level : Level ) -> bool {
17
+ debug_assert ! ( !target. is_null( ) ) ;
18
+ let log = ( * target) . get_log ( ) ;
19
+ if log. is_null ( ) {
20
+ return false ;
21
+ }
22
+ ( * log) . log_level >= level. into ( )
23
+ }
9
24
10
25
/// Checks if the debug message with the specified mask should be logged with this logger.
11
26
///
@@ -29,7 +44,7 @@ pub unsafe fn should_debug<T: LogTarget>(target: *const T, mask: Option<DebugMas
29
44
///
30
45
/// The function should be called with a valid target pointer.
31
46
#[ inline]
32
- pub unsafe fn log_error < T : LogTarget > ( target : * const T , level : ngx_uint_t , err : ngx_err_t , args : fmt:: Arguments < ' _ > ) {
47
+ pub unsafe fn log_error < T : LogTarget > ( target : * const T , level : Level , err : ngx_err_t , args : fmt:: Arguments < ' _ > ) {
33
48
debug_assert ! ( !target. is_null( ) ) ;
34
49
if let Some ( str) = args. as_str ( ) {
35
50
( * target) . write_log ( level, err, str. as_bytes ( ) ) ;
@@ -38,6 +53,35 @@ pub unsafe fn log_error<T: LogTarget>(target: *const T, level: ngx_uint_t, err:
38
53
}
39
54
}
40
55
56
+ /// Severity level
57
+ #[ repr( usize ) ]
58
+ #[ derive( PartialEq , Eq , PartialOrd , Ord , Debug ) ]
59
+ pub enum Level {
60
+ /// System is unusable
61
+ Emerg = ffi:: NGX_LOG_EMERG as usize ,
62
+ /// Action must be taken immediately
63
+ Alert = ffi:: NGX_LOG_ALERT as usize ,
64
+ /// Critical conditions
65
+ Crit = ffi:: NGX_LOG_CRIT as usize ,
66
+ /// Error conditions
67
+ Err = ffi:: NGX_LOG_ERR as usize ,
68
+ /// Warning conditions
69
+ Warn = ffi:: NGX_LOG_WARN as usize ,
70
+ /// Normal but significant condition
71
+ Notice = ffi:: NGX_LOG_NOTICE as usize ,
72
+ /// Informational messages
73
+ Info = ffi:: NGX_LOG_INFO as usize ,
74
+ /// Debug-level messages
75
+ Debug = ffi:: NGX_LOG_DEBUG as usize ,
76
+ }
77
+
78
+ impl From < Level > for ngx_uint_t {
79
+ #[ inline]
80
+ fn from ( value : Level ) -> Self {
81
+ value as ngx_uint_t
82
+ }
83
+ }
84
+
41
85
/// Utility trait for nginx structures that contain logger objects
42
86
pub trait LogTarget {
43
87
/// Default debug mask for this target
@@ -51,10 +95,10 @@ pub trait LogTarget {
51
95
52
96
/// Low-level implementation for writing byte slice into the nginx logger
53
97
#[ inline]
54
- fn write_log ( & self , level : ngx_uint_t , err : ngx_err_t , message : & [ u8 ] ) {
98
+ fn write_log ( & self , level : Level , err : ngx_err_t , message : & [ u8 ] ) {
55
99
const FORMAT : & CStr = unsafe { CStr :: from_bytes_with_nul_unchecked ( b"%*s\0 " ) } ;
56
100
let log = self . get_log ( ) . cast_mut ( ) ;
57
- unsafe { ngx_log_error_core ( level, log, err, FORMAT . as_ptr ( ) , message. len ( ) , message. as_ptr ( ) ) } ;
101
+ unsafe { ngx_log_error_core ( level. into ( ) , log, err, FORMAT . as_ptr ( ) , message. len ( ) , message. as_ptr ( ) ) } ;
58
102
}
59
103
}
60
104
@@ -78,6 +122,22 @@ impl LogTarget for ffi::ngx_conf_t {
78
122
fn get_log ( & self ) -> * const ngx_log_t {
79
123
self . log
80
124
}
125
+
126
+ #[ inline]
127
+ fn write_log ( & self , level : Level , err : ngx_err_t , msg : & [ u8 ] ) {
128
+ const FORMAT : & CStr = unsafe { CStr :: from_bytes_with_nul_unchecked ( b"%*s\0 " ) } ;
129
+ if level < Level :: Debug {
130
+ // ngx_conf_log_error will not mutate the cf argument.
131
+ // ngx_log_error_core may mutate the log argument, but cf does not own the log.
132
+ let cf = self as * const _ as * mut _ ;
133
+ unsafe { ngx_conf_log_error ( level. into ( ) , cf, err, FORMAT . as_ptr ( ) , msg. len ( ) , msg. as_ptr ( ) ) } ;
134
+ } else {
135
+ // Debug messages don't need the configuration file context
136
+ // SAFETY: this should called after `should_log` or `should_debug`, when we already know
137
+ // that the log pointer is valid
138
+ unsafe { & * self . log } . write_log ( level, err, msg) ;
139
+ }
140
+ }
81
141
}
82
142
83
143
impl LogTarget for ffi:: ngx_event_t {
@@ -92,13 +152,22 @@ impl LogTarget for ffi::ngx_event_t {
92
152
}
93
153
}
94
154
155
+ /// Write to logger at a specified [Level].
156
+ #[ macro_export]
157
+ macro_rules! ngx_log_error {
158
+ ( $level: expr, $log: expr, $( $arg: tt) * ) => {
159
+ if unsafe { $crate:: log:: should_log( $log, $level) } {
160
+ unsafe { $crate:: log:: log_error( $log, $level, 0 , format_args!( $( $arg) * ) ) } ;
161
+ }
162
+ }
163
+ }
164
+
95
165
/// Write to logger at debug level.
96
166
#[ macro_export]
97
167
macro_rules! ngx_log_debug {
98
168
( $log: expr, $( $arg: tt) * ) => {
99
169
if unsafe { $crate:: log:: should_debug( $log, None ) } {
100
- let level = $crate:: ffi:: NGX_LOG_DEBUG as $crate:: ffi:: ngx_uint_t;
101
- unsafe { $crate:: log:: log_error( $log, level, 0 , format_args!( $( $arg) * ) ) } ;
170
+ unsafe { $crate:: log:: log_error( $log, $crate:: log:: Level :: Debug , 0 , format_args!( $( $arg) * ) ) } ;
102
171
}
103
172
}
104
173
}
@@ -110,8 +179,7 @@ macro_rules! ngx_log_debug {
110
179
macro_rules! ngx_log_debug_http {
111
180
( $request: expr, $( $arg: tt) * ) => {
112
181
if unsafe { $crate:: log:: should_debug( $request, None ) } {
113
- let level = $crate:: ffi:: NGX_LOG_DEBUG as $crate:: ffi:: ngx_uint_t;
114
- unsafe { $crate:: log:: log_error( $request, level, 0 , format_args!( $( $arg) * ) ) } ;
182
+ unsafe { $crate:: log:: log_error( $request, $crate:: log:: Level :: Debug , 0 , format_args!( $( $arg) * ) ) } ;
115
183
}
116
184
}
117
185
}
@@ -128,44 +196,37 @@ macro_rules! ngx_log_debug_http {
128
196
macro_rules! ngx_log_debug_mask {
129
197
( DebugMask :: Core , $log: expr, $( $arg: tt) * ) => ( {
130
198
if unsafe { $crate:: log:: should_debug( $log, Some ( DebugMask :: Core ) ) } {
131
- let level = $crate:: ffi:: NGX_LOG_DEBUG as $crate:: ffi:: ngx_uint_t;
132
- unsafe { $crate:: log:: log_error( $log, level, 0 , format_args!( $( $arg) * ) ) } ;
199
+ unsafe { $crate:: log:: log_error( $log, $crate:: log:: Level :: Debug , 0 , format_args!( $( $arg) * ) ) } ;
133
200
}
134
201
} ) ;
135
202
( DebugMask :: Alloc , $log: expr, $( $arg: tt) * ) => ( {
136
203
if unsafe { $crate:: log:: should_debug( $log, Some ( DebugMask :: Alloc ) ) } {
137
- let level = $crate:: ffi:: NGX_LOG_DEBUG as $crate:: ffi:: ngx_uint_t;
138
- unsafe { $crate:: log:: log_error( $log, level, 0 , format_args!( $( $arg) * ) ) } ;
204
+ unsafe { $crate:: log:: log_error( $log, $crate:: log:: Level :: Debug , 0 , format_args!( $( $arg) * ) ) } ;
139
205
}
140
206
} ) ;
141
207
( DebugMask :: Mutex , $log: expr, $( $arg: tt) * ) => ( {
142
208
if unsafe { $crate:: log:: should_debug( $log, Some ( DebugMask :: Mutex ) ) } {
143
- let level = $crate:: ffi:: NGX_LOG_DEBUG as $crate:: ffi:: ngx_uint_t;
144
- unsafe { $crate:: log:: log_error( $log, level, 0 , format_args!( $( $arg) * ) ) } ;
209
+ unsafe { $crate:: log:: log_error( $log, $crate:: log:: Level :: Debug , 0 , format_args!( $( $arg) * ) ) } ;
145
210
}
146
211
} ) ;
147
212
( DebugMask :: Event , $log: expr, $( $arg: tt) * ) => ( {
148
213
if unsafe { $crate:: log:: should_debug( $log, Some ( DebugMask :: Event ) ) } {
149
- let level = $crate:: ffi:: NGX_LOG_DEBUG as $crate:: ffi:: ngx_uint_t;
150
- unsafe { $crate:: log:: log_error( $log, level, 0 , format_args!( $( $arg) * ) ) } ;
214
+ unsafe { $crate:: log:: log_error( $log, $crate:: log:: Level :: Debug , 0 , format_args!( $( $arg) * ) ) } ;
151
215
}
152
216
} ) ;
153
217
( DebugMask :: Http , $log: expr, $( $arg: tt) * ) => ( {
154
218
if unsafe { $crate:: log:: should_debug( $log, Some ( DebugMask :: Http ) ) } {
155
- let level = $crate:: ffi:: NGX_LOG_DEBUG as $crate:: ffi:: ngx_uint_t;
156
- unsafe { $crate:: log:: log_error( $log, level, 0 , format_args!( $( $arg) * ) ) } ;
219
+ unsafe { $crate:: log:: log_error( $log, $crate:: log:: Level :: Debug , 0 , format_args!( $( $arg) * ) ) } ;
157
220
}
158
221
} ) ;
159
222
( DebugMask :: Mail , $log: expr, $( $arg: tt) * ) => ( {
160
223
if unsafe { $crate:: log:: should_debug( $log, Some ( DebugMask :: Mail ) ) } {
161
- let level = $crate:: ffi:: NGX_LOG_DEBUG as $crate:: ffi:: ngx_uint_t;
162
- unsafe { $crate:: log:: log_error( $log, level, 0 , format_args!( $( $arg) * ) ) } ;
224
+ unsafe { $crate:: log:: log_error( $log, $crate:: log:: Level :: Debug , 0 , format_args!( $( $arg) * ) ) } ;
163
225
}
164
226
} ) ;
165
227
( DebugMask :: Stream , $log: expr, $( $arg: tt) * ) => ( {
166
228
if unsafe { $crate:: log:: should_debug( $log, Some ( DebugMask :: Stream ) ) } {
167
- let level = $crate:: ffi:: NGX_LOG_DEBUG as $crate:: ffi:: ngx_uint_t;
168
- unsafe { $crate:: log:: log_error( $log, level, 0 , format_args!( $( $arg) * ) ) } ;
229
+ unsafe { $crate:: log:: log_error( $log, $crate:: log:: Level :: Debug , 0 , format_args!( $( $arg) * ) ) } ;
169
230
}
170
231
} ) ;
171
232
}
@@ -247,7 +308,7 @@ mod tests {
247
308
& self . log
248
309
}
249
310
250
- fn write_log ( & self , _level : ngx_uint_t , _err : ngx_err_t , message : & [ u8 ] ) {
311
+ fn write_log ( & self , _level : Level , _err : ngx_err_t , message : & [ u8 ] ) {
251
312
self . buffer . set ( message. to_vec ( ) ) ;
252
313
}
253
314
}
@@ -282,4 +343,23 @@ mod tests {
282
343
ngx_log_debug_mask ! ( DebugMask :: Alloc , & log, "mask-alloc" ) ;
283
344
assert_ne ! ( log. buffer. take( ) , b"mask-alloc" ) ;
284
345
}
346
+ #[ test]
347
+ fn test_level ( ) {
348
+ let log = MockLog :: new ( crate :: ffi:: NGX_LOG_NOTICE ) ;
349
+
350
+ ngx_log_error ! ( Level :: Warn , & log, "level-warn" ) ;
351
+ assert_eq ! ( log. buffer. take( ) , b"level-warn" ) ;
352
+
353
+ ngx_log_error ! ( Level :: Notice , & log, "level-notice" ) ;
354
+ assert_eq ! ( log. buffer. take( ) , b"level-notice" ) ;
355
+
356
+ ngx_log_error ! ( Level :: Info , & log, "level-info" ) ;
357
+ assert_ne ! ( log. buffer. take( ) , b"level-info" ) ;
358
+
359
+ ngx_log_error ! ( Level :: Debug , & log, "level-debug" ) ;
360
+ assert_ne ! ( log. buffer. take( ) , b"level-debug" ) ;
361
+
362
+ ngx_log_error ! ( Level :: Err , & log, "level-err" ) ;
363
+ assert_eq ! ( log. buffer. take( ) , b"level-err" ) ;
364
+ }
285
365
}
0 commit comments