Skip to content

Commit 42f73e7

Browse files
committed
runtimes/core: Add requests counter metric
1 parent 28373a2 commit 42f73e7

File tree

17 files changed

+1948
-108
lines changed

17 files changed

+1948
-108
lines changed

Cargo.lock

Lines changed: 609 additions & 99 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

runtimes/core/Cargo.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ rttrace = []
1010
[dependencies]
1111
pingora = { version = "0.4", features = ["lb", "openssl"] }
1212
anyhow = "1.0.76"
13+
async-trait = "0.1"
1314
base64 = "0.21.5"
1415
gjson = "0.8.1"
1516
prost = "0.12.3"
@@ -123,6 +124,12 @@ email_address = "0.2.9"
123124
cookie = "0.18.1"
124125
malachite = "0.6.1"
125126
byteorder = "1.5.0"
127+
metrics = "0.24.2"
128+
metrics-util = { version = "0.20.0", features = ["registry", "storage"] }
129+
dashmap = "6.1.0"
130+
google-cloud-monitoring-v3 = "1.0.0"
131+
google-cloud-api = "1.0.0"
132+
google-cloud-wkt = "1.0.0"
126133

127134
[build-dependencies]
128135
prost-build = "0.12.3"

runtimes/core/src/api/auth/local.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use crate::api::auth::{AuthHandler, AuthPayload, AuthRequest, AuthResponse};
22
use crate::api::schema::encoding::Schema;
33
use crate::api::{APIResult, HandlerResponse, HandlerResponseInner, PValues};
44
use crate::log::LogFromRust;
5+
use crate::metrics::Counter;
56
use crate::model::{AuthRequestData, RequestData};
67
use crate::trace::Tracer;
78
use crate::{api, model, EndpointName};
@@ -14,6 +15,7 @@ pub struct LocalAuthHandler {
1415
pub schema: Schema,
1516
pub handler: RwLock<Option<Arc<dyn api::TypedHandler>>>,
1617
pub tracer: Tracer,
18+
pub requests_total: Counter,
1719
}
1820

1921
impl LocalAuthHandler {
@@ -152,7 +154,9 @@ impl AuthHandler for LocalAuthHandler {
152154
user_id: auth_uid.clone(),
153155
})),
154156
};
157+
155158
self.tracer.request_span_end(&model_resp, false);
159+
self.requests_total.increment_with([("code", "ok")]);
156160
Ok(AuthResponse::Authenticated {
157161
auth_uid,
158162
auth_data,
@@ -165,6 +169,8 @@ impl AuthHandler for LocalAuthHandler {
165169
data: model::ResponseData::Auth(Err(e.clone())),
166170
};
167171
self.tracer.request_span_end(&model_resp, false);
172+
self.requests_total
173+
.increment_with([("code", e.code.to_string())]);
168174
Err(e)
169175
}
170176
}

runtimes/core/src/api/endpoint.rs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use crate::api::{jsonschema, schema, ErrCode, Error};
2323
use crate::encore::parser::meta::v1::rpc;
2424
use crate::encore::parser::meta::v1::{self as meta, selector};
2525
use crate::log::LogFromRust;
26+
use crate::metrics::Counter;
2627
use crate::model::StreamDirection;
2728
use crate::names::EndpointName;
2829
use crate::trace;
@@ -406,6 +407,7 @@ pub(super) struct EndpointHandler {
406407
pub endpoint: Arc<Endpoint>,
407408
pub handler: Arc<dyn BoxedHandler>,
408409
pub shared: Arc<SharedEndpointData>,
410+
pub requests_total: Counter,
409411
}
410412

411413
#[derive(Debug)]
@@ -427,6 +429,7 @@ impl Clone for EndpointHandler {
427429
endpoint: self.endpoint.clone(),
428430
handler: self.handler.clone(),
429431
shared: self.shared.clone(),
432+
requests_total: self.requests_total.clone(),
430433
}
431434
}
432435
}
@@ -601,7 +604,6 @@ impl EndpointHandler {
601604
let duration = tokio::time::Instant::now().duration_since(request.start);
602605

603606
// If we had a request failure, log that separately.
604-
605607
if let ResponseData::Typed(Err(err)) = &resp {
606608
logger.error(Some(&request), "request failed", Some(err), {
607609
let mut fields = crate::log::Fields::new();
@@ -629,6 +631,12 @@ impl EndpointHandler {
629631
});
630632
}
631633

634+
let code = match &resp {
635+
ResponseData::Typed(Ok(_)) => "ok".to_string(),
636+
ResponseData::Typed(Err(err)) => err.code.to_string(),
637+
ResponseData::Raw(resp) => ErrCode::from(resp.status()).to_string(),
638+
};
639+
632640
logger.info(Some(&request), "request completed", {
633641
let mut fields = crate::log::Fields::new();
634642
let dur_ms = (duration.as_secs() as f64 * 1000f64)
@@ -644,13 +652,7 @@ impl EndpointHandler {
644652
)),
645653
);
646654

647-
let code = match &resp {
648-
ResponseData::Typed(Ok(_)) => "ok".to_string(),
649-
ResponseData::Typed(Err(err)) => err.code.to_string(),
650-
ResponseData::Raw(resp) => ErrCode::from(resp.status()).to_string(),
651-
};
652-
653-
fields.insert("code".into(), serde_json::Value::String(code));
655+
fields.insert("code".into(), serde_json::Value::String(code.clone()));
654656
Some(fields)
655657
});
656658

@@ -685,6 +687,7 @@ impl EndpointHandler {
685687
}),
686688
};
687689
self.shared.tracer.request_span_end(&model_resp, sensitive);
690+
self.requests_total.increment_with([("code", code)]);
688691
}
689692

690693
if let Ok(val) = HeaderValue::from_str(request.span.0.serialize_encore().as_str()) {

runtimes/core/src/api/manager.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use crate::api::{
1818
};
1919
use crate::encore::parser::meta::v1 as meta;
2020
use crate::encore::runtime::v1 as runtime;
21+
use crate::metrics::requests_total_counter;
2122
use crate::trace::Tracer;
2223
use crate::{api, model, pubsub, secrets, EncoreName, EndpointName, Hosted};
2324

@@ -283,6 +284,7 @@ fn build_auth_handler(
283284
// let is_local = hosted_services.contains(&explicit.service_name);
284285
let is_local = true;
285286
let name = EndpointName::new(explicit.service_name.clone(), auth.name.clone());
287+
let requests_total = requests_total_counter(&explicit.service_name, &auth.name);
286288

287289
let auth_data = registry.schema(auth_data_schema_idx);
288290
let auth_handler = if is_local {
@@ -294,6 +296,7 @@ fn build_auth_handler(
294296
schema,
295297
handler: Default::default(),
296298
tracer,
299+
requests_total,
297300
},
298301
)?
299302
} else {

runtimes/core/src/api/server.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use crate::api::static_assets::StaticAssetsHandler;
1212
use crate::api::{self, ToResponse};
1313
use crate::api::{paths, reqauth, schema, BoxedHandler, EndpointMap};
1414
use crate::encore::parser::meta::v1 as meta;
15+
use crate::metrics::requests_total_counter;
1516
use crate::names::EndpointName;
1617
use crate::trace;
1718

@@ -92,11 +93,14 @@ impl Server {
9293
// For static asset routes, configure the static asset handler directly.
9394
// There's no need to defer it for dynamic runtime registration.
9495
let static_handler = StaticAssetsHandler::new(assets);
96+
let requests_total =
97+
requests_total_counter(&ep.name.service(), &ep.name.endpoint());
9598

9699
let handler = EndpointHandler {
97100
endpoint: ep.clone(),
98101
handler: Arc::new(static_handler),
99102
shared: shared.clone(),
103+
requests_total,
100104
};
101105
server_handler.set(handler);
102106
}
@@ -153,11 +157,14 @@ impl Server {
153157
None => Ok(()), // anyhow::bail!("no handler found for endpoint: {}", endpoint_name),
154158
Some(h) => {
155159
let endpoint = self.endpoints.get(&endpoint_name).unwrap().to_owned();
160+
let requests_total =
161+
requests_total_counter(&endpoint.name.service(), &endpoint.name.endpoint());
156162

157163
let handler = EndpointHandler {
158164
endpoint,
159165
handler,
160166
shared: self.shared.clone(),
167+
requests_total,
161168
};
162169

163170
h.add(handler);

runtimes/core/src/lib.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ pub mod error;
2424
pub mod infracfg;
2525
pub mod log;
2626
pub mod meta;
27+
pub mod metadata;
28+
pub mod metrics;
2729
pub mod model;
2830
mod names;
2931
pub mod objects;
@@ -209,6 +211,7 @@ pub struct Runtime {
209211
app_meta: meta::AppMeta,
210212
compute: ComputeConfig,
211213
runtime: tokio::runtime::Runtime,
214+
metrics: metrics::Manager,
212215
}
213216

214217
impl Runtime {
@@ -238,6 +241,7 @@ impl Runtime {
238241

239242
let mut deployment = cfg.deployment.take().unwrap_or_default();
240243
let service_discovery = deployment.service_discovery.take().unwrap_or_default();
244+
let observability = deployment.observability.take().unwrap_or_default();
241245

242246
let http_client = reqwest::Client::builder()
243247
.build()
@@ -250,11 +254,18 @@ impl Runtime {
250254
);
251255
let platform_validator = Arc::new(platform_validator);
252256

257+
// Initialize metrics manager from runtime config
258+
let metrics_manager = metrics::Manager::from_runtime_config(
259+
&observability,
260+
&environment,
261+
&http_client,
262+
tokio_rt.handle().clone(),
263+
);
264+
253265
// Set up observability.
254266
let disable_tracing =
255267
testing || std::env::var("ENCORE_NOTRACE").is_ok_and(|v| !v.is_empty());
256268
let tracer = if !disable_tracing {
257-
let observability = deployment.observability.take().unwrap_or_default();
258269
let trace_endpoint = observability
259270
.tracing
260271
.into_iter()
@@ -411,6 +422,7 @@ impl Runtime {
411422
app_meta,
412423
compute,
413424
runtime: tokio_rt,
425+
metrics: metrics_manager,
414426
})
415427
}
416428

@@ -444,6 +456,11 @@ impl Runtime {
444456
&self.api
445457
}
446458

459+
#[inline]
460+
pub fn metrics(&self) -> &metrics::Manager {
461+
&self.metrics
462+
}
463+
447464
#[inline]
448465
pub fn endpoints(&self) -> &api::EndpointMap {
449466
self.api.endpoints()

0 commit comments

Comments
 (0)