1PMREGISTERDERIVED(3)       Library Functions Manual       PMREGISTERDERIVED(3)
2
3
4

NAME

6       pmRegisterDerived - register a derived metric name and definition
7

C SYNOPSIS

9       #include <pcp/pmapi.h>
10
11       char *pmRegisterDerived(char *name, char *expr)
12
13       cc ... -lpcp
14

DESCRIPTION

16       Derived metrics provide a way of extending the Performance Metrics Name
17       Space (PMNS) with new metrics defined  at  the  PCP  client-side  using
18       arithmetic expressions over the existing performance metrics.
19
20       Typical  uses would be to aggregate a number of similar metrics to pro‐
21       vide a higher-level summary metric or to support  the  ``delta  V  over
22       delta  V''  class  of  metrics  that  are not possible in the base data
23       semantics of PCP.  An example of the latter class would be the  average
24       I/O size, defined as
25                 delta(disk.dev.total_bytes) / delta(disk.dev.total)
26       where  both  of the disk.dev metrics are counters, and what is required
27       is to to sample both metrics, compute the difference between  the  cur‐
28       rent  and previous values and then calculate the ratio of these differ‐
29       ences.
30
31       The arguments to pmRegisterDerived are the name of the new derived met‐
32       ric  and  expr  is  an arithmetic expression defining how the values of
33       name should be computed.
34
35       name should follow the syntactic rules for  the  names  of  performance
36       metrics,  namely  one  or more components separated with a dot (``.''),
37       and each component must begin with an alphabetic followed  by  zero  or
38       more  characters  drawn  from  the alphabetics, numerics and underscore
39       (``_'').  For more details, refer to PCPIntro(1) and pmns(4).
40
41       name must be unique across all derived metrics and should not match the
42       name  of  any regular metric in the PMNS.  It is acceptable for name to
43       share some part of its prefix with an existing  subtree  of  the  PMNS,
44       e.g.  the  average  I/O size metric above could be named disk.dev.avgsz
45       which would place it amongst the other disk.dev metrics  in  the  PMNS.
46       Alternatively,  derived metrics could populate their own subtree of the
47       PMNS, e.g. the average I/O size metric above  could  be  named  my.sum‐
48       mary.disk.avgsz.
49
50       The expression expr follows these syntactic rules:
51
52       * Terminal  elements  are  either  names of existing metrics or integer
53         constants.  Recursive definitions are not allowed, so only the  names
54         of  regular  metrics (not other derived metrics) may be used. Integer
55         constants are constrained to the precision of 32-bit  unsigned  inte‐
56         gers.
57
58       * The  usual  binary arithmetic operators are supported, namely - addi‐
59         tion (``+''), subtraction (``-''), multiplication (``*'')  and  divi‐
60         sion  (``/'')  with  the normal precedence rules where multiplication
61         and division have higher precedence than addition and subtraction, so
62         a+b*c is evaluated as a+(b*c)
63
64       * Parenthesis may be used for grouping.
65
66       * The  following unary functions operate on a single performance metric
67         and return one or more values.  For all functions  (except  count()),
68         the type of the operand metric must be arithmetic (integer of various
69         sizes and signedness, float or double).
70
71         ┌─────────┬──────────────────────────────────────────────────────────┐
72         │Function │                          Value                           │
73         ├─────────┼──────────────────────────────────────────────────────────┤
74         │avg(x)   │ A singular instance being the average value  across  all │
75         │         │ instances for the metric x.                              │
76         ├─────────┼──────────────────────────────────────────────────────────┤
77         │count(x) │ A  singular  instance  being  the count of the number of │
78         │         │ instances for the metric x.                              │
79         ├─────────┼──────────────────────────────────────────────────────────┤
80         │delta(x) │ Returns the  difference  in  values  for  the  metric  x │
81         │         │ between  one  call  to pmFetch(3) and the next. There is │
82         │         │ one value in the result for each instance  that  appears │
83         │         │ in both the current and the previous sample.             │
84         ├─────────┼──────────────────────────────────────────────────────────┤
85         │max(x)   │ A  singular  instance being the maximum value across all │
86         │         │ instances for the metric x.                              │
87         ├─────────┼──────────────────────────────────────────────────────────┤
88         │min(x)   │ A singular instance being the minimum value  across  all │
89         │         │ instances for the metric x.                              │
90         ├─────────┼──────────────────────────────────────────────────────────┤
91         │sum(x)   │ A  singular  instance being the sum of the values across │
92         │         │ all instances for the metric x.                          │
93         └─────────┴──────────────────────────────────────────────────────────┘
94       * White space is ignored.
95
96       Syntactic checking  is  performed  at  the  time  pmRegisterDerived  is
97       called,  but  semantic  checking  is deferred until each new context is
98       created with  pmNewContext(3)  or  re-establised  with  pmReconnectCon‐
99       text(3),  at  which  time  the  PMNS and metadata is available to allow
100       semantic checking and the metadata of the derived metrics to be  estab‐
101       lished.
102

SEMANTIC CHECKS AND RULES

104       There  are  a  number of conversions required to determine the metadata
105       for a derived metric and to ensure the semantics of the expressions are
106       sound.
107
108       In  a  binary  expression,  if  the semantics of both operands is not a
109       counter (i.e. PM_SEM_INSTANT or PM_SEM_DISCRETE) then the  result  will
110       have  semantics PM_SEM_INSTANT unless both operands are PM_SEM_DISCRETE
111       in which case the result is also PM_SEM_DISCRETE.
112
113       The mapping of the pmUnits of the metadata uses the following rules:
114
115       * If both operands have a dimension of COUNT and the scales are not the
116         same, use the larger scale and convert the values of the operand with
117         the smaller scale.
118
119       * If both operands have a dimension of TIME and the scales are not  the
120         same, use the larger scale and convert the values of the operand with
121         the smaller scale.
122
123       * If both operands have a dimension of SPACE and the scales are not the
124         same, use the larger scale and convert the values of the operand with
125         the smaller scale.
126
127       * For addition and subtraction all dimensions for each of the  operands
128         and result are identical.
129
130       * For  multiplication,  the dimensions of the result are the sum of the
131         dimensions of the operands.
132
133       * For division, the dimensions of the result are the difference of  the
134         dimensions of the operands.
135
136       Scale  conversion  involves  division if the dimension is positive else
137       multiplication if the dimension is negative.  If  scale  conversion  is
138       applied  to  either  of  the  operands,  the result is promoted to type
139       PM_TYPE_DOUBLE.
140
141       Putting all of this together in an example, consider the derived metric
142       defined as follows:
143          x = network.interface.speed - delta(network.interface.in.bytes) /
144                             delta(sample.milliseconds)
145       The type, dimension and scale settings would propagate up the expres‐
146       sion tree as follows.
147
148        ┌────────────────────────┬────────┬───────────────┬─────────────────┐
149        │      Expression        │  Type  │  Dimension &  │ Scale Factor(s) │
150        │                        │        │  Scale        │                 │
151        ├────────────────────────┼────────┼───────────────┼─────────────────┤
152        │sample.milliseconds     │ DOUBLE │ millisec      │                 │
153        │delta(...)              │ DOUBLE │ millisec      │                 │
154        │network...bytes         │ U64    │ byte          │                 │
155        │delta(...)              │ U64    │ byte          │                 │
156        │delta(...) / delta(...) │ DOUBLE │ byte/millisec │ /1048576 and    │
157        │                        │        │               │ *1000           │
158        │network...speed         │ FLOAT  │ Mbyte/sec     │                 │
159        │x                       │ DOUBLE │ Mbyte/sec     │                 │
160        └────────────────────────┴────────┴───────────────┴─────────────────┘
161       Because semantic checking cannot be done at the time pmRegisterDerived
162       is called, errors found during semantic checking are reported using
163       pmprintf(3).  These include:
164
165       Error: derived metric <name1>: operand: <name2>: <reason>
166              There was a problem calling pmLookupName(3) to identify the op‐
167              erand metric <name2> used in the definition of the derived met‐
168              ric <name1>.
169
170       Error: derived metric <name1>: operand (<name2> [<pmid2>]): <reason>
171              There was a problem calling pmLookupDesc(3) to identify the op‐
172              erand metric <name2> with PMID <pmid2> used in the definition of
173              the derived metric <name1>.
174
175       Semantic error: derived metric <name>: <operand> <op> <operand>: Ille‐
176       gal operator for counters
177              If both operands have the semantics of counter, only addition or
178              subtraction make sense, so multiplication and division are not
179              allowed.
180
181       Semantic error: derived metric <name>: <operand> <op> <operand>: Ille‐
182       gal operator for counter and non-counter
183              Only multiplication or division are allowed if the left operand
184              has the semantics of a counter and the right operand is not a
185              counter.
186
187       Semantic error: derived metric <name>: <operand> <op> <operand>: Ille‐
188       gal operator for non-counter and counter
189              Only multiplication is allowed if the right operand has the
190              semantics of a counter and the left operand is not a counter.
191
192       Semantic error: derived metric <name>: <operand> <op> <operand>: Non-
193       arithmetic type for <left-or-right> operand
194              The binary arithmetic operators are only allowed with operands
195              with an arithmetic type (integer of various sizes and signed‐
196              ness, float or double).
197
198       Semantic error: derived metric <name>: <function>(<operand>): Non-
199       arithmetic operand for function
200              The unary functions are only defined if the operand has arith‐
201              metic type.
202

EXPRESSION EVALUATION

204       For the binary arithmetic operators, if either operand must be scaled
205       (e.g. convert bytes to Kbytes) then the result is promoted to
206       PM_TYPE_DOUBLE.  Otherwise the type of the result is determined by the
207       types of the operands, as per the following table which is evaluated
208       from top to bottom until a match is found.
209
210               ┌─────────────────────────┬──────────┬────────────────┐
211               │     Operand Types       │ Operator │  Result Type   │
212               ├─────────────────────────┼──────────┼────────────────┤
213               │either is PM_TYPE_DOUBLE │ any      │ PM_TYPE_DOUBLE │
214               ├─────────────────────────┼──────────┼────────────────┤
215               │any                      │ division │ PM_TYPE_DOUBLE │
216               ├─────────────────────────┼──────────┼────────────────┤
217               │either is PM_TYPE_FLOAT  │ any      │ PM_TYPE_FLOAT  │
218               ├─────────────────────────┼──────────┼────────────────┤
219               │either is PM_TYPE_U64    │ any      │ PM_TYPE_U64    │
220               ├─────────────────────────┼──────────┼────────────────┤
221               │either is PM_TYPE_64     │ any      │ PM_TYPE_64     │
222               ├─────────────────────────┼──────────┼────────────────┤
223               │either is PM_TYPE_U32    │ any      │ PM_TYPE_U32    │
224               ├─────────────────────────┼──────────┼────────────────┤
225               │otherwise (both are      │ any      │ PM_TYPE_32     │
226               │PM_TYPE_32)              │          │                │
227               └─────────────────────────┴──────────┴────────────────┘

CAVEATS

229       Unary negation is not supported, so the following expressions would be
230       syntactically incorrect, -3*abc and -this.number
231
232       Derived metrics are not available when using pmFetchArchive(3) as this
233       routine does not use a target list of PMIDs that could be remapped (as
234       is done for pmFetch(3)).
235
236       Derived metrics are not available with the routines pmRequestTra‐
237       versePMNS(3) and pmReceiveTraversePMNS(3) because the by the time the
238       list of names is received, the original name at the root of the search
239       is no longer available.
240
241       pmRegisterDerived does not apply retrospectively to any open contexts,
242       so the normal use would be to make all calls to pmRegisterDerived (pos‐
243       sibly via pmLoadDerivedConfig(3)) and then call pmNewContext(3).
244
245       There is no pmUnregisterDerived method, so once registered a derived
246       metric persists for the life of the application.
247

DIAGNOSTICS

249       On success, pmRegisterDerived returns NULL.
250
251       If a syntactic error is found at the time of registration, the value
252       returned by pmRegisterDerived is a pointer into expr indicating where
253       the error was found.  To identify what the error was, the application
254       should call pmDerivedErrStr(3) to retrieve the corresponding parser
255       error message.
256

SEE ALSO

258       PCPIntro(1), PMAPI(3), pmDerivedErrStr(3), pmFetch(3), pmLoadDerived‐
259       Config(3), pmNewContext(3) and pmReconnectContext(3).
260
261
262
263Performance Co-Pilot                                      PMREGISTERDERIVED(3)
Impressum