Skip to content

Commit 66a3fdd

Browse files
committed
CP-308049: rrdview tool
Viewing RRDs produced by xcp-rrdd is difficult, because the format is incompatible with rrdtool. rrdtool has a hardcoded limit of 20 char for RRD names for backward compat with its binary format. Steps: * given a directory of xml .gz files containing xcp-rrdd produced rrds * invokes itself recursively with each file in turn using xargs -P (easy way to parallelize on OCaml 4) * load all RRDs, and split them into separate files, allowing us to shorten many of their names without conflicts * some names are still too long, there is a builtin translation table to shorten these * once split an .rrd file is created using 'rrdtool restore'. This can further be queried/inspected/transformed by rrdtool as needed * a .sh script is produced that can plot the RRD if desired. There are many RRDs so plotting isn't done automatically yet. RRDs contain min/avg/max usually, so this is drawn as a strong line at the average, and an area in a lighter color for min/max (especially useful for historic data that has been aggregated). Caveats: * we don't know the unit name, that is part of the XAPI metadata, but not the XML apparently? * separate plots are generated for separate intervals, it'd be nice to join all these into the same graph * the visualization type is not the best for all RRDs, some might benefit from a smoother line, etc. * for now the tool is just built, but not installed (that'll require a .spec change too and can be done later) This is just a starting point to be able to visualize this data somehow, and we can improve the actual plotting later. Signed-off-by: Edwin Török <[email protected]>
1 parent 1cfaab9 commit 66a3fdd

File tree

5 files changed

+671
-0
lines changed

5 files changed

+671
-0
lines changed

ocaml/xcp-rrdd/bin/rrdview/dune

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
(executable
2+
(modes byte exe)
3+
(name rrdview)
4+
;(public_name rrdview)
5+
(libraries
6+
threads
7+
xapi-rrd.unix
8+
bos.setup
9+
astring
10+
fpath
11+
rresult
12+
xmlm
13+
tyre
14+
xapi-rrd
15+
result)
16+
;(package xapi-tools)
17+
)
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
open Rrd
2+
3+
type vname = VName of string
4+
5+
module Rpn = struct
6+
module VDef = struct
7+
(* see rrdgraph_rpn(3) *)
8+
type t = vname * string
9+
10+
type op = vname -> t
11+
12+
let op kind vname = (vname, kind)
13+
14+
let maximum = op "MAXIMUM"
15+
16+
let minimum = op "MINIMUM"
17+
18+
let average = op "AVERAGE"
19+
20+
let stdev = op "STDEV"
21+
22+
let last = op "LAST"
23+
24+
let first = op "FIRST"
25+
26+
let total = op "TOTAL"
27+
28+
let percent = op "PERCENT"
29+
30+
let percentnan = op "PERCENTNAN"
31+
32+
let lsl_slope = op "LSLSLOPE"
33+
34+
let lsl_intercept = op "LSLSLINT"
35+
36+
let lsl_correlation = op "LSLCORREL"
37+
end
38+
39+
module CDef = struct
40+
type t = string Seq.t (* stores a serialized RPN expression *)
41+
42+
let to_string r = r |> List.of_seq |> String.concat ","
43+
44+
let vname (VName vname) = Seq.return vname
45+
46+
let value f = Printf.sprintf "%g" f |> Seq.return
47+
48+
(* reverse polish notation: arguments first, operator last *)
49+
50+
let opn op args = Seq.append (List.to_seq args |> Seq.concat) (Seq.return op)
51+
52+
let op1 op arg = opn op [arg]
53+
54+
let op2 op arg1 arg2 = opn op [arg1; arg2]
55+
56+
let op3 op arg1 arg2 arg3 = opn op [arg1; arg2; arg3]
57+
end
58+
end
59+
60+
module Data = struct
61+
type t = string
62+
63+
(* see rrdgraph_data (3) *)
64+
65+
let def vname rrdfile rrd rra ds =
66+
let step = Int64.mul rrd.timestep @@ Int64.of_int rra.rra_pdp_cnt in
67+
( VName vname
68+
, String.concat ":"
69+
[
70+
"DEF"
71+
; vname ^ "=" ^ Fpath.to_string rrdfile
72+
; ds.ds_name
73+
; Rrd.cf_type_to_string rra.rra_cf
74+
; Printf.sprintf "step=%Lu" step
75+
]
76+
)
77+
78+
let vdef vname (VName var, rpnvdefop) =
79+
(VName vname, Printf.sprintf "CDEF:%s=%s,%s" vname var rpnvdefop)
80+
81+
let cdef vname rpn =
82+
(VName vname, Printf.sprintf "CDEF:%s=%s" vname (Rpn.CDef.to_string rpn))
83+
end
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
(** a variable name *)
2+
type vname
3+
4+
module Rpn : sig
5+
(** RPN expressions for VDEF statements, see [rrdgraph_rpn(3)] *)
6+
module VDef : sig
7+
(** an RPN expression for VDEF, see [rrdgraph_data(3)] *)
8+
type t
9+
10+
(** a VDEF RPN expression, see [rrdgraph_rpn(3)] *)
11+
type op = vname -> t
12+
13+
val maximum : op
14+
(** see [rrdgraph_rpn(3)] *)
15+
16+
val minimum : op
17+
(** see [rrdgraph_rpn(3)] *)
18+
19+
val average : op
20+
(** see [rrdgraph_rpn(3)] *)
21+
22+
val stdev : op
23+
(** see [rrdgraph_rpn(3)] *)
24+
25+
val last : op
26+
(** see [rrdgraph_rpn(3)] *)
27+
28+
val first : op
29+
(** see [rrdgraph_rpn(3)] *)
30+
31+
val total : op
32+
(** see [rrdgraph_rpn(3)] *)
33+
34+
val percent : op
35+
(** see [rrdgraph_rpn(3)] *)
36+
37+
val percentnan : op
38+
(** see [rrdgraph_rpn(3)] *)
39+
40+
val lsl_slope : op
41+
(** see [rrdgraph_rpn(3)] *)
42+
43+
val lsl_intercept : op
44+
(** see [rrdgraph_rpn(3)] *)
45+
46+
val lsl_correlation : op
47+
(** see [rrdgraph_rpn(3)] *)
48+
end
49+
50+
module CDef : sig
51+
(** an RPN expression for CDEF, see [rrdgraph_data(3)] *)
52+
type t
53+
54+
val vname : vname -> t
55+
(** [vname v] is [v] as an RPN expression *)
56+
57+
val value : float -> t
58+
(** [value v] is [v] as an RPN expression *)
59+
60+
val op1 : string -> t -> t
61+
(** [op1 op arg1] is [op arg1]. For valid operators see [rrdgraph_rpn(3)] *)
62+
63+
val op2 : string -> t -> t -> t
64+
(** [op2 op arg1 arg2] is [op arg1 arg2]. For valid operators see [rrdgraph_rpn(3)] *)
65+
66+
val op3 : string -> t -> t -> t -> t
67+
(** [op3 op arg1 arg2 arg3] is [op arg1 arg2 arg3]. For valid operators see [rrdgraph_rpn(3)] *)
68+
end
69+
end
70+
71+
module Data : sig
72+
(** an rrd graph data definition, see [rrdgraph_data(3)] *)
73+
type t
74+
75+
val def : string -> Fpath.t -> Rrd.rrd -> Rrd.rra -> Rrd.ds -> vname * t
76+
(** [def vname rrdfile rrd rra datasource] is a [DEF] (see [rrdgraph_data(3)]) that loads
77+
[datasource.ds_name] from the [rrdfile] and plots it according to the consolidation function in the
78+
specified [rra] and timestep calculated based on [rrd]. This data can be refered to as [vname]
79+
elsewhere. *)
80+
81+
val vdef : string -> Rpn.VDef.t -> vname * t
82+
(** [vdef vname vdefrpn] defines [vname] through a [VDEF] (see [rrdgraph_data(3)]) using the
83+
specified [vdefrpn] expression. Conversion to RPN form is handled internally. *)
84+
85+
val cdef : string -> Rpn.CDef.t -> vname * t
86+
(** [cdef vname cdefrpn] defines [vname] through a [CDEF] (see [rrdgraph_data(3)]) using the
87+
specified [cdefrpn] expression. Conversion to RPN form is handled internally. *)
88+
end

0 commit comments

Comments
 (0)