1PMREGISTERDERIVED(3) Library Functions Manual PMREGISTERDERIVED(3)
2
3
4
6 pmRegisterDerived, pmRegisterDerivedMetric - register a global derived
7 metric name and definition
8
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
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 ┌──────────┬───────────────────────────────────────────────┐
172 │ tag │ value │
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
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
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 └─────────────────────────┴──────────┴────────────────┘
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
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
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)