Skip to content
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

Support GELF logging output. #497

Merged
merged 1 commit into from
Jun 20, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 101 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion doc/quickstart/02_passive_node.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ Fields description:
- *logger*: (optional) logger configuration,
- *verbosity*: 0 - warning, 1 - info, 2 -debug, 3 and above - trace
- *format*: log output format - plain or json.
- *output*: log output - stderr, syslog (unix only) or journald (linux with systemd only, must be enabled during compilation)
- *output*: log output - stderr, gelf (graylog) syslog (unix only) or journald (linux with systemd only, must be enabled during compilation)
- *backend*: for gelf output: hostname:port of a graylog server.
- *logs_id*: for gelf output: unique id that identify the node as source of the logs.
- *rest*: (optional) configuration of the rest endpoint.
- *listen*: listen address
- *pkcs12*: certificate file (optional)
Expand Down
1 change: 1 addition & 0 deletions jormungandr/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ jormungandr-lib = { path = "../jormungandr-lib" }
strfmt = "0.1"
gtmpl = "0.5.6"
mktemp = "0.4.0"
slog-gelf = "0.1.0"

[dependencies.actix-web]
version = "0.7.18"
Expand Down
1 change: 1 addition & 0 deletions jormungandr/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ extern crate serde_yaml;
#[macro_use(b, o, record_static, debug, info, warn, error, crit)]
extern crate slog;
extern crate slog_async;
extern crate slog_gelf;
#[cfg(feature = "systemd")]
extern crate slog_journald;
extern crate slog_json;
Expand Down
2 changes: 1 addition & 1 deletion jormungandr/src/settings/command_arguments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ pub struct CommandLine {
#[structopt(long = "log-format", parse(try_from_str))]
pub log_format: Option<LogFormat>,

/// Set format of the log emitted. Can be "stderr", "syslog" (unix only) or "journald"
/// Set format of the log emitted. Can be "stderr", "gelf", "syslog" (unix only) or "journald"
/// (linux with systemd only, must be enabled during compilation).
/// If not configured anywhere, defaults to "stderr".
#[structopt(long = "log-output", parse(try_from_str))]
Expand Down
45 changes: 38 additions & 7 deletions jormungandr/src/settings/logging.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::log::{AsyncableDrain, JsonDrain};
use slog::{Drain, Logger};
use slog_async::Async;
use slog_gelf::Gelf;
#[cfg(feature = "systemd")]
use slog_journald::JournaldDrain;
#[cfg(unix)]
Expand All @@ -13,6 +14,8 @@ pub struct LogSettings {
pub verbosity: slog::Level,
pub format: LogFormat,
pub output: LogOutput,
pub backend: Option<String>,
pub logs_id: Option<String>,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
Expand All @@ -28,6 +31,7 @@ pub enum LogFormat {
/// Output of the logger.
pub enum LogOutput {
Stderr,
Gelf,
Copy link
Member

@vincenthz vincenthz Jun 20, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems that if you make this Gelf(String, String) you same yourself the trouble of extending the generic structure for something specific to the backend

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The structopt/YAML thing would need to be customized for this, I believe.

This whole enum needs love, but I can improve it later.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, I was not sure how the yaml parsing would workout if I did that. I can try.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok nevermind, if it's too complicated we can push this through and revisit later

#[cfg(unix)]
Syslog,
#[cfg(feature = "systemd")]
Expand All @@ -52,6 +56,7 @@ impl FromStr for LogOutput {
fn from_str(s: &str) -> Result<Self, Self::Err> {
match &*s.trim().to_lowercase() {
"stderr" => Ok(LogOutput::Stderr),
"gelf" => Ok(LogOutput::Gelf),
#[cfg(unix)]
"syslog" => Ok(LogOutput::Syslog),
#[cfg(feature = "systemd")]
Expand All @@ -63,21 +68,45 @@ impl FromStr for LogOutput {

impl LogSettings {
pub fn to_logger(&self) -> Result<Logger, Error> {
let drain = self.output.to_logger(&self.format)?.fuse();
let drain = self
.output
.to_logger(&self.format, &self.backend, &self.logs_id)?
.fuse();
let drain = slog::LevelFilter::new(drain, self.verbosity).fuse();
Ok(slog::Logger::root(drain, o!()))
}
}

impl LogOutput {
fn to_logger(&self, format: &LogFormat) -> Result<Async, Error> {
Ok(match self {
LogOutput::Stderr => format.decorate_stderr(),
fn to_logger(
&self,
format: &LogFormat,
backend: &Option<String>,
logs_id: &Option<String>,
) -> Result<Async, Error> {
match self {
LogOutput::Stderr => Ok(format.decorate_stderr()),
LogOutput::Gelf => match backend {
Some(graylog_host_port) => {
match logs_id {
Some(graylog_source) => {
let gelf_drain = LogFormat::Plain
.decorate(Gelf::new(graylog_source, graylog_host_port).unwrap());
// We also log to stderr otherwise users see no logs.
// TODO: remove when multiple output is properly supported.
let stderr_drain = format.decorate_stderr();
Ok(slog::Duplicate(gelf_drain, stderr_drain).async())
}
_ => Err(Error::MissingGelfSource),
}
}
_ => Err(Error::MissingGelfBackend),
},
#[cfg(unix)]
LogOutput::Syslog => format.decorate(slog_syslog::unix_3164(Facility::LOG_USER)?),
LogOutput::Syslog => Ok(format.decorate(slog_syslog::unix_3164(Facility::LOG_USER)?)),
#[cfg(feature = "systemd")]
LogOutput::Journald => format.decorate(JournaldDrain),
})
LogOutput::Journald => Ok(format.decorate(JournaldDrain)),
}
}
}

Expand All @@ -102,4 +131,6 @@ impl LogFormat {

custom_error! {pub Error
SyslogAccessFailed { source: io::Error } = "syslog access failed",
MissingGelfBackend = "Please specify a backend (host:port of graylog server) for the GELF logger output",
MissingGelfSource = "Please specify a logs_id for your logs when using GELF logger output",
}
Loading