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
This commit is contained in:
Hannes Mehnert 2019-10-02 22:02:07 +02:00
parent 50ed6a8d1e
commit 4ce52daea8
6 changed files with 50 additions and 15 deletions

View file

@ -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

View file

@ -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
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:"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 =

View file

@ -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 =

View file

@ -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

View file

@ -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)

View file

@ -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);
}