Learn how to push your logs to Logs Data Platform using Rust.
Rust has a logging implementation (log) that is widely used. OVHcloud has implemented this system to support the GELF format:
-
gelf_logger: This is a minimal logger.
-
log4rs-gelf: Based on gelf_logger, this implementation is compatible with the complex configurable framework log4rs.
Those loggers will:
- serialize log entries using the serde_gelf crate.
- buffer the result into memory.
- batch send over a network using TCP/TLS.
- ensure fields follow the LDP naming conventions.
This tutorial shows how to push logs with two different libraries (gelf_logger and log4rs-gelf); use whichever you prefer.
Requirements
- Rust (we recommend the last stable version)
- an activated Logs Data Platform account
- at least one stream and its token
- install the serde crate with the derive feature
- install the log crate with serde feature
Method 1: gelf_logger
You can install the gelf_logger crate by adding the dependency to your Cargo.toml
:
[dependencies]
gelf_logger = { version = "0.3.0", features = ["ovh-ldp"] }
Alternatively, the following cargo command will install it:
$ cargo add gelf_logger -F ovh-ldp
Here is a full main.rs file showing how to use the log and the gelf_logger API.
use gelf_logger::{
gelf_alert, gelf_critical, gelf_debug, gelf_emergency, gelf_error, gelf_info, gelf_log,
gelf_notice, gelf_warn, Builder, GelfLevel,
};
use log::{error, info, warn, LevelFilter};
use serde::Serialize;
#[derive(Serialize, Debug)]
struct Request<'a> {
id: u16,
method: &'a str,
path: &'a str,
}
fn main() {
Builder::new()
.filter_level(LevelFilter::Info)
.ovh_ldp(
"<YOUR-LDP-CLUSTER-ADDRESS>".to_owned(),
"<YOUR-WRITE-TOKEN>".to_owned(),
)
.init();
// basic logs
info!("hello from rust");
// Basic key-value logs.
info!(count = 5; "packet received");
warn!(user = "foo"; "unknown user");
error!(err:err = "abc".parse::<u32>().unwrap_err(); "parse error");
let req = Request {
id: 42,
method: "GET",
path: "/login",
};
// Will serialize as a `Debug` string.
info!(req:?; "incoming request");
// Will flatten all the field and add them as additional fields.
info!(req:serde; "incoming request flattened");
// Gelf specific levels.
gelf_log!(GelfLevel::Emergency, foo = "bar"; "an emergency log");
gelf_emergency!(foo = "bar"; "an emergency log");
gelf_alert!(foo = "bar"; "an alert log");
gelf_critical!(foo = "bar"; "a critical log");
gelf_error!(foo = "bar"; "an error log");
gelf_warn!(foo = "bar"; "a warn log");
gelf_notice!(foo = "bar"; "a notice log");
gelf_info!(foo = "bar"; "an info log");
gelf_debug!(foo = "bar"; "a debug log");
// Flush underlying TCP socket.
// This will only flush. The socket may be dropped without proper closing.
log::logger().flush();
}
Don't forget to modify the placeholder to the cluster where your stream resides. There is no need to put the Gelf port. Example: "bhs2.logs.ovh.com".
Don't forget to modify the placeholder to the actual value of the write token of your stream.
You could also look at the generated API documentaton.
Method 2: log4rs-gelf
This method is an alternative to the previous one. Please consider the following as a different rust project. You need to be familiar with the log4rs framework.
Install log4rs and log4rs-gelf in your Rust project.
Here is the modified Cargo.toml file:
[dependencies]
log = { version = "0.4.22", features = ["serde"] }
log4rs = "1.3.0"
log4rs-gelf = { version = "0.1.4", features = ["ovh-ldp"] }
serde = { version = "1.0.204", features = ["derive"] }
Alternatively, use the following cargo commands:
$ cargo add log4rs-gelf -F ovh-ldp
Examples
From a YAML configuration file
Copy the content of this yaml file log4rs.yaml. This file will be retrieved by the rust program to configure the framework.
appenders:
stdout:
kind: console
ldp:
additional_fields:
X-OVH-TOKEN: <YOUR-WRITE-TOKEN>
component: rust-cs
buffer_duration: 5
buffer_size: 5
hostname: <YOUR-LDP-CLUSTER-ADDRESS>
kind: buffer
level: Informational
null_character: true
port: 12202
use_tls: true
root:
appenders:
- ldp
- stdout
level: info
Don't forget to modify the placeholder <YOUR-LDP-CLUSTER-ADDRESS>
to the cluster where your stream resides. There is no need to put the Gelf port, e.g. "bhs2.logs.ovh.com".
Also, modify the placeholder <YOUR-WRITE-TOKEN>
to the actual value of the write token of your stream.
Use this configuration in your project:
use core::time;
use std::thread::sleep;
use log::{info, warn};
fn main() {
// reading
log4rs_gelf::init_file("./log4rs.yml", None).unwrap();
// using log crate APIs
info!("Hello from rust");
warn!("Warning from rust");
// simulating some work (log framework is asynchronous)
sleep(time::Duration::from_secs(5));
// flushing remaining logs
log4rs_gelf::flush().expect("Failed to send buffer, log records could be lost !");
}
You could also look at the generated API documentation.
Go further
For more information and tutorials, please see our other Logs Data Platform support guides or explore the guides for other OVHcloud products and services.