aboutsummaryrefslogtreecommitdiff
path: root/src/api
diff options
context:
space:
mode:
authorAlex Auvolat <alex@adnab.me>2022-09-08 15:50:56 +0200
committerAlex Auvolat <alex@adnab.me>2022-09-08 15:50:56 +0200
commit7f54706b95beb033820924e77e18f21f241d223e (patch)
tree26fc26ebb80e15a1ca64edd03efc9fac758274d0 /src/api
parent907054775dc71a10a92ab96112889db9113130ab (diff)
parentd9d199a6c9c0ae2a6ee2b04103c78ef1eb311956 (diff)
downloadgarage-7f54706b95beb033820924e77e18f21f241d223e.tar.gz
garage-7f54706b95beb033820924e77e18f21f241d223e.zip
Merge branch 'lx-perf-improvements' into netapp-stream-body
Diffstat (limited to 'src/api')
-rw-r--r--src/api/Cargo.toml18
-rw-r--r--src/api/admin/api_server.rs74
-rw-r--r--src/api/admin/cluster.rs4
-rw-r--r--src/api/k2v/api_server.rs14
-rw-r--r--src/api/s3/api_server.rs14
5 files changed, 65 insertions, 59 deletions
diff --git a/src/api/Cargo.toml b/src/api/Cargo.toml
index 901cb959..cdfabcb8 100644
--- a/src/api/Cargo.toml
+++ b/src/api/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "garage_api"
-version = "0.7.0"
+version = "0.8.0"
authors = ["Alex Auvolat <alex@adnab.me>"]
edition = "2018"
license = "AGPL-3.0"
@@ -14,11 +14,11 @@ path = "lib.rs"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
-garage_model = { version = "0.7.0", path = "../model" }
-garage_table = { version = "0.7.0", path = "../table" }
-garage_block = { version = "0.7.0", path = "../block" }
-garage_util = { version = "0.7.0", path = "../util" }
-garage_rpc = { version = "0.7.0", path = "../rpc" }
+garage_model = { version = "0.8.0", path = "../model" }
+garage_table = { version = "0.8.0", path = "../table" }
+garage_block = { version = "0.8.0", path = "../block" }
+garage_util = { version = "0.8.0", path = "../util" }
+garage_rpc = { version = "0.8.0", path = "../rpc" }
async-trait = "0.1.7"
base64 = "0.13"
@@ -54,9 +54,9 @@ quick-xml = { version = "0.21", features = [ "serialize" ] }
url = "2.1"
opentelemetry = "0.17"
-opentelemetry-prometheus = "0.10"
-opentelemetry-otlp = "0.10"
-prometheus = "0.13"
+opentelemetry-prometheus = { version = "0.10", optional = true }
+prometheus = { version = "0.13", optional = true }
[features]
k2v = [ "garage_util/k2v", "garage_model/k2v" ]
+metrics = [ "opentelemetry-prometheus", "prometheus" ]
diff --git a/src/api/admin/api_server.rs b/src/api/admin/api_server.rs
index c3b16715..fb0078cc 100644
--- a/src/api/admin/api_server.rs
+++ b/src/api/admin/api_server.rs
@@ -1,15 +1,17 @@
+use std::net::SocketAddr;
use std::sync::Arc;
use async_trait::async_trait;
use futures::future::Future;
-use http::header::{
- ACCESS_CONTROL_ALLOW_METHODS, ACCESS_CONTROL_ALLOW_ORIGIN, ALLOW, CONTENT_TYPE,
-};
+use http::header::{ACCESS_CONTROL_ALLOW_METHODS, ACCESS_CONTROL_ALLOW_ORIGIN, ALLOW};
use hyper::{Body, Request, Response};
-use opentelemetry::trace::{SpanRef, Tracer};
+use opentelemetry::trace::SpanRef;
+
+#[cfg(feature = "metrics")]
use opentelemetry_prometheus::PrometheusExporter;
+#[cfg(feature = "metrics")]
use prometheus::{Encoder, TextEncoder};
use garage_model::garage::Garage;
@@ -25,6 +27,7 @@ use crate::admin::router::{Authorization, Endpoint};
pub struct AdminApiServer {
garage: Arc<Garage>,
+ #[cfg(feature = "metrics")]
exporter: PrometheusExporter,
metrics_token: Option<String>,
admin_token: Option<String>,
@@ -32,7 +35,6 @@ pub struct AdminApiServer {
impl AdminApiServer {
pub fn new(garage: Arc<Garage>) -> Self {
- let exporter = opentelemetry_prometheus::exporter().init();
let cfg = &garage.config.admin;
let metrics_token = cfg
.metrics_token
@@ -44,21 +46,22 @@ impl AdminApiServer {
.map(|tok| format!("Bearer {}", tok));
Self {
garage,
- exporter,
+ #[cfg(feature = "metrics")]
+ exporter: opentelemetry_prometheus::exporter().init(),
metrics_token,
admin_token,
}
}
- pub async fn run(self, shutdown_signal: impl Future<Output = ()>) -> Result<(), GarageError> {
- if let Some(bind_addr) = self.garage.config.admin.api_bind_addr {
- let region = self.garage.config.s3_api.s3_region.clone();
- ApiServer::new(region, self)
- .run_server(bind_addr, shutdown_signal)
- .await
- } else {
- Ok(())
- }
+ pub async fn run(
+ self,
+ bind_addr: SocketAddr,
+ shutdown_signal: impl Future<Output = ()>,
+ ) -> Result<(), GarageError> {
+ let region = self.garage.config.s3_api.s3_region.clone();
+ ApiServer::new(region, self)
+ .run_server(bind_addr, shutdown_signal)
+ .await
}
fn handle_options(&self, _req: &Request<Body>) -> Result<Response<Body>, Error> {
@@ -71,22 +74,31 @@ impl AdminApiServer {
}
fn handle_metrics(&self) -> Result<Response<Body>, Error> {
- let mut buffer = vec![];
- let encoder = TextEncoder::new();
-
- let tracer = opentelemetry::global::tracer("garage");
- let metric_families = tracer.in_span("admin/gather_metrics", |_| {
- self.exporter.registry().gather()
- });
-
- encoder
- .encode(&metric_families, &mut buffer)
- .ok_or_internal_error("Could not serialize metrics")?;
-
- Ok(Response::builder()
- .status(200)
- .header(CONTENT_TYPE, encoder.format_type())
- .body(Body::from(buffer))?)
+ #[cfg(feature = "metrics")]
+ {
+ use opentelemetry::trace::Tracer;
+
+ let mut buffer = vec![];
+ let encoder = TextEncoder::new();
+
+ let tracer = opentelemetry::global::tracer("garage");
+ let metric_families = tracer.in_span("admin/gather_metrics", |_| {
+ self.exporter.registry().gather()
+ });
+
+ encoder
+ .encode(&metric_families, &mut buffer)
+ .ok_or_internal_error("Could not serialize metrics")?;
+
+ Ok(Response::builder()
+ .status(200)
+ .header(http::header::CONTENT_TYPE, encoder.format_type())
+ .body(Body::from(buffer))?)
+ }
+ #[cfg(not(feature = "metrics"))]
+ Err(Error::bad_request(
+ "Garage was built without the metrics feature".to_string(),
+ ))
}
}
diff --git a/src/api/admin/cluster.rs b/src/api/admin/cluster.rs
index 4b7716a3..99c6e332 100644
--- a/src/api/admin/cluster.rs
+++ b/src/api/admin/cluster.rs
@@ -18,7 +18,8 @@ use crate::helpers::{json_ok_response, parse_json_body};
pub async fn handle_get_cluster_status(garage: &Arc<Garage>) -> Result<Response<Body>, Error> {
let res = GetClusterStatusResponse {
node: hex::encode(garage.system.id),
- garage_version: garage.system.garage_version(),
+ garage_version: garage_util::version::garage_version(),
+ garage_features: garage_util::version::garage_features(),
db_engine: garage.db.engine(),
known_nodes: garage
.system
@@ -99,6 +100,7 @@ fn get_cluster_layout(garage: &Arc<Garage>) -> GetClusterLayoutResponse {
struct GetClusterStatusResponse {
node: String,
garage_version: &'static str,
+ garage_features: Option<&'static [&'static str]>,
db_engine: String,
known_nodes: HashMap<String, KnownNodeResp>,
layout: GetClusterLayoutResponse,
diff --git a/src/api/k2v/api_server.rs b/src/api/k2v/api_server.rs
index eb0fbdd7..084867b5 100644
--- a/src/api/k2v/api_server.rs
+++ b/src/api/k2v/api_server.rs
@@ -1,3 +1,4 @@
+use std::net::SocketAddr;
use std::sync::Arc;
use async_trait::async_trait;
@@ -36,20 +37,13 @@ pub(crate) struct K2VApiEndpoint {
impl K2VApiServer {
pub async fn run(
garage: Arc<Garage>,
+ bind_addr: SocketAddr,
+ s3_region: String,
shutdown_signal: impl Future<Output = ()>,
) -> Result<(), GarageError> {
- if let Some(cfg) = &garage.config.k2v_api {
- let bind_addr = cfg.api_bind_addr;
-
- ApiServer::new(
- garage.config.s3_api.s3_region.clone(),
- K2VApiServer { garage },
- )
+ ApiServer::new(s3_region, K2VApiServer { garage })
.run_server(bind_addr, shutdown_signal)
.await
- } else {
- Ok(())
- }
}
}
diff --git a/src/api/s3/api_server.rs b/src/api/s3/api_server.rs
index 78dfeeac..27837297 100644
--- a/src/api/s3/api_server.rs
+++ b/src/api/s3/api_server.rs
@@ -1,3 +1,4 @@
+use std::net::SocketAddr;
use std::sync::Arc;
use async_trait::async_trait;
@@ -43,16 +44,13 @@ pub(crate) struct S3ApiEndpoint {
impl S3ApiServer {
pub async fn run(
garage: Arc<Garage>,
+ addr: SocketAddr,
+ s3_region: String,
shutdown_signal: impl Future<Output = ()>,
) -> Result<(), GarageError> {
- let addr = garage.config.s3_api.api_bind_addr;
-
- ApiServer::new(
- garage.config.s3_api.s3_region.clone(),
- S3ApiServer { garage },
- )
- .run_server(addr, shutdown_signal)
- .await
+ ApiServer::new(s3_region, S3ApiServer { garage })
+ .run_server(addr, shutdown_signal)
+ .await
}
async fn handle_request_without_bucket(