• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

OISF / suricata / 23374838686

21 Mar 2026 07:29AM UTC coverage: 59.341% (-20.0%) from 79.315%
23374838686

Pull #15075

github

web-flow
Merge 90b4e834f into 6587e363a
Pull Request #15075: Stack 8001 v16.4

38 of 70 new or added lines in 10 files covered. (54.29%)

34165 existing lines in 563 files now uncovered.

119621 of 201584 relevant lines covered (59.34%)

650666.92 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

51.06
/rust/ffi/src/debug.rs
1
/* Copyright (C) 2017-2026 Open Information Security Foundation
2
 *
3
 * You can copy, redistribute or modify this Program under the terms of
4
 * the GNU General Public License version 2 as published by the Free
5
 * Software Foundation.
6
 *
7
 * This program is distributed in the hope that it will be useful,
8
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
 * GNU General Public License for more details.
11
 *
12
 * You should have received a copy of the GNU General Public License
13
 * version 2 along with this program; if not, write to the Free Software
14
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15
 * 02110-1301, USA.
16
 */
17

18
//! Logging and debug utilities, like util-debug.c.
19

20
use std::{ffi::CString, path::Path};
21

22
use suricata_sys::sys::{SCError, SCLogMessage};
23
use suricata_sys::sys::{SCFatalErrorOnInitStatic, SCLogLevel};
24

25
/// The Suricata log-level.
26
///
27
/// This must be set on start-up of Suricata, as well as on plugin
28
/// initialization so the plugin inherits the same log-level as the
29
/// running Suricata.
30
pub static mut LEVEL: SCLogLevel = SCLogLevel::SC_LOG_NOTSET;
31

32
/// Set the Rust context's idea of the log level.
33
///
34
/// This will be called during Suricata initialization with the
35
/// runtime log level.
36
///
37
/// # Safety
38
///
39
/// This function writes to the global variable LEVEL. This variable
40
/// should not be read or written from multiple threads, so this is
41
/// best called before we spawn any threads.
42
pub unsafe fn set_log_level(level: SCLogLevel) {
×
43
    LEVEL = level;
×
44
}
×
45

46
fn basename(filename: &str) -> &str {
×
47
    let path = Path::new(filename);
×
48
    if let Some(os_str) = path.file_name() {
×
49
        if let Some(basename) = os_str.to_str() {
×
50
            return basename;
×
51
        }
×
52
    }
×
53
    filename
×
54
}
×
55

UNCOV
56
pub fn fatalerror(message: &str) {
×
UNCOV
57
    unsafe {
×
UNCOV
58
        SCFatalErrorOnInitStatic(to_safe_cstring(message).as_ptr());
×
UNCOV
59
    }
×
UNCOV
60
}
×
61

62
pub fn sclog(level: SCLogLevel, file: &str, line: u32, function: &str, message: &str) {
×
63
    let filename = basename(file);
×
64
    let noext = &filename[0..filename.len() - 3];
×
65
    log_message(level, filename, line, function, noext, message);
×
66
}
×
67

68
/// SCLogMessage wrapper.
69
pub fn log_message(
77,501✔
70
    level: SCLogLevel, filename: &str, line: std::os::raw::c_uint, function: &str, module: &str,
77,501✔
71
    message: &str,
77,501✔
72
) -> SCError {
77,501✔
73
    unsafe {
77,501✔
74
        SCLogMessage(
77,501✔
75
            level,
77,501✔
76
            to_safe_cstring(filename).as_ptr(),
77,501✔
77
            line,
77,501✔
78
            to_safe_cstring(function).as_ptr(),
77,501✔
79
            to_safe_cstring(module).as_ptr(),
77,501✔
80
            to_safe_cstring(message).as_ptr(),
77,501✔
81
        )
77,501✔
82
    }
77,501✔
83
}
77,501✔
84

85
// Convert a &str into a CString by first stripping NUL bytes.
86
fn to_safe_cstring(val: &str) -> CString {
310,004✔
87
    let mut safe = Vec::with_capacity(val.len());
310,004✔
88
    for c in val.as_bytes() {
7,664,646✔
89
        if *c != 0 {
7,664,646✔
90
            safe.push(*c);
7,664,646✔
91
        }
7,664,646✔
92
    }
93
    match CString::new(safe) {
310,004✔
94
        Ok(cstr) => cstr,
310,004✔
95
        _ => CString::new("<failed to encode string>").unwrap(),
×
96
    }
97
}
310,004✔
98

99
// This macro returns the function name.
100
//
101
// This macro has been borrowed from https://github.com/popzxc/stdext-rs, which
102
// is released under the MIT license as there is currently no macro in Rust
103
// to provide the function name.
104
#[macro_export(local_inner_macros)]
105
macro_rules! function {
106
    () => {{
107
        // Okay, this is ugly, I get it. However, this is the best we can get on a stable rust.
108
        fn __f() {}
109
        fn type_name_of<T>(_: T) -> &'static str {
110
            std::any::type_name::<T>()
111
        }
112
        let name = type_name_of(__f);
113
        &name[..name.len() - 5]
114
    }};
115
}
116

117
#[macro_export]
118
macro_rules! do_log {
119
    ($level:expr, $($arg:tt)*) => {
120
        #[allow(unused_unsafe)]
121
        if unsafe { $crate::debug::LEVEL as i32 } >= $level as i32 {
122
            $crate::debug::sclog($level, file!(), line!(), $crate::function!(),
123
                  &(format!($($arg)*)));
124
        }
125
    }
126
}
127

128
#[macro_export]
129
macro_rules! SCLogError {
130
    ($($arg:tt)*) => {
131
        $crate::do_log!(suricata_sys::sys::SCLogLevel::SC_LOG_ERROR, $($arg)*);
132
    };
133
}
134

135
#[macro_export]
136
macro_rules! SCLogWarning {
137
    ($($arg:tt)*) => {
138
        $crate::do_log!(suricata_sys::sys::SCLogLevel::SC_LOG_WARNING, $($arg)*);
139
    };
140
}
141

142
#[macro_export]
143
macro_rules! SCLogNotice {
144
    ($($arg:tt)*) => {
145
        $crate::do_log!(suricata_sys::sys::SCLogLevel::SC_LOG_NOTICE, $($arg)*);
146
    }
147
}
148

149
#[macro_export]
150
macro_rules! SCLogInfo {
151
    ($($arg:tt)*) => {
152
        $crate::do_log!(suricata_sys::sys::SCLogLevel::SC_LOG_INFO, $($arg)*);
153
    }
154
}
155

156
#[macro_export]
157
macro_rules! SCLogPerf {
158
    ($($arg:tt)*) => {
159
        $crate::do_log!(suricata_sys::sys::SCLogLevel::SC_LOG_PERF, $($arg)*);
160
    }
161
}
162

163
#[macro_export]
164
macro_rules! SCLogConfig {
165
    ($($arg:tt)*) => {
166
        $crate::do_log!(suricata_sys::sys::SCLogLevel::SC_LOG_CONFIG, $($arg)*);
167
    }
168
}
169

170
// Debug mode: call C SCLogDebug
171
#[cfg(feature = "debug")]
172
#[macro_export]
173
macro_rules!SCLogDebug {
174
    ($($arg:tt)*) => {
175
        $crate::do_log!(suricata_sys::sys::SCLogLevel::SC_LOG_DEBUG, $($arg)*);
176
    }
177
}
178

179
// SCLogDebug variation to use when not compiled with debug
180
// support. This just swallows the arguments and doesn't output
181
// anything.
182
#[cfg(not(feature = "debug"))]
183
#[macro_export]
184
macro_rules! SCLogDebug {
185
    ($($arg:tt)*) => {};
186
}
187

188
#[macro_export]
189
macro_rules! SCFatalErrorOnInit {
190
    ($($arg:tt)*) => {
191
        $crate::debug::fatalerror(&format!($($arg)*));
192
    }
193
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc