aboutsummaryrefslogtreecommitdiff
path: root/src/api
diff options
context:
space:
mode:
Diffstat (limited to 'src/api')
-rw-r--r--src/api/Cargo.toml7
-rw-r--r--src/api/api_server.rs24
-rw-r--r--src/api/lib.rs2
-rw-r--r--src/api/s3_router.rs4
4 files changed, 33 insertions, 4 deletions
diff --git a/src/api/Cargo.toml b/src/api/Cargo.toml
index cc9635bb..968e8aab 100644
--- a/src/api/Cargo.toml
+++ b/src/api/Cargo.toml
@@ -26,11 +26,14 @@ err-derive = "0.3"
hex = "0.4"
hmac = "0.10"
idna = "0.2"
-log = "0.4"
+tracing = "0.1.30"
md-5 = "0.9"
nom = "7.1"
sha2 = "0.9"
+strum = "0.23"
+strum_macros = "0.23"
+
futures = "0.3"
futures-util = "0.3"
pin-project = "1.0"
@@ -49,3 +52,5 @@ serde_bytes = "0.11"
serde_json = "1.0"
quick-xml = { version = "0.21", features = [ "serialize" ] }
url = "2.1"
+
+opentelemetry = "0.17"
diff --git a/src/api/api_server.rs b/src/api/api_server.rs
index 322ea298..15b00dde 100644
--- a/src/api/api_server.rs
+++ b/src/api/api_server.rs
@@ -7,6 +7,11 @@ use hyper::server::conn::AddrStream;
use hyper::service::{make_service_fn, service_fn};
use hyper::{Body, Method, Request, Response, Server};
+use opentelemetry::{
+ trace::{FutureExt, TraceContextExt, Tracer},
+ Context,
+};
+
use garage_util::data::*;
use garage_util::error::Error as GarageError;
@@ -43,7 +48,20 @@ pub async fn run_api_server(
async move {
Ok::<_, GarageError>(service_fn(move |req: Request<Body>| {
let garage = garage.clone();
- handler(garage, req, client_addr)
+
+ let tracer = opentelemetry::global::tracer("garage");
+ let uuid = gen_uuid();
+ let span = tracer
+ .span_builder("S3 API call (unknown)")
+ .with_trace_id(
+ opentelemetry::trace::TraceId::from_hex(&hex::encode(
+ &uuid.as_slice()[..16],
+ ))
+ .unwrap(),
+ )
+ .start(&tracer);
+
+ handler(garage, req, client_addr).with_context(Context::current_with_span(span))
}))
}
});
@@ -111,6 +129,10 @@ async fn handler_inner(garage: Arc<Garage>, req: Request<Body>) -> Result<Respon
let (endpoint, bucket_name) = Endpoint::from_request(&req, bucket_name.map(ToOwned::to_owned))?;
debug!("Endpoint: {:?}", endpoint);
+ Context::current()
+ .span()
+ .update_name::<String>(format!("S3 API {}", endpoint));
+
// Some endpoints are processed early, before we even check for an API key
if let Endpoint::PostObject = endpoint {
return handle_post_object(garage, req, bucket_name.unwrap()).await;
diff --git a/src/api/lib.rs b/src/api/lib.rs
index 071cd7a6..f865325e 100644
--- a/src/api/lib.rs
+++ b/src/api/lib.rs
@@ -1,6 +1,6 @@
//! Crate for serving a S3 compatible API
#[macro_use]
-extern crate log;
+extern crate tracing;
pub mod error;
pub use error::Error;
diff --git a/src/api/s3_router.rs b/src/api/s3_router.rs
index 95a7eceb..c325805d 100644
--- a/src/api/s3_router.rs
+++ b/src/api/s3_router.rs
@@ -5,6 +5,8 @@ use std::borrow::Cow;
use hyper::header::HeaderValue;
use hyper::{HeaderMap, Method, Request};
+use strum_macros::Display;
+
/// This macro is used to generate very repetitive match {} blocks in this module
/// It is _not_ made to be used anywhere else
macro_rules! s3_match {
@@ -133,7 +135,7 @@ s3_match! {@func
/// query parameters). Parameters it may receive by header are left out, however headers are
/// considered when required to determine between one endpoint or another (for CopyObject and
/// UploadObject, for instance).
-#[derive(Debug, Clone, PartialEq, Eq)]
+#[derive(Debug, Clone, PartialEq, Eq, Display)]
pub enum Endpoint {
AbortMultipartUpload {
key: String,