Skip to content

Commit c448a3c

Browse files
committed
feat(axiom sink): Add regional edge support for data ingestion
Adds a new optional `region` configuration field to the axiom sink that allows users to specify a regional edge URL for data ingestion. When configured, data is sent to the regional edge endpoint instead of the default cloud endpoint. This enables: - Improved data locality and regional compliance - Support for both production (axiom.co) and testing (e.g., axiomtestlabs.co) domains - Backward compatibility - existing configurations continue to work unchanged Example configuration: ```yaml [sinks.axiom] type = "axiom" token = "${AXIOM_TOKEN}" dataset = "my-dataset" region = "https://eu-central-1.aws.edge.axiom.co" ``` The implementation uses the new edge endpoint format: `{region}/v1/ingest/{dataset}` when region is set, otherwise falls back to the existing cloud endpoint format: `{url}/v1/datasets/{dataset}/ingest`
1 parent 3146eca commit c448a3c

File tree

2 files changed

+75
-0
lines changed

2 files changed

+75
-0
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
The `axiom` sink now supports regional edges for data locality. A new optional `region` configuration field allows you to specify the full regional edge URL (e.g., `https://eu-central-1.aws.edge.axiom.co`, `https://us-east-1.aws.edge.axiom.co`). When configured, data is sent to the regional edge endpoint instead of the default cloud endpoint.
2+
3+
authors: toppercodes

src/sinks/axiom.rs

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ pub struct AxiomConfig {
3030
/// URI of the Axiom endpoint to send data to.
3131
///
3232
/// Only required if not using Axiom Cloud.
33+
/// Note: This is ignored if `region` is set.
3334
#[configurable(validation(format = "uri"))]
3435
#[configurable(metadata(docs::examples = "https://axiom.my-domain.com"))]
3536
#[configurable(metadata(docs::examples = "${AXIOM_URL}"))]
@@ -52,6 +53,15 @@ pub struct AxiomConfig {
5253
#[configurable(metadata(docs::examples = "vector_rocks"))]
5354
dataset: String,
5455

56+
/// The Axiom regional edge URL to use for ingestion.
57+
///
58+
/// When set, data will be sent to the regional edge endpoint instead of the default cloud endpoint.
59+
#[configurable(validation(format = "uri"))]
60+
#[configurable(metadata(docs::examples = "${AXIOM_REGION}"))]
61+
#[configurable(metadata(docs::examples = "https://eu-central-1.aws.edge.axiom.co"))]
62+
#[configurable(metadata(docs::examples = "https://us-east-1.aws.edge.axiom.co"))]
63+
region: Option<String>,
64+
5565
#[configurable(derived)]
5666
#[serde(default)]
5767
request: RequestConfig,
@@ -150,6 +160,11 @@ impl SinkConfig for AxiomConfig {
150160

151161
impl AxiomConfig {
152162
fn build_endpoint(&self) -> String {
163+
if let Some(region_url) = &self.region {
164+
let region_url = region_url.trim_end_matches('/');
165+
return format!("{}/v1/ingest/{}", region_url, self.dataset);
166+
}
167+
153168
let url = if let Some(url) = self.url.as_ref() {
154169
url.clone()
155170
} else {
@@ -182,6 +197,63 @@ mod test {
182197
"https://axiom.my-domain.com/v1/datasets/vector_rocks/ingest"
183198
);
184199
}
200+
201+
#[test]
202+
fn test_regional_edge_endpoint() {
203+
let config = super::AxiomConfig {
204+
region: Some("https://eu-central-1.aws.edge.axiom.co".to_string()),
205+
dataset: "vector_rocks".to_string(),
206+
..Default::default()
207+
};
208+
let endpoint = config.build_endpoint();
209+
assert_eq!(
210+
endpoint,
211+
"https://eu-central-1.aws.edge.axiom.co/v1/ingest/vector_rocks"
212+
);
213+
214+
// Test with trailing slash in region URL
215+
let config = super::AxiomConfig {
216+
region: Some("https://us-east-1.aws.edge.axiom.co/".to_string()),
217+
dataset: "my-dataset".to_string(),
218+
..Default::default()
219+
};
220+
let endpoint = config.build_endpoint();
221+
assert_eq!(
222+
endpoint,
223+
"https://us-east-1.aws.edge.axiom.co/v1/ingest/my-dataset"
224+
);
225+
}
226+
227+
#[test]
228+
fn test_regional_edge_with_custom_domain() {
229+
// Regional edge with custom domain (e.g., testing environment)
230+
let config = super::AxiomConfig {
231+
region: Some("https://eu-central-1.aws.edge.axiomtestlabs.co".to_string()),
232+
dataset: "test-dataset".to_string(),
233+
..Default::default()
234+
};
235+
let endpoint = config.build_endpoint();
236+
assert_eq!(
237+
endpoint,
238+
"https://eu-central-1.aws.edge.axiomtestlabs.co/v1/ingest/test-dataset"
239+
);
240+
}
241+
242+
#[test]
243+
fn test_region_takes_precedence() {
244+
// When both region and url are set, region takes precedence
245+
let config = super::AxiomConfig {
246+
url: Some("https://api.axiom.co".to_string()),
247+
region: Some("https://us-west-1.aws.edge.axiom.co".to_string()),
248+
dataset: "my-dataset".to_string(),
249+
..Default::default()
250+
};
251+
let endpoint = config.build_endpoint();
252+
assert_eq!(
253+
endpoint,
254+
"https://us-west-1.aws.edge.axiom.co/v1/ingest/my-dataset"
255+
);
256+
}
185257
}
186258

187259
#[cfg(feature = "axiom-integration-tests")]

0 commit comments

Comments
 (0)