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

NAME

6       pmRegisterDerived, pmRegisterDerivedMetric  - register a global derived
7       metric name and definition
8

C SYNOPSIS

10       #include <pcp/pmapi.h>
11
12       char *pmRegisterDerived(char *name, char *expr);
13       int pmRegisterDerivedMetric(char *name, char *expr, char **errmsg);
14
15       cc ... -lpcp
16

DESCRIPTION

18       Derived metrics provide a way of extending the Performance Metrics Name
19       Space  (PMNS)  with  new  metrics  defined at the PCP client-side using
20       expressions over the existing performance metrics.
21
22       Typical uses would be to aggregate a number of similar metrics to  pro‐
23       vide  a  higher-level  summary  metric or to support the ``delta V over
24       delta V'' class of metrics that are  not  possible  in  the  base  data
25       semantics  of PCP.  An example of the latter class would be the average
26       I/O size, defined as
27                 delta(disk.dev.total_bytes) / delta(disk.dev.total)
28       where both of the disk.dev metrics are counters, and what  is  required
29       is  to  to sample both metrics, compute the difference between the cur‐
30       rent and previous values and then calculate the ratio of these  differ‐
31       ences.
32
33       The arguments to pmRegisterDerived are the name of the new derived met‐
34       ric and expr is an expression defining how the values of name should be
35       computed.
36
37       pmRegisterDerivedMetric  is the exact functional equivalent to pmRegis‐
38       terDerived except that it provides a simplified  model  of  error  han‐
39       dling, where a formatted message is returned via the errmsg parameter.
40
41       Syntactic  checking  is  performed  at  the  time  pmRegisterDerived is
42       called, but semantic checking is deferred until each new PMAPI  context
43       is  created with pmNewContext(3) or re-established with pmReconnectCon‐
44       text(3), at which time the PMNS and  metadata  is  available  to  allow
45       semantic  checking and the metadata of the derived metrics to be deter‐
46       mined.
47
48       If pmRegisterDerived is called after one or  more  PMAPI  contexts  has
49       been  opened,  then  the  newly  registered metrics will be avaiable in
50       those contexts, however the more normal use would be to make all  calls
51       to  pmRegisterDerived (possibly via pmLoadDerivedConfig(3)) or pmRegis‐
52       terDerivedMetric before calling pmNewContext(3).
53
54       All of the defined global derived metrics are available  in  all  PMAPI
55       contexts.
56
57       It  is also possible to define per-context derived metrics once a PMAPI
58       context has been establised.  These derived metrics are private to  the
59       context  in  which  they  are  defined  using the allied routines pmAd‐
60       dDerived(3) and pmAddDerivedMetric(3).
61
62       name should follow the syntactic rules for  the  names  of  performance
63       metrics,  namely  one  or more components separated with a dot (``.''),
64       and each component must begin with an alphabetic followed  by  zero  or
65       more  characters  drawn  from  the alphabetics, numerics and underscore
66       (``_'').  For more details, refer to PCPIntro(1) and PMNS(5).
67
68       name must be unique across all derived metrics and should not match the
69       name  of  any regular metric in the PMNS.  It is acceptable for name to
70       share some part of its prefix with an existing  subtree  of  the  PMNS,
71       e.g.  the  average  I/O size metric above could be named disk.dev.avgsz
72       which would place it amongst the other disk.dev metrics  in  the  PMNS.
73       Alternatively,  derived metrics could populate their own subtree of the
74       PMNS, e.g. the average I/O size metric above  could  be  named  my.sum‐
75       mary.disk.avgsz.
76
77       The expression expr follows these syntactic rules:
78
79       * Terminal  elements  are  either  names of existing metrics or numeric
80         constants.  Recursive definitions are not allowed, so only the  names
81         of  regular  metrics (not other derived metrics) may be used. Numeric
82         constants are either integers constrained to the precision of  32-bit
83         unsigned integers or double precision floating point numbers.
84
85       * The  usual binary arithmetic operators are supported, namely addition
86         (``+''), subtraction (``-''),  multiplication  (``*'')  and  division
87         (``/'')  with  the  normal  precedence rules where multiplication and
88         division have higher precedence than  addition  and  subtraction,  so
89         a+b*c is evaluated as a+(b*c).
90
91       * Unary negation may be used, e.g.  -3*some.metric.
92
93       * C-style  relational  operators  are  supported, namely ``<'', ``<='',
94         ``=='', ``>='', ``>'' and ``!=''.  Relational expresssions  return  a
95         value  as  a 32-bit unsigned number being 0 for false and 1 for true.
96         The expected operator precedence rules apply, so arithmetic operators
97         have  higher  precedence  than  relational  operators, and a-b>c+d is
98         evaluated as (a-b)>(c+d).  All the relational  operators  have  equal
99         precedence,  so  the  (slightly odd) expression involving consecutive
100         relational operators a>b!=c is evaluated as (a>b)!=c.
101
102       * C-style boolean operators are supported, namely and (``&&'')  and  or
103         (``||'').   Boolean  expresssions return a value as a 32-bit unsigned
104         number being 0 for false and  1  for  true.   The  expected  operator
105         precedence  rules  apply,  so relational operators have higher prece‐
106         dence than boolean  operators,  and  a>b*c&&d<=e+f  is  evaluated  as
107         (a>(b*c))&&(d<=(e+f)).   Both the boolean operators have equal prece‐
108         dence, so the  expression  involving  consecutive  boolean  operators
109         a>=b||b>c&&d!=e||f>g            is            evaluated            as
110         (((a>=b)||(b>c))&&(d!=e))||(f>g).
111
112       * Additionally, the ``!'' operator may be used to negate a  boolean  or
113         relational  expression, returning a value as a 32-bit unsigned number
114         being 0 for false and 1 for true.  The expected  operator  precedence
115         rules apply, so boolean (and relational) operators have higher prece‐
116         dence  than  boolean  negation,  and  !a>b||c<d   is   evaluated   as
117         !((a>b)||(c<d)), while !a<b+c is evaluated as !(a<(b+c)).
118
119       * C-style  ternary  conditional  expressions  are supported. In general
120         terms the expression check ? foo :  bar  is  evaluated  as  foo  (the
121         ``true''  operand) if check (the ``guard'') is true, else the expres‐
122         sion evaluates to bar (the ``false'' operand).  Some special semantic
123         rules  apply  to  the  ``guard'' expression and the other two operand
124         expressions:
125         (a) Each expression may involve a singular value or a set  of  values
126             (when  the  expression  involves  one  or  more  metrics  with an
127             instance domain).
128         (b) All expressions with a set of values must  be  defined  over  the
129             same instance domain.
130         (c) Both operand expressions must have the same metadata, so the same
131             metric type, semantics and units (dimension and scale).
132         (d) The ``guard'' expression must have an aritmetic or relational  or
133             boolean  value,  so that it can be evaluated as 0 for false, else
134             true.
135         (e) If the ``guard'' expression has a singular value and one or  more
136             of the other operand expressions involves an instance domain, the
137             ``guard'' applies to all instances.
138         (f) If the ``guard'' expression has a set of values and one  or  more
139             of the other operand expressions involves an instance domain, the
140             ``guard'' is evaluated once for each instance (there must be  one
141             instance domain as per rule (b) above).
142         (g) If  one  of  the operand expressions has a singular value and the
143             other has a set of values, and the  singular  value  is  selected
144             based  on  the  evaluation of the ``guard'', then the result is a
145             set of values (all the  same)  with  instance  enumeration  being
146             taken  from  the  other  operand  expression.  For example in the
147             expression: foo ? scalar : set, if foo is true, then  the  result
148             is  a  set of values (all having the same value, scalar) over the
149             instance domain of set.
150
151       * Selection of a single instance can  be  specified  by  the  construct
152         ``[instance_name]''  which  may  be  appended  to  a metric name or a
153         parenthesized expression.  For example:
154         fw.bytes = network.interface.in.bytes[eth1] + \
155                    network.interface.out.bytes[eth1]
156         or (equivalently):
157         fw.bytes = (network.interface.in.bytes + \
158                     network.interface.out.bytes)[eth1]
159
160         All characters between the ``['' and ``]'' are considered to be  part
161         of  the (external) instance name, so be careful to avoid any spurious
162         white space.  A backslash may be used as  an  escape  prefix  in  the
163         (unlikely) event that the external instance name contains a ``]''.
164
165       * Numeric constants can also be specified using the mkconst() construc‐
166         tor which takes a number of arguments: the first is  a  numeric  con‐
167         stant  (either  integer  or  floating point), then follow one or more
168         parameters of the form tag=value or tag= where the allowed values  of
169         tag and value are as follows:
170
171              ┌──────────┬───────────────────────────────────────────────┐
172tagvalue
173              ├──────────┼───────────────────────────────────────────────┤
174              │type      │ one   of   the   numeric  metric  types  from │
175              │          │ <pcp/pmapi.h>, stripped of the PM_TYPE_  pre‐ │
176              │          │ fix, so 32, U32, 64, U64, FLOAT or DOUBLE.    │
177              ├──────────┼───────────────────────────────────────────────┤
178              │semantics │ one of the semantic types from <pcp/pmapi.h>, │
179              │          │ stripped of the PM_SEM_ prefix,  so  COUNTER, │
180              │          │ INSTANT or DISCRETE.                          │
181              ├──────────┼───────────────────────────────────────────────┤
182              │units     │ a   specification   of  dimension  and  scale │
183              │          │ (together forming the units), in  the  syntax │
184              │          │ accepted by pmParseUnitsStr(3).               │
185              └──────────┴───────────────────────────────────────────────┘
186         The value may optionally be enclosed in double quotes, and may appear
187         in any mix of upper and/or lower case.  The tag must be in lower case
188         as shown in the table above.
189
190         This  is  most  useful when the expression semantics require matching
191         type and/or semantics and/or units for operands, e.g.
192         idle = mem.util.free > mkconst(10485760, units=Kbyte)
193         avg_io_size = delta(disk.dev.total) == 0 ? \
194             -mkconst(1.0, semantics=instant, units="kbyte / count") : \
195             delta(disk.dev.total_bytes) / delta(disk.dev.total)
196
197       * Expressions may be rescaled using the rescale function that takes two
198         arguments.  The first is an arithmetic expression to be rescaled, and
199         the second is the desired units after  rescaling  that  is  a  string
200         value in the syntax accepted by pmParseUnitsStr(3).  For example:
201         rescale(network.interface.total.bytes, "Mbytes/hour")
202
203         The  expression  and the desired units must both have the same dimen‐
204         sion, e.g Space=1, Time=-1 and Count=0 in the example above.
205
206       * The following unary functions operate on a single performance  metric
207         and  return  one  or more values.  For all functions (except count(),
208         defined() and instant()), the type of  the  operand  metric  must  be
209         arithmetic  (integer  of  various sizes and signedness, float or dou‐
210         ble).
211
212             ┌───────────┬───────────────────────────────────────────────┐
213             │ Function  │                     Value                     │
214             ├───────────┼───────────────────────────────────────────────┤
215             │avg(x)     │ A singular instance being the  average  value │
216             │           │ across all instances for the metric x.        │
217             ├───────────┼───────────────────────────────────────────────┤
218             │count(x)   │ A  singular  instance  being the count of the │
219             │           │ number of instances for the metric x.   As  a │
220             │           │ special   case,  if  fetching  the  metric  x │
221             │           │ returns an error, then count(x) will be 0.    │
222             ├───────────┼───────────────────────────────────────────────┤
223             │defined(x) │ A boolean value that is true (``1'')  if  the │
224             │           │ metric  x  is defined in the PMNS, else false │
225             │           │ (``0'').  The function is  evaluated  when  a │
226             │           │ new  PMAPI  context is created with pmNewCon‐ 
227             │           │ text(3) or re-established  with  pmReconnect‐ 
228             │           │ Context(3).  So any subsequent changes to the │
229             │           │ PMNS after the PMAPI context has been  estab‐ │
230             │           │ lished  will  not  change  the  value of this │
231             │           │ function in the expression evaluation.        │
232             ├───────────┼───────────────────────────────────────────────┤
233             │delta(x)   │ Returns the difference in values for the met‐ │
234             │           │ ric  x between one call to pmFetch(3) and the │
235             │           │ next. There is one value in  the  result  for │
236             │           │ each  instance  that appears in both the cur‐ │
237             │           │ rent and the previous sample.                 │
238             ├───────────┼───────────────────────────────────────────────┤
239             │rate(x)    │ Returns the difference in values for the met‐ │
240             │           │ ric  x between one call to pmFetch(3) and the │
241             │           │ next divided by the elapsed time between  the │
242             │           │ calls  to  pmFetch(3).   The semantics of the │
243             │           │ derived metric are based on the semantics  of │
244             │           │ the  operand  (x)  with  the dimension in the │
245             │           │ time domain decreased by one and  scaling  if │
246             │           │ required  in  the time utilization case where │
247             │           │ the operand is in  units  of  time,  and  the │
248             │           │ derived  metric is unitless.  This mimics the │
249             │           │ rate conversion applied to counter metrics by │
250             │           │ tools   such   as   pmval(1),   pmie(1)   and │
251             │           │ pmchart(1).  There is one value in the result │
252             │           │ for  each  instance  that appears in both the │
253             │           │ current and the previous sample.              │
254             ├───────────┼───────────────────────────────────────────────┤
255             │instant(x) │ Returns the current value of  the  metric  x, │
256             │           │ even  it has the semantics of a counter, i.e. │
257             │           │ PM_SEM_COUNTER.  The semantics of the derived │
258             │           │ metric  are based on the semantics of the op‐ │
259             │           │ erand (x); if x has semantics PM_SEM_COUNTER, │
260             │           │ the     semantics     of     instant(x)    is │
261             │           │ PM_SEM_INSTANT, otherwise  the  semantics  of │
262             │           │ the  derived metric is the same as the seman‐ │
263             │           │ tics of the metric x.                         │
264             ├───────────┼───────────────────────────────────────────────┤
265             │max(x)     │ A singular instance being the  maximum  value │
266             │           │ across all instances for the metric x.        │
267             ├───────────┼───────────────────────────────────────────────┤
268             │min(x)     │ A  singular  instance being the minimum value │
269             │           │ across all instances for the metric x.        │
270             ├───────────┼───────────────────────────────────────────────┤
271             │sum(x)     │ A singular instance being the sum of the val‐ │
272             │           │ ues across all instances for the metric x.    │
273             └───────────┴───────────────────────────────────────────────┘
274       * The  matchinst  function  may  be  used  to  select  a  subset of the
275         instances from an instance domain for a metric  or  expression.   The
276         function takes two arguments:
277         (a) A  instance filter that consists of an optional negation operator
278             ``!'' followed by a regular expression delimited by ``/'' charac‐
279             ters.   The regular expression follows the POSIX Extended Regular
280             Expression syntax as described in regex(3).  Backslashes  may  be
281             used  as  escape  prefixes,  but  double backslash is required to
282             escape any regular expression special characters,  e.g.  for  the
283             (extremely unlikely) case of wanting to match instance names like
284             ``some*text/other[text]''  a  regular  expression  of  the   form
285             /some\\*text\/other\\[text]/  would be required.  If present, the
286             negation operator reverses the sense of  the  filtering,  so  all
287             instances not matching the regular expression will be selected.
288         (b) A  metric  or  expression  that  must be defined over an instance
289             domain.
290
291         For example, the following expression will have values for the metric
292         network.interface.in.bytes  for  all  network  interfaces  except the
293         loopback and virtual bridge devices:
294         matchinst(!/^(lo)|(vbir)/, network.interface.in.bytes)
295
296       * The scalar function may  be  used  convert  a  metric  or  expression
297         defined  over an instance domain into a scalar value that can be used
298         in other expressions.  For example:
299         net.in.bytes = scalar(network.interface.in.bytes[eth0]) + \
300                    scalar(network.interface.in.bytes[eth1])
301
302         The instance domain is removed from the metadata for the  result  and
303         the instance identifier is removed from the value during fetching.
304
305         If  the metric or expression involves more than one instance then the
306         result is formed by picking the first instance -  this  is  arbitrary
307         and  implies  the  scalar function should only be used for metrics or
308         expressions that are expected to contain zero or one instances,  e.g.
309         the  construct  ``[instance_name]''  or the matchinst function with a
310         pattern that matches at most one instance.
311
312       * Parenthesis may be used for explicit grouping.
313
314       * Lines beginning with ``#'' are treated as comments and ignored.
315
316       * White space is ignored.
317

SEMANTIC CHECKS AND RULES

319       There are a number of conversions required to  determine  the  metadata
320       for a derived metric and to ensure the semantics of the expressions are
321       sound.
322
323       In an arithmetic expression or a relational expression, if  the  seman‐
324       tics  of  both  operands  is  not  a  counter  (i.e.  PM_SEM_INSTANT or
325       PM_SEM_DISCRETE) then the result  will  have  semantics  PM_SEM_INSTANT
326       unless  both  operands  are PM_SEM_DISCRETE in which case the result is
327       also PM_SEM_DISCRETE.
328
329       For an arithmetic expression, the dimension of each operand must be the
330       same.   For a relational expression, the dimension of each operand must
331       be the same, except that numeric  constants  (with  no  dimension)  are
332       allowed, e.g. in the expression network.interface.in.drops > 0 .
333
334       To  prevent  arbitrary  and non-sensical combinations some restrictions
335       apply to expressions that combine metrics  with  counter  semantics  to
336       produce a result with counter semantics.  For an arithmetic expression,
337       if both operands have the semantics of a counter, then only addition or
338       subtraction  is  allowed,  or  if the left operand is a counter and the
339       right operand is not, then only multiplication or division are allowed,
340       or  if  the  left  operand  is not a counter and the right operand is a
341       counter, then only multiplication is allowed.
342
343       Because relational expressions use the current value only and produce a
344       result  that  is not a counter, either or both operands of a relational
345       expression may be counters.
346
347       The mapping of the pmUnits of the metadata uses the following rules:
348
349       * If both operands have a dimension of Count and the scales are not the
350         same, use the larger scale and convert the values of the operand with
351         the smaller scale.
352
353       * If both operands have a dimension of Time and the scales are not  the
354         same, use the larger scale and convert the values of the operand with
355         the smaller scale.
356
357       * If both operands have a dimension of Space and the scales are not the
358         same, use the larger scale and convert the values of the operand with
359         the smaller scale.
360
361       * For addition and subtraction all dimensions for each of the  operands
362         and result are identical.
363
364       * For  multiplication,  the dimensions of the result are the sum of the
365         dimensions of the operands.
366
367       * For division, the dimensions of the result are the difference of  the
368         dimensions of the operands.
369
370       Scale  conversion  involves  division if the dimension is positive else
371       multiplication if the dimension is negative.  If  scale  conversion  is
372       applied  to  either  of  the  operands,  the result is promoted to type
373       PM_TYPE_DOUBLE.
374
375       Putting all of this together in an example, consider the derived metric
376       defined as follows:
377          x = network.interface.speed - delta(network.interface.in.bytes) /
378                             delta(sample.milliseconds)
379       The type, dimension and scale settings would propagate up the expres‐
380       sion tree as follows.
381
382        ┌────────────────────────┬────────┬───────────────┬─────────────────┐
383        │      Expression        │  Type  │  Dimension &  │ Scale Factor(s) │
384        │                        │        │  Scale        │                 │
385        ├────────────────────────┼────────┼───────────────┼─────────────────┤
386        │sample.milliseconds     │ DOUBLE │ millisec      │                 │
387        │delta(...)              │ DOUBLE │ millisec      │                 │
388        │network...bytes         │ U64    │ byte          │                 │
389        │delta(...)              │ U64    │ byte          │                 │
390        │delta(...) / delta(...) │ DOUBLE │ byte/millisec │ /1048576 and    │
391        │                        │        │               │ *1000           │
392        │network...speed         │ FLOAT  │ Mbyte/sec     │                 │
393        │x                       │ DOUBLE │ Mbyte/sec     │                 │
394        └────────────────────────┴────────┴───────────────┴─────────────────┘
395       Expressions involving single instance selection or the matchinst func‐
396       tion must be associated with underlying metrics that have an instance
397       domain.  These constructors make no sense for singular metrics.
398
399       Because semantic checking cannot be done at the time pmRegisterDerived
400       is called, errors found during semantic checking (when any subsequent
401       calls to pmNewContext(3) or pmReconnectContext(3) succeed) are reported
402       using pmprintf(3).  These include:
403
404       Error: derived metric <name1>: operand: <name2>: <reason>
405              There was a problem calling pmLookupName(3) to identify the op‐
406              erand metric <name2> used in the definition of the derived met‐
407              ric <name1>.
408
409       Error: derived metric <name1>: operand (<name2> [<pmid2>]): <reason>
410              There was a problem calling pmLookupDesc(3) to identify the op‐
411              erand metric <name2> with PMID <pmid2> used in the definition of
412              the derived metric <name1>.
413
414       Semantic error: derived metric <name>: <operand> : <operand> Different
415       <metadata> for ternary operands
416              For a ternary expression, the ``true'' operand and the ``false''
417              operand must have exactly the same metadata, so type, semantics,
418              instance domain, and units (dimension and scale).
419
420       Semantic error: derived metric <name>: <operand> <op> <operand>: Dimen‐
421       sions are not the same
422              Operands must have the same units (dimension and scale) for each
423              of addition, subtraction, the relational operators and the bool‐
424              ean ``and'' or ``or'' operators.
425
426       Semantic error: derived metric <name>: <operand> <op> <operand>: Ille‐
427       gal operator for counter and non-counter
428              Only multiplication or division are allowed if the left operand
429              has the semantics of a counter and the right operand is not a
430              counter.
431
432       Semantic error: derived metric <name>: <operand> <op> <operand>: Ille‐
433       gal operator for counters
434              If both operands have the semantics of counter, only addition or
435              subtraction make sense, so multiplication and division are not
436              allowed.
437
438       Semantic error: derived metric <name>: <operand> <op> <operand>: Ille‐
439       gal operator for non-counter and counter
440              Only multiplication is allowed if the right operand has the
441              semantics of a counter and the left operand is not a counter.
442
443       Semantic error: derived metric <metric> <expr> RESCALE <units>: Incom‐
444       patible dimensions
445              The parameters <expr> and <units> to the rescale function must
446              have the same dimension along the axes of Time, Space and Count.
447
448       Semantic error: derived metric <name>: Incorrect time dimension for op‐
449       erand
450              Rate conversion using the rate() function is only possible for
451              operand metrics with a Time dimension of 0 or 1 (see
452              pmLookupDesc(3)).  If the operand metric's Time dimension is 0,
453              then the derived metrics has a value "per second" (Time dimen‐
454              sion of -1).  If the operand metric's Time dimension is 1, then
455              the derived metrics has a value of time utilization (Time dimen‐
456              sion of 0).
457
458       Semantic error: derived metric <name>: <function>(<operand>): Non-
459       arithmetic operand for function
460              The unary functions are only defined if the operand has arith‐
461              metic type.  Similarly the first argument to the rescale func‐
462              tion must be of arithmetic type.
463
464       Semantic error: derived metric <name>: <expr> ? ...: Non-arithmetic op‐
465       erand for ternary guard
466              The first expression for a ternary operator must have an arith‐
467              metic type.
468
469       Semantic error: derived metric <name>: ... - ...: Non-arithmetic oper‐
470       and for unary negation
471              Unary negation only makes sense if the following expression has
472              an arithmetic type.
473
474       Semantic error: derived metric <name>: <operand> <op> <operand>: Non-
475       arithmetic type for <left-or-right> operand
476              The binary arithmetic operators are only allowed with operands
477              with an arithmetic type (integer of various sizes and signed‐
478              ness, float or double).
479
480       Semantic error: derived metric <name>: <operand> <op> <operand>: Non-
481       counter and not dimensionless <left-or-right> operand
482              For multiplication or division or any of the relational opera‐
483              tors, if one of the operands has the semantics of a counter and
484              the other has the semantics of a non-counter (instantaneous or
485              discrete) then the non-counter operand must have no units
486              (dimension and scale).
487
488       Semantic error: derived metric <name>: <expr> ? <expr> : <expr>: Non-
489       scalar ternary guard with scalar expressions
490              If the ``true'' and ``false'' operands of a ternary expression
491              have a scalar value, then the ``guard'' expression must also
492              have a scalar value.
493
494       Semantic error: derived metric <name>: <expr> <op> <expr>: Operands
495       should have the same instance domain
496              For all of the binary operators (arithmetic and relational), if
497              both operands have non-scalar values, then they must be defined
498              over the same instance domain.
499

EXPRESSION EVALUATION

501       For the binary arithmetic operators, if either operand must be scaled
502       (e.g. convert bytes to Kbytes) then the result is promoted to
503       PM_TYPE_DOUBLE.  Otherwise the type of the result is determined by the
504       types of the operands, as per the following table which is evaluated
505       from top to bottom until a match is found.
506
507               ┌─────────────────────────┬──────────┬────────────────┐
508               │     Operand Types       │ Operator │  Result Type   │
509               ├─────────────────────────┼──────────┼────────────────┤
510               │either is PM_TYPE_DOUBLE │ any      │ PM_TYPE_DOUBLE │
511               ├─────────────────────────┼──────────┼────────────────┤
512               │any                      │ division │ PM_TYPE_DOUBLE │
513               ├─────────────────────────┼──────────┼────────────────┤
514               │either is PM_TYPE_FLOAT  │ any      │ PM_TYPE_FLOAT  │
515               ├─────────────────────────┼──────────┼────────────────┤
516               │either is PM_TYPE_U64    │ any      │ PM_TYPE_U64    │
517               ├─────────────────────────┼──────────┼────────────────┤
518               │either is PM_TYPE_64     │ any      │ PM_TYPE_64     │
519               ├─────────────────────────┼──────────┼────────────────┤
520               │either is PM_TYPE_U32    │ any      │ PM_TYPE_U32    │
521               ├─────────────────────────┼──────────┼────────────────┤
522               │otherwise (both are      │ any      │ PM_TYPE_32     │
523               │PM_TYPE_32)              │          │                │
524               └─────────────────────────┴──────────┴────────────────┘

CAVEATS

526       Derived metrics are not available when using pmFetchArchive(3) as this
527       routine does not use a target list of PMIDs that could be remapped (as
528       is done for pmFetch(3)).
529
530       There is no pmUnregisterDerived method, so once registered a derived
531       metric persists for the life of the application.
532

DIAGNOSTICS

534       On success, pmRegisterDerived returns NULL.
535
536       If a syntactic error is found at the time of registration, the value
537       returned by pmRegisterDerived is a pointer into expr indicating where
538       the error was found.  To identify what the error was, the application
539       should call pmDerivedErrStr(3) to retrieve the corresponding parser
540       error message.
541
542       pmRegisterDerivedMetric returns 0 and errmsg is undefined if the pars‐
543       ing is successful.
544
545       If the given expr does not conform to the required syntax pmRegister‐
546       DerivedMetric returns -1 and a dynamically allocated error message
547       string in errmsg.  The error message is terminated with a newline and
548       includes both the input name and expr, along with an indicator of the
549       position at which the error was detected.  e.g.
550                 Error: pmRegisterDerivedMetric("my.disk.rates", ...) syntax
551                 error
552                 4rat(disk.dev.read)
553                     ^
554
555       The position indicator line may be followed by an additional diagnostic
556       line describing the nature of the error, when available.
557
558       In the case of an error, the caller is responsible for calling free(3)
559       to release the space allocated for errmsg.
560

SEE ALSO

562       PCPIntro(1), free(3), pmAddDerived(3), pmAddDerivedMetric(3), PMAPI(3),
563       pmDerivedErrStr(3), pmFetch(3), pmLoadDerivedConfig(3), pmNewCon‐
564       text(3), pmprintf(3), pmReconnectContext(3) and PMNS(5).
565
566
567
568Performance Co-Pilot                                      PMREGISTERDERIVED(3)
Impressum