1
+ use std:: fmt;
2
+ use std:: io:: Write ;
3
+
1
4
/// Utility function to provide typed checking of the mask's field state.
2
5
#[ inline( always) ]
3
6
pub fn check_mask ( mask : DebugMask , log_level : usize ) -> bool {
@@ -8,6 +11,29 @@ pub fn check_mask(mask: DebugMask, log_level: usize) -> bool {
8
11
true
9
12
}
10
13
14
+ /// Format args into a provided buffer
15
+ // XXX: use core::io::BorrowedBuf to avoid initialization when stabilized
16
+ // XXX: may produce incomplete UTF-8 sequences. But writes to `ngx_log_t` already can be truncated,
17
+ // so nothing we can do here.
18
+ #[ inline]
19
+ pub fn format_into_buf < ' a > ( args : fmt:: Arguments < ' _ > , out : & ' a mut [ u8 ] ) -> & ' a [ u8 ] {
20
+ if let Some ( str) = args. as_str ( ) {
21
+ str. as_bytes ( )
22
+ } else {
23
+ let mut cur = std:: io:: Cursor :: new ( out) ;
24
+ // nothing we can or want to do on errors.
25
+ let _ = cur. write_fmt ( args) ;
26
+ let n = cur. position ( ) as usize ;
27
+ & cur. into_inner ( ) [ ..n]
28
+ }
29
+ }
30
+
31
+ /// Size of the static buffer used to format log messages.
32
+ ///
33
+ /// Approximates the remaining space in `u_char[NGX_MAX_ERROR_STR]` after writing the standard log
34
+ /// prefix (`1970/01/01 00:00:00 [info] 1#1: `).
35
+ pub const LOG_BUFFER_SIZE : usize = ( crate :: ffi:: NGX_MAX_ERROR_STR - 32 ) as _ ;
36
+
11
37
/// Write to logger at a specified level.
12
38
///
13
39
/// See [Logging](https://nginx.org/en/docs/dev/development_guide.html#logging)
@@ -18,8 +44,8 @@ macro_rules! ngx_log_error {
18
44
let log = $log;
19
45
let level = $level as $crate:: ffi:: ngx_uint_t;
20
46
if level < unsafe { ( * log) . log_level } {
21
- let message = :: std :: format! ( $ ( $arg ) + ) ;
22
- let message = message . as_bytes ( ) ;
47
+ let mut out = [ 0u8 ; $crate :: log :: LOG_BUFFER_SIZE ] ;
48
+ let message = $crate :: log :: format_into_buf ( format_args! ( $ ( $arg ) + ) , & mut out ) ;
23
49
unsafe {
24
50
$crate:: ffi:: ngx_log_error_core( level, log, 0 , c"%*s" . as_ptr( ) , message. len( ) , message. as_ptr( ) ) ;
25
51
}
@@ -34,8 +60,8 @@ macro_rules! ngx_conf_log_error {
34
60
let cf: * mut $crate:: ffi:: ngx_conf_t = $cf;
35
61
let level = $level as $crate:: ffi:: ngx_uint_t;
36
62
if level < unsafe { ( * ( * cf) . log) . log_level } {
37
- let message = :: std :: format! ( $ ( $arg ) + ) ;
38
- let message = message . as_bytes ( ) ;
63
+ let mut out = [ 0u8 ; $crate :: log :: LOG_BUFFER_SIZE ] ;
64
+ let message = $crate :: log :: format_into_buf ( format_args! ( $ ( $arg ) + ) , & mut out ) ;
39
65
unsafe {
40
66
$crate:: ffi:: ngx_conf_log_error( level, cf, 0 , c"%*s" . as_ptr( ) , message. len( ) , message. as_ptr( ) ) ;
41
67
}
@@ -50,8 +76,8 @@ macro_rules! ngx_log_debug {
50
76
let log = $log;
51
77
if $crate:: log:: check_mask( $mask, unsafe { ( * log) . log_level } ) {
52
78
let level = $crate:: ffi:: NGX_LOG_DEBUG as $crate:: ffi:: ngx_uint_t;
53
- let message = format! ( $ ( $arg ) + ) ;
54
- let message = message . as_bytes ( ) ;
79
+ let mut out = [ 0u8 ; $crate :: log :: LOG_BUFFER_SIZE ] ;
80
+ let message = $crate :: log :: format_into_buf ( format_args! ( $ ( $arg ) + ) , & mut out ) ;
55
81
unsafe {
56
82
$crate:: ffi:: ngx_log_error_core( level, log, 0 , c"%*s" . as_ptr( ) , message. len( ) , message. as_ptr( ) ) ;
57
83
}
0 commit comments