influx stats
This commit is contained in:
parent
467debe303
commit
f939ff5a58
|
@ -104,26 +104,18 @@ let handle s addr () =
|
||||||
Logs.info (fun m -> m "handling connection %a" Vmm_lwt.pp_sockaddr addr) ;
|
Logs.info (fun m -> m "handling connection %a" Vmm_lwt.pp_sockaddr addr) ;
|
||||||
let rec loop () =
|
let rec loop () =
|
||||||
Vmm_lwt.read_wire s >>= function
|
Vmm_lwt.read_wire s >>= function
|
||||||
| Error (`Msg msg) ->
|
|
||||||
Logs.err (fun m -> m "error while reading %s" msg) ;
|
|
||||||
loop ()
|
|
||||||
| Error _ ->
|
| Error _ ->
|
||||||
Logs.err (fun m -> m "exception while reading") ;
|
Logs.err (fun m -> m "exception while reading") ;
|
||||||
Lwt.return_unit
|
Lwt.return_unit
|
||||||
| Ok (_, `Success _) ->
|
| Ok (header, `Command (`Console_cmd cmd)) ->
|
||||||
Logs.err (fun m -> m "unexpected success reply") ;
|
begin
|
||||||
loop ()
|
|
||||||
| Ok (_, `Failure _) ->
|
|
||||||
Logs.err (fun m -> m "unexpected failure reply") ;
|
|
||||||
loop ()
|
|
||||||
| Ok (header, `Command cmd) ->
|
|
||||||
(if not (Vmm_asn.version_eq header.Vmm_asn.version my_version) then
|
(if not (Vmm_asn.version_eq header.Vmm_asn.version my_version) then
|
||||||
Lwt.return (Error (`Msg "ignoring data with bad version"))
|
Lwt.return (Error (`Msg "ignoring data with bad version"))
|
||||||
else
|
else
|
||||||
match cmd with
|
match cmd with
|
||||||
| `Console_cmd `Console_add -> add_fifo header.Vmm_asn.id
|
| `Console_add -> add_fifo header.Vmm_asn.id
|
||||||
| `Console_cmd `Console_subscribe -> subscribe s header.Vmm_asn.id
|
| `Console_subscribe -> subscribe s header.Vmm_asn.id
|
||||||
| _ -> Lwt.return (Error (`Msg "unexpected command"))) >>= (function
|
| `Console_data _ -> Lwt.return (Error (`Msg "unexpected command"))) >>= (function
|
||||||
| Ok msg -> Vmm_lwt.write_wire s (header, `Success (`String msg))
|
| Ok msg -> Vmm_lwt.write_wire s (header, `Success (`String msg))
|
||||||
| Error (`Msg msg) ->
|
| Error (`Msg msg) ->
|
||||||
Logs.err (fun m -> m "error while processing command: %s" msg) ;
|
Logs.err (fun m -> m "error while processing command: %s" msg) ;
|
||||||
|
@ -132,6 +124,10 @@ let handle s addr () =
|
||||||
| Error _ ->
|
| Error _ ->
|
||||||
Logs.err (fun m -> m "exception while writing to socket") ;
|
Logs.err (fun m -> m "exception while writing to socket") ;
|
||||||
Lwt.return_unit
|
Lwt.return_unit
|
||||||
|
end
|
||||||
|
| Ok wire ->
|
||||||
|
Logs.warn (fun m -> m "ignoring %a" Vmm_asn.pp_wire wire) ;
|
||||||
|
loop ()
|
||||||
in
|
in
|
||||||
loop () >>= fun () ->
|
loop () >>= fun () ->
|
||||||
Vmm_lwt.safe_close s >|= fun () ->
|
Vmm_lwt.safe_close s >|= fun () ->
|
||||||
|
|
|
@ -140,7 +140,7 @@ module P = struct
|
||||||
vm ifd.name (String.concat ~sep:"," fields)
|
vm ifd.name (String.concat ~sep:"," fields)
|
||||||
end
|
end
|
||||||
|
|
||||||
let my_version = `WV2
|
let my_version = `AV2
|
||||||
|
|
||||||
let command = ref 1L
|
let command = ref 1L
|
||||||
|
|
||||||
|
@ -181,7 +181,6 @@ let rec read_sock_write_tcp c ?fd addr addrtype =
|
||||||
None) >>= fun fd ->
|
None) >>= fun fd ->
|
||||||
read_sock_write_tcp c ?fd addr addrtype
|
read_sock_write_tcp c ?fd addr addrtype
|
||||||
| Some fd ->
|
| Some fd ->
|
||||||
let open Vmm_wire in
|
|
||||||
Logs.debug (fun m -> m "reading from unix socket") ;
|
Logs.debug (fun m -> m "reading from unix socket") ;
|
||||||
Vmm_lwt.read_wire c >>= function
|
Vmm_lwt.read_wire c >>= function
|
||||||
| Error e ->
|
| Error e ->
|
||||||
|
@ -190,60 +189,40 @@ let rec read_sock_write_tcp c ?fd addr addrtype =
|
||||||
safe_close fd >>= fun () ->
|
safe_close fd >>= fun () ->
|
||||||
safe_close c >|= fun () ->
|
safe_close c >|= fun () ->
|
||||||
true
|
true
|
||||||
| Ok (hdr, data) ->
|
| Ok (hdr, `Command (`Stats_cmd (`Stats_data (ru, vmm, ifs)))) ->
|
||||||
if not (version_eq hdr.version my_version) then begin
|
begin
|
||||||
|
if not (Vmm_asn.version_eq hdr.Vmm_asn.version my_version) then begin
|
||||||
Logs.err (fun m -> m "unknown wire protocol version") ;
|
Logs.err (fun m -> m "unknown wire protocol version") ;
|
||||||
safe_close fd >>= fun () ->
|
safe_close fd >>= fun () ->
|
||||||
safe_close c >|= fun () ->
|
safe_close c >|= fun () ->
|
||||||
false
|
false
|
||||||
end else if Vmm_wire.is_fail hdr then begin
|
|
||||||
Logs.err (fun m -> m "failed to retrieve statistics") ;
|
|
||||||
safe_close fd >>= fun () ->
|
|
||||||
safe_close c >|= fun () ->
|
|
||||||
false
|
|
||||||
end else if Vmm_wire.is_reply hdr then begin
|
|
||||||
Logs.info (fun m -> m "received reply, continuing") ;
|
|
||||||
read_sock_write_tcp c ~fd addr addrtype
|
|
||||||
end else
|
end else
|
||||||
(match Vmm_wire.Stats.int_to_op hdr.Vmm_wire.tag with
|
let name = string_of_id hdr.Vmm_asn.id in
|
||||||
| Some Vmm_wire.Stats.Data ->
|
|
||||||
begin
|
|
||||||
let r =
|
|
||||||
let open Rresult.R.Infix in
|
|
||||||
Vmm_wire.decode_strings data >>= fun (id, off) ->
|
|
||||||
Vmm_wire.Stats.decode_stats (Cstruct.shift data off) >>| fun stats ->
|
|
||||||
(Vmm_core.string_of_id id, stats)
|
|
||||||
in
|
|
||||||
match r with
|
|
||||||
| Error (`Msg msg) ->
|
|
||||||
Logs.warn (fun m -> m "error %s while decoding stats, ignoring" msg) ;
|
|
||||||
Lwt.return (Some fd)
|
|
||||||
| Ok (name, (ru, vmm, ifs)) ->
|
|
||||||
let ru = P.encode_ru name ru in
|
let ru = P.encode_ru name ru in
|
||||||
let vmm = match vmm with [] -> [] | _ -> [ P.encode_vmm name vmm ] in
|
let vmm = match vmm with [] -> [] | _ -> [ P.encode_vmm name vmm ] in
|
||||||
let taps = List.map (P.encode_if name) ifs in
|
let taps = List.map (P.encode_if name) ifs in
|
||||||
let out = (String.concat ~sep:"\n" (ru :: vmm @ taps)) ^ "\n" in
|
let out = (String.concat ~sep:"\n" (ru :: vmm @ taps)) ^ "\n" in
|
||||||
Logs.debug (fun m -> m "writing %d via tcp" (String.length out)) ;
|
Logs.debug (fun m -> m "writing %d via tcp" (String.length out)) ;
|
||||||
Vmm_lwt.write_wire fd (Cstruct.of_string out) >>= function
|
Vmm_lwt.write_raw fd (Bytes.unsafe_of_string out) >>= function
|
||||||
| Ok () ->
|
| Ok () ->
|
||||||
Logs.debug (fun m -> m "wrote successfully") ;
|
Logs.debug (fun m -> m "wrote successfully") ;
|
||||||
Lwt.return (Some fd)
|
read_sock_write_tcp c ~fd addr addrtype
|
||||||
| Error e ->
|
| Error e ->
|
||||||
Logs.err (fun m -> m "error %s while writing to tcp (%s)"
|
Logs.err (fun m -> m "error %s while writing to tcp (%s)"
|
||||||
(str_of_e e) name) ;
|
(str_of_e e) name) ;
|
||||||
safe_close fd >|= fun () ->
|
safe_close fd >|= fun () ->
|
||||||
None
|
false
|
||||||
end
|
end
|
||||||
| _ ->
|
| Ok wire ->
|
||||||
Logs.err (fun m -> m "unhandled tag %lu" hdr.tag) ;
|
Logs.warn (fun m -> m "ignoring %a" Vmm_asn.pp_wire wire) ;
|
||||||
Lwt.return (Some fd)) >>= fun fd ->
|
Lwt.return (Some fd) >>= fun fd ->
|
||||||
read_sock_write_tcp c ?fd addr addrtype
|
read_sock_write_tcp c ?fd addr addrtype
|
||||||
|
|
||||||
let query_sock vm c =
|
let query_sock vm c =
|
||||||
let request = Vmm_wire.Stats.subscribe !command my_version vm in
|
let header = Vmm_asn.{ version = my_version ; sequence = !command ; id = vm } in
|
||||||
command := Int64.succ !command ;
|
command := Int64.succ !command ;
|
||||||
Logs.debug (fun m -> m "%Lu requesting %a via socket" !command pp_id vm) ;
|
Logs.debug (fun m -> m "%Lu requesting %a via socket" !command pp_id vm) ;
|
||||||
Vmm_lwt.write_wire c request
|
Vmm_lwt.write_wire c (header, `Command (`Stats_cmd `Stats_subscribe))
|
||||||
|
|
||||||
let rec maybe_connect stat_socket =
|
let rec maybe_connect stat_socket =
|
||||||
let c = Lwt_unix.(socket PF_UNIX SOCK_STREAM 0) in
|
let c = Lwt_unix.(socket PF_UNIX SOCK_STREAM 0) in
|
||||||
|
|
|
@ -98,12 +98,6 @@ let handle mvar ring s addr () =
|
||||||
| Error _ ->
|
| Error _ ->
|
||||||
Logs.err (fun m -> m "exception while reading") ;
|
Logs.err (fun m -> m "exception while reading") ;
|
||||||
Lwt.return_unit
|
Lwt.return_unit
|
||||||
| Ok (_, `Failure _) ->
|
|
||||||
Logs.warn (fun m -> m "ignoring failure") ;
|
|
||||||
loop ()
|
|
||||||
| Ok (_, `Success _) ->
|
|
||||||
Logs.warn (fun m -> m "ignoring success") ;
|
|
||||||
loop ()
|
|
||||||
| Ok (hdr, `Command (`Log_cmd lc)) ->
|
| Ok (hdr, `Command (`Log_cmd lc)) ->
|
||||||
if not (Vmm_asn.version_eq hdr.Vmm_asn.version my_version) then begin
|
if not (Vmm_asn.version_eq hdr.Vmm_asn.version my_version) then begin
|
||||||
Logs.warn (fun m -> m "unsupported version") ;
|
Logs.warn (fun m -> m "unsupported version") ;
|
||||||
|
@ -140,8 +134,8 @@ let handle mvar ring s addr () =
|
||||||
Lwt.return_unit
|
Lwt.return_unit
|
||||||
| Ok () -> loop () (* TODO no need to loop ;) *)
|
| Ok () -> loop () (* TODO no need to loop ;) *)
|
||||||
end
|
end
|
||||||
| _ ->
|
| Ok wire ->
|
||||||
Logs.err (fun m -> m "unknown command") ;
|
Logs.warn (fun m -> m "ignoring %a" Vmm_asn.pp_wire wire) ;
|
||||||
loop ()
|
loop ()
|
||||||
in
|
in
|
||||||
loop () >>= fun () ->
|
loop () >>= fun () ->
|
||||||
|
|
|
@ -20,6 +20,6 @@ let () =
|
||||||
Pkg.bin "provision/vmm_revoke" ;
|
Pkg.bin "provision/vmm_revoke" ;
|
||||||
Pkg.bin "provision/vmm_gen_ca" ; *)
|
Pkg.bin "provision/vmm_gen_ca" ; *)
|
||||||
(* Pkg.clib "stats/libvmm_stats_stubs.clib" ; *)
|
(* Pkg.clib "stats/libvmm_stats_stubs.clib" ; *)
|
||||||
(* Pkg.bin "stats/vmm_stats_lwt" ;
|
Pkg.bin "stats/vmm_stats_lwt" ;
|
||||||
Pkg.bin "app/vmm_influxdb_stats" ; *)
|
Pkg.bin "app/vmm_influxdb_stats" ;
|
||||||
]
|
]
|
||||||
|
|
|
@ -79,11 +79,7 @@ let read_wire s =
|
||||||
else
|
else
|
||||||
Lwt.return (Error `Eof)
|
Lwt.return (Error `Eof)
|
||||||
|
|
||||||
let write_wire s wire =
|
let write_raw s buf =
|
||||||
let data = Vmm_asn.wire_to_cstruct wire in
|
|
||||||
let dlen = Cstruct.create 4 in
|
|
||||||
Cstruct.BE.set_uint32 dlen 0 (Int32.of_int (Cstruct.len data)) ;
|
|
||||||
let buf = Cstruct.(to_bytes (append dlen data)) in
|
|
||||||
let rec w off l =
|
let rec w off l =
|
||||||
Lwt.catch (fun () ->
|
Lwt.catch (fun () ->
|
||||||
Lwt_unix.send s buf off l [] >>= fun n ->
|
Lwt_unix.send s buf off l [] >>= fun n ->
|
||||||
|
@ -98,6 +94,13 @@ let write_wire s wire =
|
||||||
(* Logs.debug (fun m -> m "writing %a" Cstruct.hexdump_pp (Cstruct.of_bytes buf)) ; *)
|
(* Logs.debug (fun m -> m "writing %a" Cstruct.hexdump_pp (Cstruct.of_bytes buf)) ; *)
|
||||||
w 0 (Bytes.length buf)
|
w 0 (Bytes.length buf)
|
||||||
|
|
||||||
|
let write_wire s wire =
|
||||||
|
let data = Vmm_asn.wire_to_cstruct wire in
|
||||||
|
let dlen = Cstruct.create 4 in
|
||||||
|
Cstruct.BE.set_uint32 dlen 0 (Int32.of_int (Cstruct.len data)) ;
|
||||||
|
let buf = Cstruct.(to_bytes (append dlen data)) in
|
||||||
|
write_raw s buf
|
||||||
|
|
||||||
let safe_close fd =
|
let safe_close fd =
|
||||||
Lwt.catch
|
Lwt.catch
|
||||||
(fun () -> Lwt_unix.close fd)
|
(fun () -> Lwt_unix.close fd)
|
||||||
|
|
|
@ -9,6 +9,8 @@ val wait_and_clear :
|
||||||
val read_wire :
|
val read_wire :
|
||||||
Lwt_unix.file_descr ->
|
Lwt_unix.file_descr ->
|
||||||
(Vmm_asn.wire, [> `Eof | `Exception | `Toomuch ]) result Lwt.t
|
(Vmm_asn.wire, [> `Eof | `Exception | `Toomuch ]) result Lwt.t
|
||||||
|
val write_raw :
|
||||||
|
Lwt_unix.file_descr -> bytes -> (unit, [> `Exception ]) result Lwt.t
|
||||||
val write_wire :
|
val write_wire :
|
||||||
Lwt_unix.file_descr -> Vmm_asn.wire -> (unit, [> `Exception ]) result Lwt.t
|
Lwt_unix.file_descr -> Vmm_asn.wire -> (unit, [> `Exception ]) result Lwt.t
|
||||||
val safe_close : Lwt_unix.file_descr -> unit Lwt.t
|
val safe_close : Lwt_unix.file_descr -> unit Lwt.t
|
||||||
|
|
|
@ -16,7 +16,9 @@ external vmmapi_close : vmctx -> unit = "vmmanage_vmmapi_close"
|
||||||
external vmmapi_statnames : vmctx -> string list = "vmmanage_vmmapi_statnames"
|
external vmmapi_statnames : vmctx -> string list = "vmmanage_vmmapi_statnames"
|
||||||
external vmmapi_stats : vmctx -> int64 list = "vmmanage_vmmapi_stats"
|
external vmmapi_stats : vmctx -> int64 list = "vmmanage_vmmapi_stats"
|
||||||
|
|
||||||
let my_version = `WV2
|
let my_version = `AV2
|
||||||
|
|
||||||
|
let bcast = ref 0L
|
||||||
|
|
||||||
let descr = ref []
|
let descr = ref []
|
||||||
|
|
||||||
|
@ -117,10 +119,10 @@ let tick t =
|
||||||
match Vmm_core.drop_super ~super:id ~sub:vmid with
|
match Vmm_core.drop_super ~super:id ~sub:vmid with
|
||||||
| None -> Logs.err (fun m -> m "couldn't drop super %a from sub %a" Vmm_core.pp_id id Vmm_core.pp_id vmid) ; out
|
| None -> Logs.err (fun m -> m "couldn't drop super %a from sub %a" Vmm_core.pp_id id Vmm_core.pp_id vmid) ; out
|
||||||
| Some real_id ->
|
| Some real_id ->
|
||||||
let name = Vmm_core.string_of_id real_id in
|
let header = Vmm_asn.{ version = my_version ; sequence = !bcast ; id = real_id } in
|
||||||
|
bcast := Int64.succ !bcast ;
|
||||||
let stats_encoded = Vmm_wire.Stats.(data 0L my_version name (encode_stats stats)) in
|
let data = `Stats_data stats in
|
||||||
(socket, vmid, stats_encoded) :: out)
|
((socket, vmid, (header, `Command (`Stats_cmd data))) :: out))
|
||||||
out xs)
|
out xs)
|
||||||
[] (Vmm_trie.all t'.vmid_pid)
|
[] (Vmm_trie.all t'.vmid_pid)
|
||||||
in
|
in
|
||||||
|
@ -171,29 +173,38 @@ let remove_vmid t vmid =
|
||||||
let remove_vmids t vmids =
|
let remove_vmids t vmids =
|
||||||
List.fold_left remove_vmid t vmids
|
List.fold_left remove_vmid t vmids
|
||||||
|
|
||||||
let handle t socket hdr cs =
|
let handle t socket (header, wire) =
|
||||||
let open Vmm_wire in
|
|
||||||
let open Vmm_wire.Stats in
|
|
||||||
let r =
|
let r =
|
||||||
if not (version_eq my_version hdr.version) then
|
if not (Vmm_asn.version_eq my_version header.Vmm_asn.version) then
|
||||||
Error (`Msg "cannot handle version")
|
Error (`Msg "cannot handle version")
|
||||||
else
|
else
|
||||||
decode_strings cs >>= fun (id, off) ->
|
match wire with
|
||||||
match int_to_op hdr.tag with
|
| `Command (`Stats_cmd cmd) ->
|
||||||
| Some Add ->
|
begin
|
||||||
decode_pid_taps (Cstruct.shift cs off) >>= fun (pid, taps) ->
|
let id = header.Vmm_asn.id in
|
||||||
|
match cmd with
|
||||||
|
| `Stats_add (pid, taps) ->
|
||||||
add_pid t id pid taps >>= fun t ->
|
add_pid t id pid taps >>= fun t ->
|
||||||
Ok (t, `Add id, None, success ~msg:"added" my_version hdr.id (op_to_int Add))
|
Ok (t, `Add id, None, Some "added")
|
||||||
| Some Remove ->
|
| `Stats_remove ->
|
||||||
let t = remove_vmid t id in
|
let t = remove_vmid t id in
|
||||||
Ok (t, `Remove id, None, success ~msg:"removed" my_version hdr.id (op_to_int Remove))
|
Ok (t, `Remove id, None, Some "removed")
|
||||||
| Some Subscribe ->
|
| `Stats_subscribe ->
|
||||||
let name_sockets, close = Vmm_trie.insert id socket t.name_sockets in
|
let name_sockets, close = Vmm_trie.insert id socket t.name_sockets in
|
||||||
Ok ({ t with name_sockets }, `None, close, success ~msg:"subscribed" my_version hdr.id (op_to_int Subscribe))
|
Ok ({ t with name_sockets }, `None, close, Some "subscribed")
|
||||||
| _ -> Error (`Msg "unknown command")
|
| _ -> Error (`Msg "unknown command")
|
||||||
|
end
|
||||||
|
| _ ->
|
||||||
|
Logs.warn (fun m -> m "ignoring %a" Vmm_asn.pp_wire (header, wire)) ;
|
||||||
|
Ok (t, `None, None, None)
|
||||||
in
|
in
|
||||||
match r with
|
match r with
|
||||||
| Ok (t, action, close, out) -> t, action, close, out
|
| Ok (t, action, close, out) ->
|
||||||
|
let out = match out with
|
||||||
|
| None -> None
|
||||||
|
| Some str -> Some (header, `Success (`String str))
|
||||||
|
in
|
||||||
|
t, action, close, out
|
||||||
| Error (`Msg msg) ->
|
| Error (`Msg msg) ->
|
||||||
Logs.err (fun m -> m "error while processing %s" msg) ;
|
Logs.err (fun m -> m "error while processing %s" msg) ;
|
||||||
t, `None, None, fail ~msg my_version hdr.id
|
t, `None, None, Some (header, `Failure msg)
|
||||||
|
|
|
@ -27,8 +27,8 @@ let handle s addr () =
|
||||||
Vmm_lwt.read_wire s >>= function
|
Vmm_lwt.read_wire s >>= function
|
||||||
| Error (`Msg msg) -> Logs.err (fun m -> m "error while reading %s" msg) ; loop acc
|
| Error (`Msg msg) -> Logs.err (fun m -> m "error while reading %s" msg) ; loop acc
|
||||||
| Error _ -> Logs.err (fun m -> m "exception while reading") ; Lwt.return acc
|
| Error _ -> Logs.err (fun m -> m "exception while reading") ; Lwt.return acc
|
||||||
| Ok (hdr, data) ->
|
| Ok wire ->
|
||||||
let t', action, close, out = Vmm_stats.handle !t s hdr data in
|
let t', action, close, out = Vmm_stats.handle !t s wire in
|
||||||
let acc = match action with
|
let acc = match action with
|
||||||
| `Add pid -> pid :: acc
|
| `Add pid -> pid :: acc
|
||||||
| `Remove pid -> List.filter (fun m -> m <> pid) acc
|
| `Remove pid -> List.filter (fun m -> m <> pid) acc
|
||||||
|
@ -36,6 +36,9 @@ let handle s addr () =
|
||||||
in
|
in
|
||||||
t := t' ;
|
t := t' ;
|
||||||
(match close with None -> Lwt.return_unit | Some s' -> Vmm_lwt.safe_close s') >>= fun () ->
|
(match close with None -> Lwt.return_unit | Some s' -> Vmm_lwt.safe_close s') >>= fun () ->
|
||||||
|
match out with
|
||||||
|
| None -> loop acc
|
||||||
|
| Some out ->
|
||||||
Vmm_lwt.write_wire s out >>= function
|
Vmm_lwt.write_wire s out >>= function
|
||||||
| Ok () -> loop acc
|
| Ok () -> loop acc
|
||||||
| Error _ -> Logs.err (fun m -> m "exception while writing") ; Lwt.return acc
|
| Error _ -> Logs.err (fun m -> m "exception while writing") ; Lwt.return acc
|
||||||
|
|
Loading…
Reference in a new issue