use anyhow::{Context, Result};
use reqwest::blocking::Client;
use reqwest::header::HeaderValue;
use serde_json::Value;
pub fn post_chunks(
client: &Client,
url: &str,
api_key: &str,
chunks: Vec<Vec<Value>>,
) -> Result<()> {
let mut first_err: Option<anyhow::Error> = None;
let total = chunks.len();
for (idx, chunk) in chunks.into_iter().enumerate() {
match post_one(client, url, api_key, &chunk) {
Ok(()) => {}
Err(e) => {
tracing::warn!(chunk = idx + 1, total, error = %e, "datadog chunk POST failed");
if first_err.is_none() {
first_err = Some(e);
}
}
}
}
if let Some(e) = first_err {
return Err(e.context("datadog logs POST"));
}
Ok(())
}
fn post_one(client: &Client, url: &str, api_key: &str, chunk: &[Value]) -> Result<()> {
let mut key = HeaderValue::from_str(api_key)
.map_err(|e| anyhow::anyhow!("invalid Datadog API key: {e}"))?;
key.set_sensitive(true);
client
.post(url)
.header("Content-Type", "application/json")
.header("DD-API-KEY", key)
.json(&chunk)
.send()
.context("send")?
.error_for_status()
.context("status")?;
Ok(())
}