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(5).
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() and
68         instant()),  the type of the operand metric must be arithmetic (inte‐
69         ger of various sizes and signedness, float or double).
70
71           ┌───────────┬────────────────────────────────────────────────────┐
72           │ Function  │                       Value                        │
73           ├───────────┼────────────────────────────────────────────────────┤
74           │avg(x)     │ A singular instance being the average value across │
75           │           │ all instances for the metric x.                    │
76           ├───────────┼────────────────────────────────────────────────────┤
77           │count(x)   │ A  singular instance being the count of the number │
78           │           │ of 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 │
82           │           │ is one value in the result for each instance  that │
83           │           │ appears  in both the current and the previous sam‐ │
84           │           │ ple.                                               │
85           ├───────────┼────────────────────────────────────────────────────┤
86           │rate(x)    │ Returns the difference in values for the metric  x │
87           │           │ between  one  call  to  pmFetch(3)  and  the  next │
88           │           │ divided by the elapsed time between the  calls  to │
89           │           │ pmFetch(3).   The  semantics of the derived metric │
90           │           │ are based on the semantics of the operand (x) with │
91           │           │ the  dimension in the time domain decreased by one │
92           │           │ and scaling if required in  the  time  utilization │
93           │           │ case  where  the  operand is in units of time, and │
94           │           │ the derived metric is unitless.  This  mimics  the │
95           │           │ rate  conversion  applied  to  counter  metrics by │
96           │           │ tools such as pmval(1),  pmie(1)  and  pmchart(1). │
97           │           │ There is one value in the result for each instance │
98           │           │ that appears in both the current and the  previous │
99           │           │ sample.                                            │
100           ├───────────┼────────────────────────────────────────────────────┤
101           │instant(x) │ Returns the current value of the metric x, even it │
102           │           │ has   the   semantics   of   a    counter,    i.e. │
103           │           │ PM_SEM_COUNTER.  The semantics of the derived met‐ │
104           │           │ ric are based on the semantics of the operand (x); │
105           │           │ if  x  has semantics PM_SEM_COUNTER, the semantics │
106           │           │ of instant(x)  is  PM_SEM_INSTANT,  otherwise  the │
107           │           │ semantics of the derived metric is the same as the │
108           │           │ semantics of the metric x.                         │
109           ├───────────┼────────────────────────────────────────────────────┤
110           │max(x)     │ A singular instance being the maximum value across │
111           │           │ all instances for the metric x.                    │
112           ├───────────┼────────────────────────────────────────────────────┤
113           │min(x)     │ A singular instance being the minimum value across │
114           │           │ all instances for the metric x.                    │
115           ├───────────┼────────────────────────────────────────────────────┤
116           │sum(x)     │ A singular instance being the sum  of  the  values │
117           │           │ across all instances for the metric x.             │
118           └───────────┴────────────────────────────────────────────────────┘
119       * White space is ignored.
120
121       Syntactic  checking  is  performed  at  the  time  pmRegisterDerived is
122       called, but semantic checking is deferred until  each  new  context  is
123       created  with  pmNewContext(3)  or  re-established with pmReconnectCon‐
124       text(3), at which time the PMNS and  metadata  is  available  to  allow
125       semantic  checking and the metadata of the derived metrics to be estab‐
126       lished.
127

SEMANTIC CHECKS AND RULES

129       There are a number of conversions required to  determine  the  metadata
130       for a derived metric and to ensure the semantics of the expressions are
131       sound.
132
133       In a binary expression, if the semantics of  both  operands  is  not  a
134       counter  (i.e.  PM_SEM_INSTANT or PM_SEM_DISCRETE) then the result will
135       have semantics PM_SEM_INSTANT unless both operands are  PM_SEM_DISCRETE
136       in which case the result is also PM_SEM_DISCRETE.
137
138       The mapping of the pmUnits of the metadata uses the following rules:
139
140       * If both operands have a dimension of COUNT and the scales are not the
141         same, use the larger scale and convert the values of the operand with
142         the smaller scale.
143
144       * If  both operands have a dimension of TIME and the scales are not the
145         same, use the larger scale and convert the values of the operand with
146         the smaller scale.
147
148       * If both operands have a dimension of SPACE and the scales are not the
149         same, use the larger scale and convert the values of the operand with
150         the smaller scale.
151
152       * For  addition and subtraction all dimensions for each of the operands
153         and result are identical.
154
155       * For multiplication, the dimensions of the result are the sum  of  the
156         dimensions of the operands.
157
158       * For  division, the dimensions of the result are the difference of the
159         dimensions of the operands.
160
161       Scale conversion involves division if the dimension  is  positive  else
162       multiplication  if  the  dimension  is negative. If scale conversion is
163       applied to either of the operands,  the  result  is  promoted  to  type
164       PM_TYPE_DOUBLE.
165
166       Putting all of this together in an example, consider the derived metric
167       defined as follows:
168          x = network.interface.speed - delta(network.interface.in.bytes) /
169                             delta(sample.milliseconds)
170       The type, dimension and scale settings would propagate up the expres‐
171       sion tree as follows.
172
173        ┌────────────────────────┬────────┬───────────────┬─────────────────┐
174        │      Expression        │  Type  │  Dimension &  │ Scale Factor(s) │
175        │                        │        │  Scale        │                 │
176        ├────────────────────────┼────────┼───────────────┼─────────────────┤
177        │sample.milliseconds     │ DOUBLE │ millisec      │                 │
178        │delta(...)              │ DOUBLE │ millisec      │                 │
179        │network...bytes         │ U64    │ byte          │                 │
180        │delta(...)              │ U64    │ byte          │                 │
181        │delta(...) / delta(...) │ DOUBLE │ byte/millisec │ /1048576 and    │
182        │                        │        │               │ *1000           │
183        │network...speed         │ FLOAT  │ Mbyte/sec     │                 │
184        │x                       │ DOUBLE │ Mbyte/sec     │                 │
185        └────────────────────────┴────────┴───────────────┴─────────────────┘
186       Because semantic checking cannot be done at the time pmRegisterDerived
187       is called, errors found during semantic checking are reported using
188       pmprintf(3).  These include:
189
190       Error: derived metric <name1>: operand: <name2>: <reason>
191              There was a problem calling pmLookupName(3) to identify the op‐
192              erand metric <name2> used in the definition of the derived met‐
193              ric <name1>.
194
195       Error: derived metric <name1>: operand (<name2> [<pmid2>]): <reason>
196              There was a problem calling pmLookupDesc(3) to identify the op‐
197              erand metric <name2> with PMID <pmid2> used in the definition of
198              the derived metric <name1>.
199
200       Semantic error: derived metric <name>: <operand> <op> <operand>: Ille‐
201       gal operator for counters
202              If both operands have the semantics of counter, only addition or
203              subtraction make sense, so multiplication and division are not
204              allowed.
205
206       Semantic error: derived metric <name>: <operand> <op> <operand>: Ille‐
207       gal operator for counter and non-counter
208              Only multiplication or division are allowed if the left operand
209              has the semantics of a counter and the right operand is not a
210              counter.
211
212       Semantic error: derived metric <name>: <operand> <op> <operand>: Ille‐
213       gal operator for non-counter and counter
214              Only multiplication is allowed if the right operand has the
215              semantics of a counter and the left operand is not a counter.
216
217       Semantic error: derived metric <name>: <operand> <op> <operand>: Non-
218       arithmetic type for <left-or-right> operand
219              The binary arithmetic operators are only allowed with operands
220              with an arithmetic type (integer of various sizes and signed‐
221              ness, float or double).
222
223       Semantic error: derived metric <name>: <function>(<operand>): Non-
224       arithmetic operand for function
225              The unary functions are only defined if the operand has arith‐
226              metic type.
227
228       Semantic error: derived metric <name>: Incorrect time dimension for op‐
229       erand
230              Rate conversion using the rate() function is only possible for
231              operand metrics with a Time dimension of 0 or 1 (see
232              pmLookupDesc(3)).  If the operand metric's Time dimension is 0,
233              then the derived metrics has a value "per second" (Time dimen‐
234              sion of -1).  If the operand metric's Time dimension is 1, then
235              the derived metrics has a value of time utilization (Time dimen‐
236              sion of 0).
237

EXPRESSION EVALUATION

239       For the binary arithmetic operators, if either operand must be scaled
240       (e.g. convert bytes to Kbytes) then the result is promoted to
241       PM_TYPE_DOUBLE.  Otherwise the type of the result is determined by the
242       types of the operands, as per the following table which is evaluated
243       from top to bottom until a match is found.
244
245               ┌─────────────────────────┬──────────┬────────────────┐
246               │     Operand Types       │ Operator │  Result Type   │
247               ├─────────────────────────┼──────────┼────────────────┤
248               │either is PM_TYPE_DOUBLE │ any      │ PM_TYPE_DOUBLE │
249               ├─────────────────────────┼──────────┼────────────────┤
250               │any                      │ division │ PM_TYPE_DOUBLE │
251               ├─────────────────────────┼──────────┼────────────────┤
252               │either is PM_TYPE_FLOAT  │ any      │ PM_TYPE_FLOAT  │
253               ├─────────────────────────┼──────────┼────────────────┤
254               │either is PM_TYPE_U64    │ any      │ PM_TYPE_U64    │
255               ├─────────────────────────┼──────────┼────────────────┤
256               │either is PM_TYPE_64     │ any      │ PM_TYPE_64     │
257               ├─────────────────────────┼──────────┼────────────────┤
258               │either is PM_TYPE_U32    │ any      │ PM_TYPE_U32    │
259               ├─────────────────────────┼──────────┼────────────────┤
260               │otherwise (both are      │ any      │ PM_TYPE_32     │
261               │PM_TYPE_32)              │          │                │
262               └─────────────────────────┴──────────┴────────────────┘

CAVEATS

264       Unary negation is not supported, so the following expressions would be
265       syntactically incorrect, -3*abc and -this.number
266
267       Derived metrics are not available when using pmFetchArchive(3) as this
268       routine does not use a target list of PMIDs that could be remapped (as
269       is done for pmFetch(3)).
270
271       pmRegisterDerived does not apply retrospectively to any open contexts,
272       so the normal use would be to make all calls to pmRegisterDerived (pos‐
273       sibly via pmLoadDerivedConfig(3)) and then call pmNewContext(3).
274
275       There is no pmUnregisterDerived method, so once registered a derived
276       metric persists for the life of the application.
277

DIAGNOSTICS

279       On success, pmRegisterDerived returns NULL.
280
281       If a syntactic error is found at the time of registration, the value
282       returned by pmRegisterDerived is a pointer into expr indicating where
283       the error was found.  To identify what the error was, the application
284       should call pmDerivedErrStr(3) to retrieve the corresponding parser
285       error message.
286

SEE ALSO

288       PCPIntro(1), PMAPI(3), pmDerivedErrStr(3), pmFetch(3), pmLoadDerived‐
289       Config(3), pmNewContext(3) and pmReconnectContext(3).
290
291
292
293Performance Co-Pilot                                      PMREGISTERDERIVED(3)
Impressum