X-Git-Url: http://git.annexia.org/?a=blobdiff_plain;f=virt-top%2Fvirt_top.ml;h=ef5ac6753de13d9f688c71a4682062e31695c6bb;hb=9aa5ec5ec146eba8a574eae4d109ab9bcd7e932a;hp=75042c130c904a92ba518eb014ff4bc4f2f95958;hpb=daf79631f3eff904ba89297148c4125ac7dfee39;p=virt-top.git diff --git a/virt-top/virt_top.ml b/virt-top/virt_top.ml index 75042c1..ef5ac67 100644 --- a/virt-top/virt_top.ml +++ b/virt-top/virt_top.ml @@ -126,11 +126,13 @@ let uri = ref None let debug_file = ref "" let csv_enabled = ref false let csv_cpu = ref true +let csv_mem = ref true let csv_block = ref true let csv_net = ref true let init_file = ref DefaultInitFile let script_mode = ref false let stream_mode = ref false +let block_in_bytes = ref false (* Tuple of never-changing data returned by start_up function. *) type setup = @@ -170,13 +172,15 @@ let start_up () = "-b", Arg.Set batch_mode, " " ^ s_"Batch mode"; "-c", Arg.String set_uri, - "uri " ^ s_"Connect to URI (default: Xen)"; + "uri " ^ s_"Connect to libvirt URI"; "--connect", Arg.String set_uri, - "uri " ^ s_"Connect to URI (default: Xen)"; + "uri " ^ s_"Connect to libvirt URI"; "--csv", Arg.String set_csv, "file " ^ s_"Log statistics to CSV file"; "--no-csv-cpu", Arg.Clear csv_cpu, " " ^ s_"Disable CPU stats in CSV"; + "--no-csv-mem", Arg.Clear csv_mem, + " " ^ s_"Disable memory stats in CSV"; "--no-csv-block", Arg.Clear csv_block, " " ^ s_"Disable block device stats in CSV"; "--no-csv-net", Arg.Clear csv_net, @@ -203,6 +207,8 @@ let start_up () = " " ^ s_"Run from a script (no user interface)"; "--stream", Arg.Set stream_mode, " " ^ s_"dump output to stdout (no userinterface)"; + "--block-in-bytes", Arg.Set block_in_bytes, + " " ^ s_"show block device load in bytes rather than reqs"; "--version", Arg.Unit display_version, " " ^ s_"Display version number and exit"; ] in @@ -230,12 +236,14 @@ OPTIONS" in | _, "debug", filename -> debug_file := filename | _, "csv", filename -> set_csv filename | _, "csv-cpu", b -> csv_cpu := bool_of_string b + | _, "csv-mem", b -> csv_mem := 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 | _, "stream", b -> stream_mode := bool_of_string b + | _, "block-in-bytes", b -> block_in_bytes := bool_of_string b | _, "end-time", t -> set_end_time t | _, "overwrite-init-file", "false" -> no_init_file () | lineno, key, _ -> @@ -264,7 +272,7 @@ OPTIONS" in prerr_endline (Libvirt.Virterror.to_string err); (* If non-root and no explicit connection URI, print a warning. *) if Unix.geteuid () <> 0 && name = None then ( - print_endline (s_"NB: If you want to monitor a local Xen hypervisor, you usually need to be root"); + print_endline (s_"NB: If you want to monitor a local hypervisor, you usually need to be root"); ); exit 1 in @@ -398,9 +406,17 @@ and rd_active = { (* The following are since the last slice, or 0 if cannot be calculated: *) rd_cpu_time : float; (* CPU time used in nanoseconds. *) rd_percent_cpu : float; (* CPU time as percent of total. *) + rd_mem_bytes : int64; (* Memory usage in bytes *) + rd_mem_percent: int64; (* Memory usage as percent of total *) (* The following are since the last slice, or None if cannot be calc'd: *) rd_block_rd_reqs : int64 option; (* Number of block device read rqs. *) rd_block_wr_reqs : int64 option; (* Number of block device write rqs. *) + rd_block_rd_bytes : int64 option; (* Number of bytes block device read *) + rd_block_wr_bytes : int64 option; (* Number of bytes block device write *) + (* _info fields includes the number considering --block_in_bytes option *) + rd_block_rd_info : int64 option; (* Block device read info for user *) + rd_block_wr_info : int64 option; (* Block device read info for user *) + rd_net_rx_bytes : int64 option; (* Number of bytes received. *) rd_net_tx_bytes : int64 option; (* Number of bytes transmitted. *) } @@ -500,7 +516,10 @@ let collect, clear_pcpu_display_data = rd_prev_block_stats = prev_block_stats; rd_prev_interface_stats = prev_interface_stats; rd_cpu_time = 0.; rd_percent_cpu = 0.; + rd_mem_bytes = 0L; rd_mem_percent = 0L; rd_block_rd_reqs = None; rd_block_wr_reqs = None; + rd_block_rd_bytes = None; rd_block_wr_bytes = None; + rd_block_rd_info = None; rd_block_wr_info = None; rd_net_rx_bytes = None; rd_net_tx_bytes = None; }) with @@ -532,9 +551,14 @@ let collect, clear_pcpu_display_data = let cpu_time = Int64.to_float (rd.rd_info.D.cpu_time -^ prev_info.D.cpu_time) in let percent_cpu = 100. *. cpu_time /. total_cpu in + let mem_usage = rd.rd_info.D.memory in + let mem_percent = + 100L *^ rd.rd_info.D.memory /^ node_info.C.memory in let rd = { rd with rd_cpu_time = cpu_time; - rd_percent_cpu = percent_cpu } in + rd_percent_cpu = percent_cpu; + rd_mem_bytes = mem_usage; + rd_mem_percent = mem_percent} in name, Active rd (* For all other domains we can't calculate it, so leave as 0 *) | rd -> rd @@ -562,10 +586,23 @@ let collect, clear_pcpu_display_data = block_stats.D.rd_req -^ prev_block_stats.D.rd_req in let write_reqs = block_stats.D.wr_req -^ prev_block_stats.D.wr_req in + let read_bytes = + block_stats.D.rd_bytes -^ prev_block_stats.D.rd_bytes in + let write_bytes = + block_stats.D.wr_bytes -^ prev_block_stats.D.wr_bytes in let rd = { rd with rd_block_rd_reqs = Some read_reqs; - rd_block_wr_reqs = Some write_reqs } in + rd_block_wr_reqs = Some write_reqs; + rd_block_rd_bytes = Some read_bytes; + rd_block_wr_bytes = Some write_bytes; + } in + let rd = { rd with + rd_block_rd_info = if !block_in_bytes then + rd.rd_block_rd_bytes else rd.rd_block_rd_reqs; + rd_block_wr_info = if !block_in_bytes then + rd.rd_block_wr_bytes else rd.rd_block_wr_reqs; + } in name, Active rd (* For all other domains we can't calculate it, so leave as None. *) | rd -> rd @@ -849,8 +886,12 @@ let redraw = (* Print domains. *) attron A.reverse; - mvaddstr header_lineno 0 - (pad cols " ID S RDRQ WRRQ RXBY TXBY %CPU %MEM TIME NAME"); + let header_string = if !block_in_bytes + then " ID S RDBY WRBY RXBY TXBY %CPU %MEM TIME NAME" + else " ID S RDRQ WRRQ RXBY TXBY %CPU %MEM TIME NAME" + in + mvaddstr header_lineno 0 + (pad cols header_string); attroff A.reverse; let rec loop lineno = function @@ -858,14 +899,12 @@ let redraw = | (name, Active rd) :: doms -> if lineno < lines then ( let state = show_state rd.rd_info.D.state in - let rd_req = Show.int64_option rd.rd_block_rd_reqs in - let wr_req = Show.int64_option rd.rd_block_wr_reqs in + let rd_req = Show.int64_option rd.rd_block_rd_info in + let wr_req = Show.int64_option rd.rd_block_wr_info in let rx_bytes = Show.int64_option rd.rd_net_rx_bytes in let tx_bytes = Show.int64_option rd.rd_net_tx_bytes in let percent_cpu = Show.percent rd.rd_percent_cpu in - let percent_mem = - 100L *^ rd.rd_info.D.memory /^ node_info.C.memory in - let percent_mem = Int64.to_float percent_mem in + let percent_mem = Int64.to_float rd.rd_mem_percent in let percent_mem = Show.percent percent_mem in let time = Show.time rd.rd_info.D.cpu_time in @@ -1203,7 +1242,11 @@ let write_csv_header () = (* These fields are repeated for each domain: *) [ "Domain ID"; "Domain name"; ] @ (if !csv_cpu then [ "CPU (ns)"; "%CPU"; ] else []) @ - (if !csv_block then [ "Block RDRQ"; "Block WRRQ"; ] else []) @ + (if !csv_mem then [ "Mem (bytes)"; "%Mem";] else []) @ + (if !csv_block && not !block_in_bytes + then [ "Block RDRQ"; "Block WRRQ"; ] else []) @ + (if !csv_block && !block_in_bytes + then [ "Block RDBY"; "Block WRBY"; ] else []) @ (if !csv_net then [ "Net RXBY"; "Net TXBY" ] else []) ) @@ -1257,9 +1300,12 @@ let append_csv (if !csv_cpu then [ string_of_float rd.rd_cpu_time; string_of_float rd.rd_percent_cpu ] else []) @ + (if !csv_mem then [ + Int64.to_string rd.rd_mem_bytes; Int64.to_string rd.rd_mem_percent + ] else []) @ (if !csv_block then [ - string_of_int64_option rd.rd_block_rd_reqs; - string_of_int64_option rd.rd_block_wr_reqs; + string_of_int64_option rd.rd_block_rd_info; + string_of_int64_option rd.rd_block_wr_info; ] else []) @ (if !csv_net then [ string_of_int64_option rd.rd_net_rx_bytes; @@ -1283,7 +1329,10 @@ let dump_stdout printable_time hostname node_info.C.model node_info.C.cpus nr_pcpus node_info.C.mhz (node_info.C.memory /^ 1024L); (* dump domain information one by one *) - printf " ID S RDRQ WRRQ RXBY TXBY %%CPU %%MEM TIME NAME\n"; + let rd, wr = if !block_in_bytes then "RDBY", "WRBY" else "RDRQ", "WRRQ" + in + printf " ID S %s %s RXBY TXBY %%CPU %%MEM TIME NAME\n" rd wr; + (* sort by ID *) let doms = let compare = @@ -1300,18 +1349,16 @@ let dump_stdout let dump_domain = fun name rd -> begin let state = show_state rd.rd_info.D.state in - let rd_req = if rd.rd_block_rd_reqs = None then " 0" - else Show.int64_option rd.rd_block_rd_reqs in - let wr_req = if rd.rd_block_wr_reqs = None then " 0" - else Show.int64_option rd.rd_block_wr_reqs in + let rd_req = if rd.rd_block_rd_info = None then " 0" + else Show.int64_option rd.rd_block_rd_info in + let wr_req = if rd.rd_block_wr_info = None then " 0" + else Show.int64_option rd.rd_block_wr_info in let rx_bytes = if rd.rd_net_rx_bytes = None then " 0" else Show.int64_option rd.rd_net_rx_bytes in let tx_bytes = if rd.rd_net_tx_bytes = None then " 0" else Show.int64_option rd.rd_net_tx_bytes in let percent_cpu = Show.percent rd.rd_percent_cpu in - let percent_mem = - 100L *^ rd.rd_info.D.memory /^ node_info.C.memory in - let percent_mem = Int64.to_float percent_mem in + let percent_mem = Int64.to_float rd.rd_mem_percent in let percent_mem = Show.percent percent_mem in let time = Show.time rd.rd_info.D.cpu_time in printf "%5d %c %s %s %s %s %s %s %s %s\n" @@ -1401,6 +1448,7 @@ and get_key_press setup delay = else if k = Char.code '2' then toggle_net_display () else if k = Char.code '3' then toggle_block_display () else if k = Char.code 'W' then write_init_file () + else if k = Char.code 'B' then toggle_block_in_bytes_mode () else unknown_command k ) @@ -1546,6 +1594,12 @@ and toggle_block_display () = (* key 3 *) | TaskDisplay | NetDisplay -> BlockDisplay | BlockDisplay -> TaskDisplay +and toggle_block_in_bytes_mode () = (* key B *) + block_in_bytes := + match !block_in_bytes with + | false -> true + | true -> false + (* Write an init file. *) and write_init_file () = match !init_file with @@ -1674,6 +1728,7 @@ and show_help (_, _, _, _, _, _, hostname, key "q" (s_"Quit"); key "d s" (s_"Set update interval"); key "h" (s_"Help"); + key "B" (s_"toggle block info req/bytes"); (* Sort order. *) ignore (get_lineno ());