Merge branch 'prometheus' into 'master'

Fix panic if starting singleplayer twice without closing the game

See merge request veloren/veloren!491
This commit is contained in:
Marcel 2019-09-10 13:33:42 +00:00
commit a5962da2b2
2 changed files with 94 additions and 43 deletions

View File

@ -664,13 +664,18 @@ impl Server {
.with_label_values(&["sync"]) .with_label_values(&["sync"])
.set((before_tick_7 - before_tick_6).as_nanos() as i64); .set((before_tick_7 - before_tick_6).as_nanos() as i64);
self.metrics.player_online.set(self.clients.len() as i64); self.metrics.player_online.set(self.clients.len() as i64);
let mut chonk_cnt = 0; self.metrics
let chunk_cnt = self.state.terrain().iter().fold(0, |a, (_, c)| { .time_of_day
chonk_cnt += 1; .set(self.state.ecs().read_resource::<TimeOfDay>().0);
a + c.sub_chunks_len() if self.metrics.is_100th_tick() {
}); let mut chonk_cnt = 0;
self.metrics.chonks_count.set(chonk_cnt as i64); let chunk_cnt = self.state.terrain().iter().fold(0, |a, (_, c)| {
self.metrics.chunks_count.set(chunk_cnt as i64); chonk_cnt += 1;
a + c.sub_chunks_len()
});
self.metrics.chonks_count.set(chonk_cnt as i64);
self.metrics.chunks_count.set(chunk_cnt as i64);
}
//self.metrics.entity_count.set(self.state.); //self.metrics.entity_count.set(self.state.);
self.metrics self.metrics
.tick_time .tick_time

View File

@ -1,11 +1,18 @@
extern crate prometheus; extern crate prometheus;
extern crate prometheus_static_metric; extern crate prometheus_static_metric;
extern crate rouille; extern crate rouille;
use prometheus::{Encoder, IntGauge, IntGaugeVec, Opts, Registry, TextEncoder}; use prometheus::{Encoder, Gauge, IntGauge, IntGaugeVec, Opts, Registry, TextEncoder};
use rouille::router; use rouille::{router, Server};
use std::net::{IpAddr, Ipv4Addr, SocketAddr}; use std::{
use std::thread; convert::TryInto,
use std::thread::JoinHandle; net::{IpAddr, Ipv4Addr, SocketAddr},
sync::{
atomic::{AtomicBool, Ordering},
Arc,
},
thread,
time::{SystemTime, UNIX_EPOCH},
};
pub struct ServerMetrics { pub struct ServerMetrics {
pub chonks_count: IntGauge, pub chonks_count: IntGauge,
@ -14,9 +21,12 @@ pub struct ServerMetrics {
pub entity_count: IntGauge, pub entity_count: IntGauge,
pub tick_time: IntGaugeVec, pub tick_time: IntGaugeVec,
pub build_info: IntGauge, pub build_info: IntGauge,
pub start_time: IntGauge,
pub time_of_day: Gauge,
pub light_count: IntGauge, pub light_count: IntGauge,
pub registry: Registry, pub thread_running: Arc<AtomicBool>,
pub handle: Option<JoinHandle<()>>, pub handle: Option<thread::JoinHandle<()>>,
pub every_100th: i8,
} }
impl ServerMetrics { impl ServerMetrics {
@ -35,6 +45,13 @@ impl ServerMetrics {
.const_label("hash", common::util::GIT_HASH) .const_label("hash", common::util::GIT_HASH)
.const_label("version", ""); .const_label("version", "");
let build_info = IntGauge::with_opts(opts).unwrap(); let build_info = IntGauge::with_opts(opts).unwrap();
let opts = Opts::new(
"veloren_start_time",
"start time of the server in seconds since EPOCH",
);
let start_time = IntGauge::with_opts(opts).unwrap();
let opts = Opts::new("time_of_day", "ingame time in ingame-seconds");
let time_of_day = Gauge::with_opts(opts).unwrap();
let opts = Opts::new( let opts = Opts::new(
"light_count", "light_count",
"number of all lights currently active on the server", "number of all lights currently active on the server",
@ -57,52 +74,81 @@ impl ServerMetrics {
.unwrap(); .unwrap();
let tick_time = IntGaugeVec::from(vec); let tick_time = IntGaugeVec::from(vec);
let since_the_epoch = SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("Time went backwards");
start_time.set(since_the_epoch.as_secs().try_into().unwrap());
let registry = Registry::new(); let registry = Registry::new();
//registry.register(Box::new(chonks_count.clone())).unwrap(); //registry.register(Box::new(chonks_count.clone())).unwrap();
registry.register(Box::new(player_online.clone())).unwrap(); registry.register(Box::new(player_online.clone())).unwrap();
registry.register(Box::new(entity_count.clone())).unwrap(); registry.register(Box::new(entity_count.clone())).unwrap();
registry.register(Box::new(build_info.clone())).unwrap(); registry.register(Box::new(build_info.clone())).unwrap();
registry.register(Box::new(start_time.clone())).unwrap();
registry.register(Box::new(time_of_day.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(chonks_count.clone())).unwrap();
registry.register(Box::new(chunks_count.clone())).unwrap(); registry.register(Box::new(chunks_count.clone())).unwrap();
registry.register(Box::new(tick_time.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(build_info.clone())).unwrap();
//prometheus::register(Box::new(light_count.clone())).unwrap();
prometheus::register(Box::new(chonks_count.clone())).unwrap();
prometheus::register(Box::new(chunks_count.clone())).unwrap();
prometheus::register(Box::new(tick_time.clone())).unwrap();
let mut metrics = Self { let thread_running = Arc::new(AtomicBool::new(true));
let thread_running2 = thread_running.clone();
//TODO: make this a job
let handle = Some(thread::spawn(move || {
let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 14005);
let server = Server::new(addr, move |request| {
router!(request,
(GET) (/metrics) => {
let encoder = TextEncoder::new();
let mut buffer = vec![];
let mf = registry.gather();
encoder.encode(&mf, &mut buffer).unwrap();
rouille::Response::text(String::from_utf8(buffer).unwrap())
},
_ => rouille::Response::empty_404()
)
})
.expect("Failed to start server");
while thread_running2.load(Ordering::Relaxed) {
server.poll();
}
}));
Self {
chonks_count, chonks_count,
chunks_count, chunks_count,
player_online, player_online,
entity_count, entity_count,
tick_time, tick_time,
build_info, build_info,
start_time,
time_of_day,
light_count, light_count,
registry, thread_running,
handle: None, handle,
}; every_100th: 0,
}
}
let handle = thread::spawn(|| { pub fn is_100th_tick(&mut self) -> bool {
let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 14005); self.every_100th += 1;
rouille::start_server(addr, move |request| { if self.every_100th == 100 {
router!(request, self.every_100th = 0;
(GET) (/metrics) => { true
let encoder = TextEncoder::new(); } else {
let mut buffer = vec![]; false
let mf = prometheus::gather(); }
encoder.encode(&mf, &mut buffer).unwrap(); }
rouille::Response::text(String::from_utf8(buffer).unwrap()) }
},
_ => rouille::Response::empty_404() impl Drop for ServerMetrics {
) fn drop(&mut self) {
}); self.thread_running.store(false, Ordering::Relaxed);
}); let handle = self.handle.take();
metrics.handle = Some(handle); handle
.unwrap()
metrics .join()
.expect("Error shutting down prometheus metric exporter");
} }
} }