-
Notifications
You must be signed in to change notification settings - Fork 697
Add syslog supports #2537
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
+266
−1
Merged
Add syslog supports #2537
Changes from all commits
Commits
Show all changes
26 commits
Select commit
Hold shift + click to select a range
ae86c6a
Stub for wrap syslog.h
tisonkun ad6a2f3
Wrap openlog
tisonkun 216b4a8
Make it work
tisonkun 216911e
lib_enums and docs
tisonkun a19d932
wrap priority
tisonkun 953fdec
reduce error handle noise and add docs
tisonkun 98289d5
try add setlogmask
tisonkun f527072
Revert "try add setlogmask"
tisonkun ee8ffed
fixup tests
tisonkun 5c547d6
fixup all
tisonkun f4bd797
add changelog
tisonkun 0e6c99b
turn on syslog for tests
tisonkun f9df215
revert irrelevant format
tisonkun a60f314
add new feature flags
tisonkun d051dc6
Add back closelog
tisonkun 12e7bdf
Use AsRef<OsStr> for openlog.ident
tisonkun 169b5d0
polish APIs
tisonkun 0c61a95
fixup
tisonkun 584e4df
test on linux
tisonkun 718519c
test on unix
tisonkun c98a454
fixup flags
tisonkun 9f3596e
fixup all
tisonkun 541801e
Update src/syslog.rs
tisonkun 596280b
refactor: use AsRef<OsStr> on non-Linux and &'static CStr on Linux fo…
SteveLauC 1cadebe
style: fmt
SteveLauC 7014ca1
fix: Linux build by importing CStr
SteveLauC File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Add support for `syslog`, `openlog`, `closelog` on all `unix`. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,216 @@ | ||
//! Interfaces for controlling system log. | ||
|
||
use crate::{NixPath, Result}; | ||
use std::ffi::OsStr; | ||
use std::ptr; | ||
|
||
/// Logging options of subsequent [`syslog`] calls can be set by calling [`openlog`]. | ||
/// | ||
/// The parameter `ident` is a string that will be prepended to every message. The `logopt` | ||
/// argument specifies logging options. The `facility` parameter encodes a default facility to be | ||
/// assigned to all messages that do not have an explicit facility encoded. | ||
// | ||
// On Linux, the `ident` argument needs to have static lifetime according to the | ||
// man page: | ||
// | ||
// The argument ident in the call of openlog() is probably stored as-is. Thus, | ||
// if the string it points to is changed, syslog() may start prepending the changed | ||
// string, and if the string it points to ceases to exist, the results are | ||
// undefined. Most portable is to use a string constant. | ||
#[cfg(target_os = "linux")] | ||
pub fn openlog( | ||
ident: Option<&'static std::ffi::CStr>, | ||
logopt: LogFlags, | ||
facility: Facility, | ||
) -> Result<()> { | ||
let logopt = logopt.bits(); | ||
let facility = facility as libc::c_int; | ||
match ident { | ||
None => unsafe { | ||
libc::openlog(ptr::null(), logopt, facility); | ||
}, | ||
Some(ident) => ident.with_nix_path(|ident| unsafe { | ||
libc::openlog(ident.as_ptr(), logopt, facility); | ||
})?, | ||
} | ||
|
||
Ok(()) | ||
} | ||
|
||
/// Logging options of subsequent [`syslog`] calls can be set by calling [`openlog`]. | ||
/// | ||
/// The parameter `ident` is a string that will be prepended to every message. The `logopt` | ||
/// argument specifies logging options. The `facility` parameter encodes a default facility to be | ||
/// assigned to all messages that do not have an explicit facility encoded. | ||
#[cfg(not(target_os = "linux"))] | ||
pub fn openlog<S: AsRef<OsStr> + ?Sized>( | ||
ident: Option<&S>, | ||
logopt: LogFlags, | ||
facility: Facility, | ||
) -> Result<()> { | ||
let logopt = logopt.bits(); | ||
let facility = facility as libc::c_int; | ||
match ident.map(OsStr::new) { | ||
None => unsafe { | ||
libc::openlog(ptr::null(), logopt, facility); | ||
}, | ||
Some(ident) => ident.with_nix_path(|ident| unsafe { | ||
libc::openlog(ident.as_ptr(), logopt, facility); | ||
})?, | ||
} | ||
|
||
Ok(()) | ||
} | ||
|
||
/// Writes message to the system message logger. | ||
/// | ||
/// The message is then written to the system console, log files, logged-in users, or forwarded | ||
/// to other machines as appropriate. | ||
/// | ||
/// # Examples | ||
/// | ||
/// ```rust | ||
/// use nix::syslog::{openlog, syslog, Facility, LogFlags, Severity, Priority}; | ||
/// | ||
/// let priority = Priority::new(Severity::LOG_EMERG, Facility::LOG_USER); | ||
/// syslog(priority, "Hello, nix!").unwrap(); | ||
/// | ||
/// // use `format!` to format the message | ||
/// let name = "syslog"; | ||
/// syslog(priority, &format!("Hello, {name}!")).unwrap(); | ||
/// ``` | ||
pub fn syslog<P, S>(priority: P, message: &S) -> Result<()> | ||
where | ||
P: Into<Priority>, | ||
tisonkun marked this conversation as resolved.
Show resolved
Hide resolved
|
||
S: AsRef<OsStr> + ?Sized, | ||
{ | ||
let priority = priority.into(); | ||
let formatter = OsStr::new("%s"); | ||
tisonkun marked this conversation as resolved.
Show resolved
Hide resolved
|
||
let message = OsStr::new(message); | ||
formatter.with_nix_path(|formatter| { | ||
message.with_nix_path(|message| unsafe { | ||
libc::syslog(priority.0, formatter.as_ptr(), message.as_ptr()) | ||
}) | ||
})??; | ||
Ok(()) | ||
} | ||
|
||
/// Closes the log file. | ||
pub fn closelog() { | ||
unsafe { libc::closelog() } | ||
} | ||
|
||
/// The priority for a log message. | ||
#[derive(Debug, Clone, Copy)] | ||
pub struct Priority(libc::c_int); | ||
|
||
impl Priority { | ||
/// Create a new priority from a facility and severity level. | ||
pub fn new(severity: Severity, facility: Facility) -> Self { | ||
let priority = (facility as libc::c_int) | (severity as libc::c_int); | ||
Priority(priority) | ||
} | ||
} | ||
|
||
impl From<Severity> for Priority { | ||
fn from(severity: Severity) -> Self { | ||
let priority = severity as libc::c_int; | ||
Priority(priority) | ||
} | ||
} | ||
|
||
libc_bitflags! { | ||
/// Options for system logging. | ||
pub struct LogFlags: libc::c_int { | ||
tisonkun marked this conversation as resolved.
Show resolved
Hide resolved
|
||
/// Log the process id with each message: useful for identifying instantiations of | ||
/// daemons. | ||
LOG_PID; | ||
/// If syslog() cannot pass the message to syslogd(8) it will attempt to write the | ||
/// message to the console ("/dev/console"). | ||
LOG_CONS; | ||
/// The converse of [`LOG_NDELAY`][LogFlags::LOG_NDELAY]; opening of the connection is | ||
/// delayed until `syslog` is called. | ||
/// | ||
/// This is the default, and need not be specified. | ||
LOG_ODELAY; | ||
/// Open the connection to syslogd(8) immediately. Normally the open is delayed until | ||
/// the first message is logged. Useful for programs that need to manage the order in | ||
/// which file descriptors are allocated. | ||
LOG_NDELAY; | ||
/// Write the message to standard error output as well to the system log. | ||
#[cfg(not(any(target_os = "redox", target_os = "illumos")))] | ||
LOG_PERROR; | ||
} | ||
} | ||
|
||
libc_enum! { | ||
/// Severity levels for log messages. | ||
#[repr(i32)] | ||
#[non_exhaustive] | ||
pub enum Severity { | ||
tisonkun marked this conversation as resolved.
Show resolved
Hide resolved
|
||
/// A panic condition. | ||
/// | ||
/// This is normally broadcast to all users. | ||
LOG_EMERG, | ||
/// A condition that should be corrected immediately, such as a corrupted system database. | ||
LOG_ALERT, | ||
/// Critical conditions, e.g., hard device errors. | ||
LOG_CRIT, | ||
/// Errors. | ||
LOG_ERR, | ||
/// Warning messages. | ||
LOG_WARNING, | ||
/// Conditions that are not error conditions, but should possibly be handled specially. | ||
LOG_NOTICE, | ||
/// Informational messages. | ||
LOG_INFO, | ||
/// Messages that contain information normally of use only when debugging a program. | ||
LOG_DEBUG, | ||
} | ||
} | ||
|
||
libc_enum! { | ||
/// Facilities for log messages. | ||
#[repr(i32)] | ||
#[non_exhaustive] | ||
pub enum Facility { | ||
/// Messages generated by the kernel. | ||
/// | ||
/// These cannot be generated by any user processes. | ||
LOG_KERN, | ||
/// Messages generated by random user processes. | ||
/// | ||
/// This is the default facility identifier if none is specified. | ||
LOG_USER, | ||
/// The mail system. | ||
LOG_MAIL, | ||
/// System daemons, such as routed(8), that are not provided for explicitly by other facilities. | ||
LOG_DAEMON, | ||
/// The authorization system: login(1), su(1), getty(8), etc. | ||
LOG_AUTH, | ||
/// Messages generated internally by syslogd(8). | ||
LOG_SYSLOG, | ||
/// The line printer spooling system: cups-lpd(8), cupsd(8), etc. | ||
LOG_LPR, | ||
/// The network news system. | ||
LOG_NEWS, | ||
/// The uucp system. | ||
LOG_UUCP, | ||
/// Reserved for local use. | ||
LOG_LOCAL0, | ||
/// Reserved for local use. | ||
LOG_LOCAL1, | ||
/// Reserved for local use. | ||
LOG_LOCAL2, | ||
/// Reserved for local use. | ||
LOG_LOCAL3, | ||
/// Reserved for local use. | ||
LOG_LOCAL4, | ||
/// Reserved for local use. | ||
LOG_LOCAL5, | ||
/// Reserved for local use. | ||
LOG_LOCAL6, | ||
/// Reserved for local use. | ||
LOG_LOCAL7, | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -42,6 +42,8 @@ mod test_sendfile; | |
))] | ||
mod test_spawn; | ||
|
||
mod test_syslog; | ||
|
||
mod test_time; | ||
mod test_unistd; | ||
|
||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
use nix::syslog::{openlog, syslog, Facility, LogFlags, Severity}; | ||
|
||
#[test] | ||
fn test_syslog_hello_world() { | ||
let flags = LogFlags::LOG_PID; | ||
|
||
#[cfg(not(target_os = "linux"))] | ||
openlog(None::<&str>, flags, Facility::LOG_USER).unwrap(); | ||
#[cfg(target_os = "linux")] | ||
openlog(None, flags, Facility::LOG_USER).unwrap(); | ||
|
||
syslog(Severity::LOG_EMERG, "Hello, nix!").unwrap(); | ||
let name = "syslog"; | ||
syslog(Severity::LOG_NOTICE, &format!("Hello, {name}!")).unwrap(); | ||
} | ||
|
||
#[test] | ||
#[cfg(target_os = "linux")] | ||
fn test_openlog_with_ident() { | ||
use std::ffi::CStr; | ||
|
||
const IDENT: &CStr = unsafe { | ||
CStr::from_bytes_with_nul_unchecked(b"test_openlog_with_ident\0") | ||
}; | ||
|
||
let flags = LogFlags::LOG_PID; | ||
openlog(Some(IDENT), flags, Facility::LOG_USER).unwrap(); | ||
syslog(Severity::LOG_EMERG, "Hello, ident!").unwrap(); | ||
} | ||
|
||
#[test] | ||
#[cfg(not(target_os = "linux"))] | ||
fn test_openlog_with_ident() { | ||
let flags = LogFlags::LOG_PID; | ||
openlog(Some("test_openlog_with_ident"), flags, Facility::LOG_USER) | ||
.unwrap(); | ||
syslog(Severity::LOG_EMERG, "Hello, ident!").unwrap(); | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.