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:
parent
50ed6a8d1e
commit
4ce52daea8
|
@ -107,6 +107,9 @@ module P = struct
|
||||||
"tsize", i64 mem.tsize ;
|
"tsize", i64 mem.tsize ;
|
||||||
"dsize", i64 mem.dsize ;
|
"dsize", i64 mem.dsize ;
|
||||||
"ssize", i64 mem.ssize ;
|
"ssize", i64 mem.ssize ;
|
||||||
|
"cow_fauls", string_of_int mem.cow ;
|
||||||
|
"runtime", i64 mem.runtime ;
|
||||||
|
"start", tv mem.start ;
|
||||||
]
|
]
|
||||||
in
|
in
|
||||||
let fields = List.map (fun (k, v) -> k ^ "=" ^ v) fields in
|
let fields = List.map (fun (k, v) -> k ^ "=" ^ v) fields in
|
||||||
|
|
|
@ -122,18 +122,21 @@ let ru =
|
||||||
|
|
||||||
let kinfo_mem =
|
let kinfo_mem =
|
||||||
let open Stats in
|
let open Stats in
|
||||||
let f (vsize, rss, tsize, dsize, ssize) =
|
let f (vsize, (rss, (tsize, (dsize, (ssize, (runtime, (cow, start))))))) =
|
||||||
{ vsize ; rss ; tsize ; dsize ; ssize }
|
{ vsize ; rss ; tsize ; dsize ; ssize ; runtime ; cow ; start }
|
||||||
and g t =
|
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
|
in
|
||||||
Asn.S.map f g @@
|
Asn.S.map f g @@
|
||||||
Asn.S.(sequence5
|
Asn.S.(sequence @@
|
||||||
(required ~label:"bsize" int64)
|
(required ~label:"bsize" int64)
|
||||||
(required ~label:"rss" int64)
|
@ (required ~label:"rss" int64)
|
||||||
(required ~label:"tsize" int64)
|
@ (required ~label:"tsize" int64)
|
||||||
(required ~label:"dsize" int64)
|
@ (required ~label:"dsize" int64)
|
||||||
(required ~label:"ssize" int64))
|
@ (required ~label:"ssize" int64)
|
||||||
|
@ (required ~label:"runtime" int64)
|
||||||
|
@ (required ~label:"cow" int)
|
||||||
|
-@ (required ~label:"start" timeval))
|
||||||
|
|
||||||
(* TODO is this good? *)
|
(* TODO is this good? *)
|
||||||
let int32 =
|
let int32 =
|
||||||
|
|
|
@ -222,11 +222,14 @@ module Stats = struct
|
||||||
tsize : int64 ;
|
tsize : int64 ;
|
||||||
dsize : int64 ;
|
dsize : int64 ;
|
||||||
ssize : int64 ;
|
ssize : int64 ;
|
||||||
|
runtime : int64 ;
|
||||||
|
cow : int ;
|
||||||
|
start : (int64 * int) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
let pp_kinfo_mem ppf t =
|
let pp_kinfo_mem ppf t =
|
||||||
Fmt.pf ppf "virtual-size %Lu rss %Lu text-size %Lu data-size %Lu stack-size %Lu"
|
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.vsize t.rss t.tsize t.dsize t.ssize t.runtime t.cow (fst t.start) (snd t.start)
|
||||||
|
|
||||||
type vmm = (string * int64) list
|
type vmm = (string * int64) list
|
||||||
let pp_vmm ppf vmm =
|
let pp_vmm ppf vmm =
|
||||||
|
|
|
@ -108,6 +108,9 @@ module Stats : sig
|
||||||
tsize : int64 ;
|
tsize : int64 ;
|
||||||
dsize : int64 ;
|
dsize : int64 ;
|
||||||
ssize : int64 ;
|
ssize : int64 ;
|
||||||
|
runtime : int64 ;
|
||||||
|
cow : int ;
|
||||||
|
start : (int64 * int) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
val pp_kinfo_mem : kinfo_mem Fmt.t
|
val pp_kinfo_mem : kinfo_mem Fmt.t
|
||||||
|
|
|
@ -1,11 +1,28 @@
|
||||||
open Vmm_core
|
open Vmm_core
|
||||||
open Albatross_stats_pure
|
open Albatross_stats_pure
|
||||||
|
|
||||||
let timer pid vmmapi =
|
let old_rt = ref 0L
|
||||||
|
|
||||||
|
let timer pid vmmapi interval =
|
||||||
let rusage = sysctl_rusage pid in
|
let rusage = sysctl_rusage pid in
|
||||||
Logs.app (fun m -> m "sysctl rusage: %a" Stats.pp_rusage_mem rusage) ;
|
Logs.app (fun m -> m "sysctl rusage: %a" Stats.pp_rusage_mem rusage) ;
|
||||||
let kinfo_mem = sysctl_kinfo_mem pid in
|
let kinfo_mem = sysctl_kinfo_mem pid in
|
||||||
Logs.app (fun m -> m "kinfo mem: %a" Stats.pp_kinfo_mem kinfo_mem) ;
|
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
|
match vmmapi with
|
||||||
| None -> ()
|
| None -> ()
|
||||||
| Some vmctx -> match wrap vmmapi_stats vmctx with
|
| Some vmctx -> match wrap vmmapi_stats vmctx with
|
||||||
|
@ -31,7 +48,7 @@ let jump _ pid name interval =
|
||||||
fill_descr vmctx ;
|
fill_descr vmctx ;
|
||||||
Some vmctx
|
Some vmctx
|
||||||
in
|
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
|
let t, _u = Lwt.task () in
|
||||||
t)
|
t)
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
CAMLprim value vmmanage_sysctl_kinfo_mem (value pid_r) {
|
CAMLprim value vmmanage_sysctl_kinfo_mem (value pid_r) {
|
||||||
CAMLparam1(pid_r);
|
CAMLparam1(pid_r);
|
||||||
CAMLlocal3(res, utime, stime);
|
CAMLlocal2(res, start);
|
||||||
int name[4];
|
int name[4];
|
||||||
int error;
|
int error;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
@ -39,12 +39,18 @@ CAMLprim value vmmanage_sysctl_kinfo_mem (value pid_r) {
|
||||||
if (error < 0)
|
if (error < 0)
|
||||||
uerror("sysctl", Nothing);
|
uerror("sysctl", Nothing);
|
||||||
|
|
||||||
res = caml_alloc(5, 0);
|
res = caml_alloc(8, 0);
|
||||||
Store_field (res, 0, Val64(p.ki_size));
|
Store_field (res, 0, Val64(p.ki_size));
|
||||||
Store_field (res, 1, Val64(p.ki_rssize));
|
Store_field (res, 1, Val64(p.ki_rssize));
|
||||||
Store_field (res, 2, Val64(p.ki_tsize));
|
Store_field (res, 2, Val64(p.ki_tsize));
|
||||||
Store_field (res, 3, Val64(p.ki_dsize));
|
Store_field (res, 3, Val64(p.ki_dsize));
|
||||||
Store_field (res, 4, Val64(p.ki_ssize));
|
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);
|
CAMLreturn(res);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue