mirror of
https://github.com/zed-industries/zed.git
synced 2024-12-27 12:02:07 +03:00
Add OpenMetrics endpoint exposing the basic RPC store metrics as guages
Co-authored-by: Antonio Scandurra <me@as-cii.com>
This commit is contained in:
parent
4032e517f9
commit
2e6fa889ea
22
Cargo.lock
generated
22
Cargo.lock
generated
@ -870,6 +870,7 @@ dependencies = [
|
|||||||
"nanoid",
|
"nanoid",
|
||||||
"parking_lot 0.11.2",
|
"parking_lot 0.11.2",
|
||||||
"project",
|
"project",
|
||||||
|
"prometheus",
|
||||||
"rand 0.8.5",
|
"rand 0.8.5",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"rpc",
|
"rpc",
|
||||||
@ -3401,6 +3402,21 @@ dependencies = [
|
|||||||
"workspace",
|
"workspace",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "prometheus"
|
||||||
|
version = "0.13.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cface98dfa6d645ea4c789839f176e4b072265d085bfcc48eaa8d137f58d3c39"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if 1.0.0",
|
||||||
|
"fnv",
|
||||||
|
"lazy_static",
|
||||||
|
"memchr",
|
||||||
|
"parking_lot 0.12.1",
|
||||||
|
"protobuf",
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "prost"
|
name = "prost"
|
||||||
version = "0.8.0"
|
version = "0.8.0"
|
||||||
@ -3477,6 +3493,12 @@ dependencies = [
|
|||||||
"prost 0.9.0",
|
"prost 0.9.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "protobuf"
|
||||||
|
version = "2.27.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cf7e6d18738ecd0902d30d1ad232c9125985a3422929b16c65517b38adc14f96"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pulldown-cmark"
|
name = "pulldown-cmark"
|
||||||
version = "0.9.1"
|
version = "0.9.1"
|
||||||
|
@ -31,6 +31,7 @@ lazy_static = "1.4"
|
|||||||
lipsum = { version = "0.8", optional = true }
|
lipsum = { version = "0.8", optional = true }
|
||||||
nanoid = "0.4"
|
nanoid = "0.4"
|
||||||
parking_lot = "0.11.1"
|
parking_lot = "0.11.1"
|
||||||
|
prometheus = "0.13"
|
||||||
rand = "0.8"
|
rand = "0.8"
|
||||||
reqwest = { version = "0.11", features = ["json"], optional = true }
|
reqwest = { version = "0.11", features = ["json"], optional = true }
|
||||||
scrypt = "0.7"
|
scrypt = "0.7"
|
||||||
|
@ -29,6 +29,7 @@ use futures::{
|
|||||||
FutureExt, SinkExt, StreamExt, TryStreamExt,
|
FutureExt, SinkExt, StreamExt, TryStreamExt,
|
||||||
};
|
};
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
|
use prometheus::{register_int_gauge, IntGauge};
|
||||||
use rpc::{
|
use rpc::{
|
||||||
proto::{self, AnyTypedEnvelope, EntityMessage, EnvelopedMessage, RequestMessage},
|
proto::{self, AnyTypedEnvelope, EntityMessage, EnvelopedMessage, RequestMessage},
|
||||||
Connection, ConnectionId, Peer, Receipt, TypedEnvelope,
|
Connection, ConnectionId, Peer, Receipt, TypedEnvelope,
|
||||||
@ -57,6 +58,18 @@ use tracing::{info_span, instrument, Instrument};
|
|||||||
|
|
||||||
pub use store::{Store, Worktree};
|
pub use store::{Store, Worktree};
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
static ref METRIC_CONNECTIONS: IntGauge =
|
||||||
|
register_int_gauge!("connections", "number of connections").unwrap();
|
||||||
|
static ref METRIC_PROJECTS: IntGauge =
|
||||||
|
register_int_gauge!("projects", "number of open projects").unwrap();
|
||||||
|
static ref METRIC_SHARED_PROJECTS: IntGauge = register_int_gauge!(
|
||||||
|
"shared_projects",
|
||||||
|
"number of open projects with one or more guests"
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
type MessageHandler =
|
type MessageHandler =
|
||||||
Box<dyn Send + Sync + Fn(Arc<Server>, Box<dyn AnyTypedEnvelope>) -> BoxFuture<'static, ()>>;
|
Box<dyn Send + Sync + Fn(Arc<Server>, Box<dyn AnyTypedEnvelope>) -> BoxFuture<'static, ()>>;
|
||||||
|
|
||||||
@ -1534,6 +1547,11 @@ impl<'a> Drop for StoreWriteGuard<'a> {
|
|||||||
self.check_invariants();
|
self.check_invariants();
|
||||||
|
|
||||||
let metrics = self.metrics();
|
let metrics = self.metrics();
|
||||||
|
|
||||||
|
METRIC_CONNECTIONS.set(metrics.connections as _);
|
||||||
|
METRIC_PROJECTS.set(metrics.registered_projects as _);
|
||||||
|
METRIC_SHARED_PROJECTS.set(metrics.shared_projects as _);
|
||||||
|
|
||||||
tracing::info!(
|
tracing::info!(
|
||||||
connections = metrics.connections,
|
connections = metrics.connections,
|
||||||
registered_projects = metrics.registered_projects,
|
registered_projects = metrics.registered_projects,
|
||||||
@ -1609,6 +1627,7 @@ pub fn routes(server: Arc<Server>) -> Router<Body> {
|
|||||||
.layer(middleware::from_fn(auth::validate_header))
|
.layer(middleware::from_fn(auth::validate_header))
|
||||||
.layer(Extension(server)),
|
.layer(Extension(server)),
|
||||||
)
|
)
|
||||||
|
.route("/metrics", get(handle_metrics))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn handle_websocket_request(
|
pub async fn handle_websocket_request(
|
||||||
@ -1642,6 +1661,19 @@ pub async fn handle_websocket_request(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn handle_metrics() -> axum::response::Response {
|
||||||
|
let encoder = prometheus::TextEncoder::new();
|
||||||
|
let metric_families = prometheus::gather();
|
||||||
|
match encoder.encode_to_string(&metric_families) {
|
||||||
|
Ok(string) => (StatusCode::OK, string).into_response(),
|
||||||
|
Err(error) => (
|
||||||
|
StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
format!("failed to encode metrics {:?}", error),
|
||||||
|
)
|
||||||
|
.into_response(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn to_axum_message(message: TungsteniteMessage) -> AxumMessage {
|
fn to_axum_message(message: TungsteniteMessage) -> AxumMessage {
|
||||||
match message {
|
match message {
|
||||||
TungsteniteMessage::Text(payload) => AxumMessage::Text(payload),
|
TungsteniteMessage::Text(payload) => AxumMessage::Text(payload),
|
||||||
|
Loading…
Reference in New Issue
Block a user