From 4ce52daea846e77032dda84bd8f2e7c345faf163 Mon Sep 17 00:00:00 2001 From: Hannes Mehnert Date: Wed, 2 Oct 2019 22:02:07 +0200 Subject: [PATCH] gather more statistics from kinfo_user (sys/user.h) on FreeBSD - real time runtime information (in microsecs) ki_runtime - start timeval ki_start - count of copy-on-write fauls ki_cow --- daemon/albatross_influx.ml | 3 +++ src/vmm_asn.ml | 21 ++++++++++++--------- src/vmm_core.ml | 7 +++++-- src/vmm_core.mli | 3 +++ stats/albatross_stat_client.ml | 21 +++++++++++++++++++-- stats/albatross_stats_stubs.c | 10 ++++++++-- 6 files changed, 50 insertions(+), 15 deletions(-) diff --git a/daemon/albatross_influx.ml b/daemon/albatross_influx.ml index 31c1d93..9823db9 100644 --- a/daemon/albatross_influx.ml +++ b/daemon/albatross_influx.ml @@ -107,6 +107,9 @@ module P = struct "tsize", i64 mem.tsize ; "dsize", i64 mem.dsize ; "ssize", i64 mem.ssize ; + "cow_fauls", string_of_int mem.cow ; + "runtime", i64 mem.runtime ; + "start", tv mem.start ; ] in let fields = List.map (fun (k, v) -> k ^ "=" ^ v) fields in diff --git a/src/vmm_asn.ml b/src/vmm_asn.ml index 8f93ee7..affe60a 100644 --- a/src/vmm_asn.ml +++ b/src/vmm_asn.ml @@ -122,18 +122,21 @@ let ru = let kinfo_mem = let open Stats in - let f (vsize, rss, tsize, dsize, ssize) = - { vsize ; rss ; tsize ; dsize ; ssize } + let f (vsize, (rss, (tsize, (dsize, (ssize, (runtime, (cow, start))))))) = + { vsize ; rss ; tsize ; dsize ; ssize ; runtime ; cow ; start } and g t = - (t.vsize, t.rss, t.tsize, t.dsize, t.ssize) + (t.vsize, (t.rss, (t.tsize, (t.dsize, (t.ssize, (t.runtime, (t.cow, t.start))))))) in Asn.S.map f g @@ - Asn.S.(sequence5 - (required ~label:"bsize" int64) - (required ~label:"rss" int64) - (required ~label:"tsize" int64) - (required ~label:"dsize" int64) - (required ~label:"ssize" int64)) + Asn.S.(sequence @@ + (required ~label:"bsize" int64) + @ (required ~label:"rss" int64) + @ (required ~label:"tsize" int64) + @ (required ~label:"dsize" int64) + @ (required ~label:"ssize" int64) + @ (required ~label:"runtime" int64) + @ (required ~label:"cow" int) + -@ (required ~label:"start" timeval)) (* TODO is this good? *) let int32 = diff --git a/src/vmm_core.ml b/src/vmm_core.ml index b5124c5..a661cde 100644 --- a/src/vmm_core.ml +++ b/src/vmm_core.ml @@ -222,11 +222,14 @@ module Stats = struct tsize : int64 ; dsize : int64 ; ssize : int64 ; + runtime : int64 ; + cow : int ; + start : (int64 * int) ; } let pp_kinfo_mem ppf t = - Fmt.pf ppf "virtual-size %Lu rss %Lu text-size %Lu data-size %Lu stack-size %Lu" - t.vsize t.rss t.tsize t.dsize t.ssize + Fmt.pf ppf "virtual-size %Lu rss %Lu text-size %Lu data-size %Lu stack-size %Lu runtime %Lu cow %u start %Lu.%d" + t.vsize t.rss t.tsize t.dsize t.ssize t.runtime t.cow (fst t.start) (snd t.start) type vmm = (string * int64) list let pp_vmm ppf vmm = diff --git a/src/vmm_core.mli b/src/vmm_core.mli index b132e1f..c4ba4f6 100644 --- a/src/vmm_core.mli +++ b/src/vmm_core.mli @@ -108,6 +108,9 @@ module Stats : sig tsize : int64 ; dsize : int64 ; ssize : int64 ; + runtime : int64 ; + cow : int ; + start : (int64 * int) ; } val pp_kinfo_mem : kinfo_mem Fmt.t diff --git a/stats/albatross_stat_client.ml b/stats/albatross_stat_client.ml index e71f5d0..ca491d6 100644 --- a/stats/albatross_stat_client.ml +++ b/stats/albatross_stat_client.ml @@ -1,11 +1,28 @@ open Vmm_core open Albatross_stats_pure -let timer pid vmmapi = +let old_rt = ref 0L + +let timer pid vmmapi interval = let rusage = sysctl_rusage pid in Logs.app (fun m -> m "sysctl rusage: %a" Stats.pp_rusage_mem rusage) ; let kinfo_mem = sysctl_kinfo_mem pid in Logs.app (fun m -> m "kinfo mem: %a" Stats.pp_kinfo_mem kinfo_mem) ; + let delta, pct = + if !old_rt = 0L then + let delta = kinfo_mem.Stats.runtime in + let now = Unix.gettimeofday () in + let start = + Int64.to_float (fst kinfo_mem.start) +. + ((float_of_int (snd kinfo_mem.start)) /. 1_000_000_000.) + in + delta, Int64.to_float delta /. ((now -. start) *. 1_000_000.) + else + let delta = Int64.sub kinfo_mem.Stats.runtime !old_rt in + delta, Int64.to_float delta /. (interval *. 1_000_000.) + in + Logs.app (fun m -> m "delta %Lu pct %f" delta pct) ; + old_rt := kinfo_mem.Stats.runtime; match vmmapi with | None -> () | Some vmctx -> match wrap vmmapi_stats vmctx with @@ -31,7 +48,7 @@ let jump _ pid name interval = fill_descr vmctx ; Some vmctx in - let _ev = Lwt_engine.on_timer interval true (fun _e -> timer pid vmmapi) in + let _ev = Lwt_engine.on_timer interval true (fun _e -> timer pid vmmapi interval) in let t, _u = Lwt.task () in t) diff --git a/stats/albatross_stats_stubs.c b/stats/albatross_stats_stubs.c index d31ff4d..9c1d8d7 100644 --- a/stats/albatross_stats_stubs.c +++ b/stats/albatross_stats_stubs.c @@ -23,7 +23,7 @@ CAMLprim value vmmanage_sysctl_kinfo_mem (value pid_r) { CAMLparam1(pid_r); - CAMLlocal3(res, utime, stime); + CAMLlocal2(res, start); int name[4]; int error; size_t len; @@ -39,12 +39,18 @@ CAMLprim value vmmanage_sysctl_kinfo_mem (value pid_r) { if (error < 0) uerror("sysctl", Nothing); - res = caml_alloc(5, 0); + res = caml_alloc(8, 0); Store_field (res, 0, Val64(p.ki_size)); Store_field (res, 1, Val64(p.ki_rssize)); Store_field (res, 2, Val64(p.ki_tsize)); Store_field (res, 3, Val64(p.ki_dsize)); Store_field (res, 4, Val64(p.ki_ssize)); + Store_field (res, 5, Val64(p.ki_runtime)); + Store_field (res, 6, Val_int(p.ki_cow)); + start = caml_alloc(2, 0); + Store_field (start, 0, Val64(p.ki_start.tv_sec)); + Store_field (start, 1, Val_int(p.ki_start.tv_usec)); + Store_field (res, 7, start); CAMLreturn(res); }