(* 'top'-like tool for libvirt domains.
- * $Id: virt_top.ml,v 1.5 2007/08/30 13:52:40 rjones Exp $
- *)
+ (C) Copyright 2007 Richard W.M. Jones, Red Hat Inc.
+ http://libvirt.org/
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*)
open Printf
open ExtList
let uri = ref None
let debug_file = ref ""
let csv_enabled = ref false
+let csv_cpu = ref true
+let csv_block = ref true
+let csv_net = ref true
let init_file = ref DefaultInitFile
let script_mode = ref false
"-c", Arg.String set_uri, "uri Connect to URI (default: Xen)";
"--connect", Arg.String set_uri, "uri Connect to URI (default: Xen)";
"--csv", Arg.String set_csv, "file Log statistics to CSV file";
+ "--no-csv-cpu", Arg.Clear csv_cpu, " Disable CPU stats in CSV";
+ "--no-csv-block", Arg.Clear csv_block, " Disable block device stats in CSV";
+ "--no-csv-net", Arg.Clear csv_net, " Disable net stats in CSV";
"-d", Arg.Float set_delay, "delay Delay time interval (seconds)";
"--debug", Arg.Set_string debug_file, "file Send debug messages to file";
"--hist-cpu", Arg.Set_int historical_cpu_delay, "secs Historical CPU delay";
| _, "connect", uri -> set_uri uri
| _, "debug", filename -> debug_file := filename
| _, "csv", filename -> set_csv filename
+ | _, "csv-cpu", b -> csv_cpu := bool_of_string b
+ | _, "csv-block", b -> csv_block := bool_of_string b
+ | _, "csv-net", b -> csv_net := bool_of_string b
| _, "batch", b -> batch_mode := bool_of_string b
| _, "secure", b -> secure_mode := bool_of_string b
| _, "script", b -> script_mode := bool_of_string b
let tm = Unix.localtime time in
let printable_time =
sprintf "%02d:%02d:%02d" tm.Unix.tm_hour tm.Unix.tm_min tm.Unix.tm_sec in
- mvaddstr top_lineno 0 ("virt-top " ^ printable_time ^ " - ");
(* What's the total CPU time elapsed since we were last called? (ns) *)
let total_cpu_per_pcpu = 1_000_000_000. *. (time -. !last_time) in
(* Get the screen/window size. *)
let lines, cols = get_size () in
+ (* Time. *)
+ mvaddstr top_lineno 0 ("virt-top " ^ printable_time ^ " - ");
+
(* Basic node_info. *)
addstr (sprintf "%s %d/%dCPU %dMHz %LdMB "
node_info.C.model node_info.C.cpus nr_pcpus node_info.C.mhz
(* Write CSV header row. *)
let write_csv_header () =
- (!csv_write)
+ (!csv_write) (
[ "Hostname"; "Time"; "Arch"; "Physical CPUs";
"Count"; "Running"; "Blocked"; "Paused"; "Shutdown";
"Shutoff"; "Crashed"; "Active"; "Inactive";
"%CPU"; "Total memory (KB)"; "Total guest memory (KB)";
- "Total CPU time (ns)";
+ "Total CPU time (ns)" ] @
(* These fields are repeated for each domain: *)
- "Domain ID"; "Domain name";
- "CPU (ns)"; "%CPU";
- "Block RDRQ"; "Block WRRQ";
- "Net RXBY"; "Net TXBY" ]
+ [ "Domain ID"; "Domain name"; ] @
+ (if !csv_cpu then [ "CPU (ns)"; "%CPU"; ] else []) @
+ (if !csv_block then [ "Block RDRQ"; "Block WRRQ"; ] else []) @
+ (if !csv_net then [ "Net RXBY"; "Net TXBY" ] else [])
+ )
(* Write summary data to CSV file. *)
let append_csv
let domain_fields = List.map (
fun (domname, rd) ->
- [ string_of_int rd.rd_domid; domname;
- string_of_float rd.rd_cpu_time; string_of_float rd.rd_percent_cpu;
- string_of_int64_option rd.rd_block_rd_reqs;
- string_of_int64_option rd.rd_block_wr_reqs;
- string_of_int64_option rd.rd_net_rx_bytes;
- string_of_int64_option rd.rd_net_tx_bytes; ]
+ [ string_of_int rd.rd_domid; domname ] @
+ (if !csv_cpu then [
+ string_of_float rd.rd_cpu_time; string_of_float rd.rd_percent_cpu
+ ] else []) @
+ (if !csv_block then [
+ string_of_int64_option rd.rd_block_rd_reqs;
+ string_of_int64_option rd.rd_block_wr_reqs;
+ ] else []) @
+ (if !csv_net then [
+ string_of_int64_option rd.rd_net_rx_bytes;
+ string_of_int64_option rd.rd_net_tx_bytes;
+ ] else [])
) doms in
let domain_fields = List.flatten domain_fields in