#![cfg(feature = "loki")]
#![cfg_attr(docsrs, doc(cfg(feature = "loki")))]
use std::time::Duration;
use crate::BasicAuth;
pub const LOKI_DEFAULT_APP: &str = "rust-app";
pub const LOKI_DEFAULT_JOB: &str = "rust-job";
pub const LOKI_DEFAULT_ENV: &str = "rust-env";
pub const LOKI_DEFAULT_RETRIES: usize = 3;
pub const LOKI_DEFAULT_WORKERS: usize = 1;
pub const LOKI_DEFAULT_CONNECTION_TIMEOUT: Duration = Duration::from_secs(1);
pub const LOKI_DEFAULT_REQUEST_TIMEOUT: Duration = Duration::from_secs(2);
#[derive(Clone)]
pub struct Config {
pub(crate) url: String,
pub(crate) app: String,
pub(crate) job: String,
pub(crate) env: String,
pub(crate) basic_auth: Option<BasicAuth>,
pub(crate) bearer_auth: Option<String>,
pub(crate) connection_timeout: Duration,
pub(crate) request_timeout: Duration,
pub(crate) max_retries: usize,
pub(crate) worker_count: usize,
}
impl Config {
pub fn new<S>(url: S) -> Self
where
S: Into<String>,
{
Self::with_labels(
url,
LOKI_DEFAULT_APP.to_string(),
LOKI_DEFAULT_JOB.to_string(),
LOKI_DEFAULT_ENV.to_string(),
)
}
pub fn with_labels<S1, S2, S3, S4>(url: S1, app: S3, job: S2, env: S4) -> Self
where
S1: Into<String>,
S2: Into<String>,
S3: Into<String>,
S4: Into<String>,
{
let mut url = url.into();
if !url.ends_with('/') {
url.push('/');
}
Self {
url,
app: app.into(),
job: job.into(),
env: env.into(),
basic_auth: None,
bearer_auth: None,
connection_timeout: LOKI_DEFAULT_CONNECTION_TIMEOUT,
request_timeout: LOKI_DEFAULT_REQUEST_TIMEOUT,
max_retries: LOKI_DEFAULT_RETRIES,
worker_count: LOKI_DEFAULT_WORKERS,
}
}
pub fn get_url(&self) -> &str {
&self.url
}
pub fn get_app(&self) -> &str {
&self.app
}
pub fn get_job(&self) -> &str {
&self.job
}
pub fn get_env(&self) -> &str {
&self.env
}
pub fn get_basic_auth(&self) -> Option<&BasicAuth> {
self.basic_auth.as_ref()
}
pub fn get_bearer_auth(&self) -> Option<&str> {
self.bearer_auth.as_ref().map(|auth| auth.as_str())
}
pub fn get_connection_timeout(&self) -> Duration {
self.connection_timeout
}
pub fn get_request_timeout(&self) -> Duration {
self.request_timeout
}
pub fn get_worker_count(&self) -> usize {
self.worker_count
}
pub fn get_max_retries(&self) -> usize {
self.max_retries
}
pub fn url<S: Into<String>>(mut self, url: S) -> Self {
let mut url = url.into();
if !url.ends_with('/') {
url.push('/');
}
self.url = url;
self
}
pub fn app<S: Into<String>>(mut self, app: S) -> Self {
self.app = app.into();
self
}
pub fn job<S: Into<String>>(mut self, job: S) -> Self {
self.job = job.into();
self
}
pub fn env<S: Into<String>>(mut self, env: S) -> Self {
self.env = env.into();
self
}
pub fn worker_count(mut self, worker_count: usize) -> Self {
self.worker_count = worker_count;
self
}
pub fn max_retries(mut self, max_retries: usize) -> Self {
self.max_retries = max_retries;
self
}
pub fn basic_auth<BA>(mut self, basic_auth: Option<BA>) -> Self
where
BA: Into<BasicAuth>,
{
self.basic_auth = basic_auth.map(|auth| auth.into());
self
}
pub fn bearer_auth<S>(mut self, token: Option<S>) -> Self
where
S: Into<String>,
{
self.bearer_auth = token.map(|token| token.into());
self
}
pub fn connection_timeout<D: Into<Duration>>(mut self, connection_timeout: D) -> Self {
self.connection_timeout = connection_timeout.into();
self
}
pub fn request_timeout<S: Into<Duration>>(mut self, request_timeout: S) -> Self {
self.request_timeout = request_timeout.into();
self
}
}
impl std::fmt::Debug for Config {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut d = f.debug_struct("LokiConfig");
d.field("url", &self.url)
.field("app", &self.app)
.field("job", &self.job)
.field("env", &self.env);
#[cfg(debug_assertions)]
{
d.field("basic_auth", &self.basic_auth)
.field("bearer_auth", &self.bearer_auth);
}
#[cfg(not(debug_assertions))]
{
let auth_status = if self.bearer_auth.is_some() || self.basic_auth.is_some() {
"REDACTED (Set)"
} else {
"None"
};
d.field("auth", &auth_status);
}
d.field("connection_timeout", &self.connection_timeout)
.field("request_timeout", &self.request_timeout)
.field("max_retries", &self.max_retries)
.field("worker_count", &self.worker_count)
.finish()
}
}