Skip to content

Commit 9c1c13d

Browse files
authored
Add ingestion API (#210)
Add another API to ingest log data. This will push logs to stream name present in header `x-p-stream-name`
1 parent 77cf001 commit 9c1c13d

File tree

3 files changed

+37
-2
lines changed

3 files changed

+37
-2
lines changed

server/src/handlers/event.rs

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,14 @@ use crate::event;
2525
use crate::query::Query;
2626
use crate::response::QueryResponse;
2727
use crate::s3::S3;
28-
use crate::utils::header_parsing::collect_labelled_headers;
28+
use crate::utils::header_parsing::{collect_labelled_headers, ParseHeaderError};
2929
use crate::utils::{self, flatten_json_body, merge};
3030

3131
use self::error::{PostError, QueryError};
3232

3333
const PREFIX_TAGS: &str = "x-p-tag-";
3434
const PREFIX_META: &str = "x-p-meta-";
35+
const STREAM_NAME_HEADER_KEY: &str = "x-p-stream-name";
3536
const SEPARATOR: char = '^';
3637

3738
pub async fn query(_req: HttpRequest, json: web::Json<Value>) -> Result<HttpResponse, QueryError> {
@@ -48,12 +49,38 @@ pub async fn query(_req: HttpRequest, json: web::Json<Value>) -> Result<HttpResp
4849
.map_err(|e| e.into())
4950
}
5051

52+
pub async fn ingest(
53+
req: HttpRequest,
54+
body: web::Json<serde_json::Value>,
55+
) -> Result<HttpResponse, PostError> {
56+
if let Some((_, stream_name)) = req
57+
.headers()
58+
.iter()
59+
.find(|&(key, _)| key == STREAM_NAME_HEADER_KEY)
60+
{
61+
push_logs(stream_name.to_str().unwrap().to_owned(), req, body).await?;
62+
63+
Ok(HttpResponse::Ok().finish())
64+
} else {
65+
Err(PostError::Header(ParseHeaderError::MissingStreamName))
66+
}
67+
}
68+
5169
pub async fn post_event(
5270
req: HttpRequest,
5371
body: web::Json<serde_json::Value>,
5472
) -> Result<HttpResponse, PostError> {
5573
let stream_name: String = req.match_info().get("logstream").unwrap().parse().unwrap();
74+
push_logs(stream_name, req, body).await?;
5675

76+
Ok(HttpResponse::Ok().finish())
77+
}
78+
79+
async fn push_logs(
80+
stream_name: String,
81+
req: HttpRequest,
82+
body: web::Json<serde_json::Value>,
83+
) -> Result<(), PostError> {
5784
let tags = HashMap::from([(
5885
"p_tags".to_string(),
5986
collect_labelled_headers(&req, PREFIX_TAGS, SEPARATOR)?,
@@ -89,7 +116,7 @@ pub async fn post_event(
89116
event.process().await?;
90117
}
91118

92-
Ok(HttpResponse::Ok().finish())
119+
Ok(())
93120
}
94121

95122
pub mod error {

server/src/main.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,8 @@ pub fn configure_routes(cfg: &mut web::ServiceConfig) {
259259
web::scope(&base_path())
260260
// POST "/query" ==> Get results of the SQL query passed in request body
261261
.service(web::resource(query_path()).route(web::post().to(handlers::event::query)))
262+
// POST "/ingest" ==> Post logs to given log stream based on header
263+
.service(web::resource(ingest_path()).route(web::post().to(handlers::event::ingest)))
262264
.service(
263265
// logstream API
264266
web::resource(logstream_path("{logstream}"))
@@ -341,6 +343,10 @@ fn query_path() -> String {
341343
"/query".to_string()
342344
}
343345

346+
fn ingest_path() -> String {
347+
"/ingest".to_string()
348+
}
349+
344350
fn alert_path(stream_name: &str) -> String {
345351
format!("{}/alert", logstream_path(stream_name))
346352
}

server/src/utils.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ pub mod header_parsing {
103103
SeperatorInKey(char),
104104
#[error("A value passed in header contains reserved char {0}")]
105105
SeperatorInValue(char),
106+
#[error("Stream name not found in header")]
107+
MissingStreamName,
106108
}
107109

108110
impl ResponseError for ParseHeaderError {

0 commit comments

Comments
 (0)