mirror of
https://github.com/rustfs/rustfs.git
synced 2026-01-16 17:20:33 +00:00
* chore: Add copyright and license headers This commit adds the Apache 2.0 license and a copyright notice to the header of all source files. This ensures that the licensing and copyright information is clearly stated within the codebase. * cargo fmt * fix * fmt * fix clippy
85 lines
2.7 KiB
Rust
85 lines
2.7 KiB
Rust
// Copyright 2024 RustFS Team
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
use crate::UnifiedLogEntry;
|
|
use crate::sinks::Sink;
|
|
use async_trait::async_trait;
|
|
|
|
/// Webhook Sink Implementation
|
|
pub struct WebhookSink {
|
|
endpoint: String,
|
|
auth_token: String,
|
|
client: reqwest::Client,
|
|
max_retries: usize,
|
|
retry_delay_ms: u64,
|
|
}
|
|
|
|
impl WebhookSink {
|
|
pub fn new(endpoint: String, auth_token: String, max_retries: usize, retry_delay_ms: u64) -> Self {
|
|
WebhookSink {
|
|
endpoint,
|
|
auth_token,
|
|
client: reqwest::Client::builder()
|
|
.timeout(std::time::Duration::from_secs(10))
|
|
.build()
|
|
.unwrap_or_else(|_| reqwest::Client::new()),
|
|
max_retries,
|
|
retry_delay_ms,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[async_trait]
|
|
impl Sink for WebhookSink {
|
|
async fn write(&self, entry: &UnifiedLogEntry) {
|
|
let mut retries = 0;
|
|
let url = self.endpoint.clone();
|
|
let entry_clone = entry.clone();
|
|
let auth_value = reqwest::header::HeaderValue::from_str(format!("Bearer {}", self.auth_token.clone()).as_str()).unwrap();
|
|
while retries < self.max_retries {
|
|
match self
|
|
.client
|
|
.post(&url)
|
|
.header(reqwest::header::AUTHORIZATION, auth_value.clone())
|
|
.json(&entry_clone)
|
|
.send()
|
|
.await
|
|
{
|
|
Ok(response) if response.status().is_success() => {
|
|
return;
|
|
}
|
|
_ => {
|
|
retries += 1;
|
|
if retries < self.max_retries {
|
|
tokio::time::sleep(tokio::time::Duration::from_millis(
|
|
self.retry_delay_ms * (1 << retries), // Exponential backoff
|
|
))
|
|
.await;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
eprintln!("Failed to send log to webhook after {0} retries", self.max_retries);
|
|
}
|
|
}
|
|
|
|
impl Drop for WebhookSink {
|
|
fn drop(&mut self) {
|
|
// Perform any necessary cleanup here
|
|
// For example, you might want to log that the sink is being dropped
|
|
eprintln!("Dropping WebhookSink with URL: {0}", self.endpoint);
|
|
}
|
|
}
|