From b05e51152fdd7a638bfb9cf7237c131ce2d7a4a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcel=20M=C3=A4rtens?= Date: Sat, 7 Sep 2019 15:10:57 +0200 Subject: [PATCH] update version, revert from static prometheus back to normal because static doesnt supprot registries, and implement most of the metrics except for entity count --- Cargo.lock | 8 ++-- common/src/terrain/chonk.rs | 34 ++++++++++++++ server/Cargo.toml | 2 +- server/src/lib.rs | 62 ++++++++++++++++++++---- server/src/metrics.rs | 94 +++++++++++++++++++++---------------- 5 files changed, 146 insertions(+), 54 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 49e64aa65a..0a547fbf34 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2461,7 +2461,7 @@ dependencies = [ [[package]] name = "prometheus-static-metric" -version = "0.1.4" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3091,7 +3091,7 @@ dependencies = [ [[package]] name = "specs-idvs" version = "0.1.0" -source = "git+https://gitlab.com/veloren/specs-idvs.git#18ad795469f45d58fdcfcb4ee48435b2061bc7bc" +source = "git+https://gitlab.com/veloren/specs-idvs.git#4ce792042f951a29874954582234836c0eccaed6" dependencies = [ "hibitset 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", "specs 0.14.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3584,7 +3584,7 @@ dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "prometheus 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "prometheus-static-metric 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "prometheus-static-metric 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "ron 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "scan_fmt 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -4151,7 +4151,7 @@ dependencies = [ "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" "checksum proc-macro2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4c5c2380ae88876faae57698be9e9775e3544decad214599c3a6266cca6ac802" "checksum prometheus 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5567486d5778e2c6455b1b90ff1c558f29e751fc018130fa182e15828e728af1" -"checksum prometheus-static-metric 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1d2b4a6a1ae793e7eb6773a5301a5a08e8929ea5517b677c93e57ce2d0973c02" +"checksum prometheus-static-metric 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1baa57413523cff73783204f73299a3f602ebcf51a5e64752b32bc1b3c376013" "checksum protobuf 2.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "40361836defdd5871ff7e84096c6f6444af7fc157f8ef1789f54f147687caa20" "checksum quasi 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18c45c4854d6d1cf5d531db97c75880feb91c958b0720f4ec1057135fec358b3" "checksum quasi_codegen 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "51b9e25fa23c044c1803f43ca59c98dac608976dd04ce799411edd58ece776d4" diff --git a/common/src/terrain/chonk.rs b/common/src/terrain/chonk.rs index 1b1dfa6496..2ed46585ea 100644 --- a/common/src/terrain/chonk.rs +++ b/common/src/terrain/chonk.rs @@ -267,6 +267,40 @@ impl<'a, V: Vox, S: RectVolSize, M: Clone> IntoPosIterator for &'a Chonk usize { + self.chonks + } + pub fn homogeneous(&self) -> usize { + self.homogeneous + } + pub fn hash(&self) -> usize { + self.hash + } + pub fn heterogeneous(&self) -> usize { + self.heterogeneous + } +} + +impl Default for ChonkMetrics { + fn default() -> Self { + ChonkMetrics { + chonks: 0, + homogeneous: 0, + hash: 0, + heterogeneous: 0, + } + } +} + impl<'a, V: Vox, S: RectVolSize, M: Clone> IntoVolIterator<'a> for &'a Chonk { type IntoIter = ChonkVolIter<'a, V, S, M>; diff --git a/server/Cargo.toml b/server/Cargo.toml index da576815ca..c705da2872 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -22,5 +22,5 @@ chrono = "0.4.7" hashbrown = { version = "0.5.0", features = ["serde", "nightly"] } crossbeam = "0.7.2" prometheus = "0.7" -prometheus-static-metric = "0.1" +prometheus-static-metric = "0.2" hyper = "0.12.34" \ No newline at end of file diff --git a/server/src/lib.rs b/server/src/lib.rs index 85a14407bd..f6c85e1715 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -6,8 +6,8 @@ pub mod client; pub mod cmd; pub mod error; pub mod input; -pub mod settings; pub mod metrics; +pub mod settings; // Reexports pub use crate::{error::Error, input::Input, settings::ServerSettings}; @@ -23,19 +23,24 @@ use common::{ msg::{ClientMsg, ClientState, RequestStateError, ServerError, ServerInfo, ServerMsg}, net::PostOffice, state::{BlockChange, State, TimeOfDay, Uid}, - terrain::{block::Block, TerrainChunk, TerrainChunkSize, TerrainGrid}, + terrain::{block::Block, chonk::ChonkMetrics, TerrainChunk, TerrainChunkSize, TerrainGrid}, vol::{ReadVol, RectVolSize, Vox}, }; use crossbeam::channel; use hashbrown::HashSet; use log::debug; +use metrics::ServerMetrics; use rand::Rng; -use specs::{join::Join, world::EntityBuilder as EcsEntityBuilder, Builder, Entity as EcsEntity, SystemData}; -use std::{i32, net::SocketAddr, sync::Arc, time::{Duration, Instant}}; +use specs::{join::Join, world::EntityBuilder as EcsEntityBuilder, Builder, Entity as EcsEntity}; +use std::{ + i32, + net::SocketAddr, + sync::Arc, + time::{Duration, Instant}, +}; use uvth::{ThreadPool, ThreadPoolBuilder}; use vek::*; use world::{ChunkSupplement, World}; -use metrics::ServerMetrics; const CLIENT_TIMEOUT: f64 = 20.0; // Seconds @@ -383,7 +388,7 @@ impl Server { // 7) Update Metrics with current data // 8) Finish the tick, passing control of the main thread back to the frontend - let before_tick = Instant::now(); + let before_tick_1 = Instant::now(); // 1) Build up a list of events for this frame, to be passed to the frontend. let mut frontend_events = Vec::new(); @@ -401,12 +406,14 @@ impl Server { // Handle game events self.handle_events(); + let before_tick_4 = Instant::now(); // 4) Tick the client's LocalState. self.state.tick(dt); // Tick the world self.world.tick(dt); + let before_tick_5 = Instant::now(); // 5) Fetch any generated `TerrainChunk`s and insert them into the terrain. // Also, send the chunk data to anybody that is close by. if let Ok((key, (chunk, supplement))) = self.chunk_rx.try_recv() { @@ -526,6 +533,7 @@ impl Server { self.state.remove_chunk(key); } + let before_tick_6 = Instant::now(); // 6) Synchronise clients with the new state of the world. self.sync_clients(); @@ -590,9 +598,47 @@ impl Server { let _ = self.state.ecs_mut().delete_entity(entity); } + let before_tick_7 = Instant::now(); // 7) Update Metrics - self.metrics.player_online.set(self.clients.len() as f64); - self.metrics.tick_time.set(before_tick.elapsed().as_nanos() as f64); + self.metrics + .tick_time + .with_label_values(&["input"]) + .set((before_tick_4 - before_tick_1).as_nanos() as i64); + self.metrics + .tick_time + .with_label_values(&["world"]) + .set((before_tick_5 - before_tick_4).as_nanos() as i64); + self.metrics + .tick_time + .with_label_values(&["terrain"]) + .set((before_tick_6 - before_tick_5).as_nanos() as i64); + self.metrics + .tick_time + .with_label_values(&["sync"]) + .set((before_tick_7 - before_tick_6).as_nanos() as i64); + self.metrics.player_online.set(self.clients.len() as i64); + let cm = self + .state + .terrain() + .iter() + .fold(ChonkMetrics::default(), |a, (_, c)| a + c.get_metrics()); + self.metrics + .chonks_count + .with_label_values(&["homogeneous"]) + .set(cm.homogeneous() as i64); + self.metrics + .chonks_count + .with_label_values(&["hash"]) + .set(cm.hash() as i64); + self.metrics + .chonks_count + .with_label_values(&["heterogeneous"]) + .set(cm.heterogeneous() as i64); + //self.metrics.entity_count.set(self.state.); + self.metrics + .tick_time + .with_label_values(&["metrics"]) + .set(before_tick_7.elapsed().as_nanos() as i64); // 8) Finish the tick, pass control back to the frontend. diff --git a/server/src/metrics.rs b/server/src/metrics.rs index a3c3986421..454bb0050b 100644 --- a/server/src/metrics.rs +++ b/server/src/metrics.rs @@ -1,31 +1,22 @@ -extern crate prometheus; extern crate hyper; +extern crate prometheus; extern crate prometheus_static_metric; use hyper::rt::Future; use hyper::service::service_fn_ok; use hyper::{Body, Request, Response, Server}; -use prometheus::{TextEncoder, Encoder, Registry, Counter, Gauge, Opts, GaugeVec, CounterVec}; -use prometheus_static_metric::make_static_metric; +use prometheus::{Encoder, IntGauge, IntGaugeVec, Opts, Registry, TextEncoder}; use std::thread; -use std::time::Duration; +use std::thread::JoinHandle; -make_static_metric! { - pub struct StaticChonkGaugeVec: Gauge { - "method" => { - hetero, - hash, - homo, - }, - } -} pub struct ServerMetrics { - pub chonks_count: StaticChonkGaugeVec, - pub player_online: Gauge, - pub entity_count: Gauge, - pub tick_time: Gauge, - pub build_info: Gauge, - pub light_count: Gauge, + pub chonks_count: IntGaugeVec, + pub player_online: IntGauge, + pub entity_count: IntGauge, + pub tick_time: IntGaugeVec, + pub build_info: IntGauge, + pub light_count: IntGauge, pub registry: Registry, + pub handle: Option>, } fn metric_service(_req: Request) -> Response { @@ -40,6 +31,7 @@ fn metric_service(_req: Request) -> Response { } impl ServerMetrics { + /* fn metric_service(&self, _req: Request) -> Response { let encoder = TextEncoder::new(); let mut buffer = vec![]; @@ -49,42 +41,60 @@ impl ServerMetrics { .header(hyper::header::CONTENT_TYPE, encoder.format_type()) .body(Body::from(buffer)) .unwrap() - } + }*/ pub fn new() -> Self { - let opts = Opts::new("player_online", "shows the number of clients connected to the server"); - let player_online = Gauge::with_opts(opts).unwrap(); - let opts = Opts::new("entity_count", "number of all entities currently active on the server"); - let entity_count = Gauge::with_opts(opts).unwrap(); - let opts = Opts::new("tick_time", "time in ms requiered for a tick of the server"); - let tick_time = Gauge::with_opts(opts).unwrap(); + let opts = Opts::new( + "player_online", + "shows the number of clients connected to the server", + ); + let player_online = IntGauge::with_opts(opts).unwrap(); + let opts = Opts::new( + "entity_count", + "number of all entities currently active on the server", + ); + let entity_count = IntGauge::with_opts(opts).unwrap(); let opts = Opts::new("veloren_build_info", "Build information") .const_label("hash", common::util::GIT_HASH) .const_label("version", ""); - let build_info = Gauge::with_opts(opts).unwrap(); - let opts = Opts::new("light_count", "number of all lights currently active on the server"); - let light_count = Gauge::with_opts(opts).unwrap(); - let vec = GaugeVec::new(Opts::new("chonks_count", "number of all chonks currently active on the server"), &["method"]).unwrap(); - let chonks_count = StaticChonkGaugeVec::from(&vec); - - chonks_count.hetero.set(1337.0); - chonks_count.hash.set(42.0); - entity_count.set(42.0); + let build_info = IntGauge::with_opts(opts).unwrap(); + let opts = Opts::new( + "light_count", + "number of all lights currently active on the server", + ); + let light_count = IntGauge::with_opts(opts).unwrap(); + let vec = IntGaugeVec::new( + Opts::new( + "chonks_count", + "number of all chonks currently active on the server", + ), + &["type"], + ) + .unwrap(); + let chonks_count: IntGaugeVec = IntGaugeVec::from(vec); + let vec = IntGaugeVec::new( + Opts::new("tick_time", "time in ns requiered for a tick of the server"), + &["period"], + ) + .unwrap(); + let tick_time = IntGaugeVec::from(vec); let registry = Registry::new(); //registry.register(Box::new(chonks_count.clone())).unwrap(); registry.register(Box::new(player_online.clone())).unwrap(); registry.register(Box::new(entity_count.clone())).unwrap(); - registry.register(Box::new(tick_time.clone())).unwrap(); registry.register(Box::new(build_info.clone())).unwrap(); - registry.register(Box::new(light_count.clone())).unwrap(); + //registry.register(Box::new(light_count.clone())).unwrap(); + registry.register(Box::new(chonks_count.clone())).unwrap(); + registry.register(Box::new(tick_time.clone())).unwrap(); prometheus::register(Box::new(player_online.clone())).unwrap(); prometheus::register(Box::new(entity_count.clone())).unwrap(); - prometheus::register(Box::new(tick_time.clone())).unwrap(); prometheus::register(Box::new(build_info.clone())).unwrap(); - prometheus::register(Box::new(light_count.clone())).unwrap(); + //prometheus::register(Box::new(light_count.clone())).unwrap(); + prometheus::register(Box::new(chonks_count.clone())).unwrap(); + prometheus::register(Box::new(tick_time.clone())).unwrap(); - let mut metrics = Self{ + let mut metrics = Self { chonks_count, player_online, entity_count, @@ -92,6 +102,7 @@ impl ServerMetrics { build_info, light_count, registry, + handle: None, }; let addr = ([0, 0, 0, 0], 14005).into(); @@ -103,7 +114,8 @@ impl ServerMetrics { let handle = thread::spawn(|| { hyper::rt::run(server); }); + metrics.handle = Some(handle); metrics } -} \ No newline at end of file +}