Changeset View
Standalone View
share/man/man3/stats.3
- This file was added.
| .\" | |||||
| .\" Copyright (c) 2016-2018 Netflix, Inc. | |||||
| .\" All rights reserved. | |||||
| .\" | |||||
| .\" Redistribution and use in source and binary forms, with or without | |||||
| .\" modification, are permitted provided that the following conditions | |||||
| .\" are met: | |||||
| .\" 1. Redistributions of source code must retain the above copyright | |||||
| .\" notice, this list of conditions, and the following disclaimer, | |||||
| .\" without modification, immediately at the beginning of the file. | |||||
| .\" 2. The name of the author may not be used to endorse or promote products | |||||
| .\" derived from this software without specific prior written permission. | |||||
| .\" | |||||
| .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |||||
| .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||||
| .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||||
| .\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR | |||||
| .\" ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||||
| .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||||
| .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||||
| .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||||
| .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||||
| .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||||
| .\" SUCH DAMAGE. | |||||
| .\" | |||||
| .\" $FreeBSD$ | |||||
| .\" | |||||
| .Dd July 8, 2018 | |||||
| .Dt STATS 3 | |||||
| .Os | |||||
| .Sh NAME | |||||
| .Nm stats | |||||
| .Nd statistics gathering | |||||
| .Sh LIBRARY | |||||
| .Lb libstats | |||||
| .Sh SYNOPSIS | |||||
| .In sys/arb.h | |||||
| .In sys/qmath.h | |||||
| .In sys/stats.h | |||||
| .Ss Stats Blob Template Management Functions | |||||
| .Ft int | |||||
| .Fo stats_tpl_alloc | |||||
| .Fa "const char *name" | |||||
| .Fa "uint32_t flags" | |||||
| .Fc | |||||
| .Ft int | |||||
| .Fo stats_tpl_fetch_allocid | |||||
| .Fa "const char *name" | |||||
| .Fa "uint32_t hash" | |||||
| .Fc | |||||
| .Ft int | |||||
| .Fo stats_tpl_fetch | |||||
| .Fa "int tpl_id" | |||||
| .Fa "struct statsblob_tpl **tpl" | |||||
| .Fc | |||||
| .Ft int | |||||
| .Fo stats_tpl_id2name | |||||
| .Fa "uint32_t tpl_id" | |||||
| .Fa "char *buf" | |||||
| .Fa "size_t len" | |||||
| .Fc | |||||
| .Ft int | |||||
| .Fo stats_tpl_sample_rates | |||||
| .Fa "SYSCTL_HANDLER_ARGS" | |||||
| .Fc | |||||
| .Ft int | |||||
| .Fo stats_tpl_sample_rollthedice | |||||
| .Fa "struct stats_tpl_sample_rate *rates" | |||||
| .Fa "int nrates" | |||||
| .Fa "void *seed_bytes" | |||||
| .Fa "size_t seed_len" | |||||
| .Fc | |||||
| .Ft struct voistatspec | |||||
| .Fo STATS_VSS_SUM | |||||
| .Fc | |||||
| .Ft struct voistatspec | |||||
| .Fo STATS_VSS_MAX | |||||
| .Fc | |||||
| .Ft struct voistatspec | |||||
| .Fo STATS_VSS_MIN | |||||
| .Fc | |||||
| .Ft struct voistatspec | |||||
| .Fo STATS_VSS_CRHIST<32|64>_LIN | |||||
| .Fa "lb" | |||||
| .Fa "ub" | |||||
| .Fa "stepinc" | |||||
| .Fa "vsdflags" | |||||
| .Fc | |||||
| .Ft struct voistatspec | |||||
| .Fo STATS_VSS_CRHIST<32|64>_EXP | |||||
| .Fa "lb" | |||||
| .Fa "ub" | |||||
| .Fa "stepbase" | |||||
| .Fa "stepexp" | |||||
| .Fa "vsdflags" | |||||
| .Fc | |||||
| .Ft struct voistatspec | |||||
| .Fo "STATS_VSS_CRHIST<32|64>_LINEXP" | |||||
| .Fa "lb" | |||||
| .Fa "ub" | |||||
| .Fa "nlinsteps" | |||||
| .Fa "stepbase" | |||||
| .Fa "vsdflags" | |||||
| .Fc | |||||
| .Ft struct voistatspec | |||||
| .Fo "STATS_VSS_CRHIST<32|64>_USR" | |||||
| .Fa Sy "HBKTS" Ns Pq Sy "CRBKT" Ns ( Em "lb" ) , "..." Pc , | |||||
| .Fa "vsdflags" | |||||
| .Fc | |||||
| .Ft struct voistatspec | |||||
| .Fo "STATS_VSS_DRHIST<32|64>_USR" | |||||
| .Fa Sy "HBKTS" Ns Pq Sy "DRBKT" Ns ( Em "lb" , "ub" ) , "..." Pc , | |||||
| .Fa "vsdflags" | |||||
| .Fc | |||||
| .Ft struct voistatspec | |||||
| .Fo "STATS_VSS_DVHIST<32|64>_USR" | |||||
| .Fa Sy "HBKTS" Ns Pq Sy "DVBKT" Ns ( Em "val" ) , "..." Pc , | |||||
| .Fa "vsdflags" | |||||
| .Fc | |||||
| .Ft struct voistatspec | |||||
| .Fo STATS_VSS_TDGSTCLUST<32|64> | |||||
| .Fa "nctroids" | |||||
| .Fa "prec" | |||||
| .Fc | |||||
| .Ft int | |||||
| .Fo stats_tpl_add_voistats | |||||
| .Fa "uint32_t tpl_id" | |||||
| .Fa "int32_t voi_id" | |||||
| .Fa "const char *voi_name" | |||||
| .Fa "enum vsd_dtype voi_dtype" | |||||
| .Fa "uint32_t nvss" | |||||
| .Fa "struct voistatspec *vss" | |||||
| .Fa "uint32_t flags" | |||||
| .Fc | |||||
| .Ss Stats Blob Data Gathering Functions | |||||
| .Ft int | |||||
| .Fo stats_voi_update_<abs|rel>_<dtype> | |||||
| .Fa "struct statsblob *sb" | |||||
| .Fa "int32_t voi_id" | |||||
| .Fa "<dtype> voival" | |||||
| .Fc | |||||
| .Ss Stats Blob Utility Functions | |||||
| .Ft struct statsblob * | |||||
| .Fo stats_blob_alloc | |||||
| .Fa "uint32_t tpl_id" | |||||
| .Fa "uint32_t flags" | |||||
| .Fc | |||||
| .Ft int | |||||
| .Fo stats_blob_init | |||||
| .Fa "struct statsblob *sb" | |||||
| .Fa "uint32_t tpl_id" | |||||
| .Fa "uint32_t flags" | |||||
| .Fc | |||||
| .Ft int | |||||
| .Fo stats_blob_clone | |||||
| .Fa "struct statsblob **dst" | |||||
| .Fa "size_t dstmaxsz" | |||||
| .Fa "struct statsblob *src" | |||||
| .Fa "uint32_t flags" | |||||
| .Fc | |||||
| .Ft void | |||||
| .Fo stats_blob_destroy | |||||
| .Fa "struct statsblob *sb" | |||||
| .Fc | |||||
| .Ft int | |||||
| .Fo stats_voistat_fetch_dptr | |||||
| .Fa "struct statsblob *sb" | |||||
| .Fa "int32_t voi_id" | |||||
| .Fa "enum voi_stype stype" | |||||
| .Fa "enum vsd_dtype *retdtype" | |||||
| .Fa "struct voistatdata **retvsd" | |||||
| .Fa "size_t *retvsdsz" | |||||
| .Fc | |||||
| .Ft int | |||||
| .Fo stats_voistat_fetch_<dtype> | |||||
| .Fa "struct statsblob *sb" | |||||
| .Fa "int32_t voi_id" | |||||
| .Fa "enum voi_stype stype" | |||||
| .Fa "<dtype> *ret" | |||||
| .Fc | |||||
| .Ft int | |||||
| .Fo stats_blob_snapshot | |||||
| .Fa "struct statsblob **dst" | |||||
| .Fa "size_t dstmaxsz" | |||||
| .Fa "struct statsblob *src" | |||||
| .Fa "uint32_t flags" | |||||
| .Fc | |||||
| .Ft int | |||||
| .Fo stats_blob_tostr | |||||
| .Fa "struct statsblob *sb" | |||||
| .Fa "struct sbuf *buf" | |||||
| .Fa "enum sb_str_fmt fmt" | |||||
| .Fa "uint32_t flags" | |||||
| .Fc | |||||
| .Ft int | |||||
| .Fo stats_voistatdata_tostr | |||||
| .Fa "const struct voistatdata *vsd" | |||||
| .Fa "enum vsd_dtype dtype" | |||||
| .Fa "enum sb_str_fmt fmt" | |||||
| .Fa "struct sbuf *buf" | |||||
| .Fa "int objdump" | |||||
| .Fc | |||||
| .Ft typedef int | |||||
| .Fn "\*(lp*stats_blob_visitcb_t\*(rp" "struct sb_visit *sbv" "void *usrctx" | |||||
| .Ft int | |||||
| .Fo stats_blob_visit | |||||
| .Fa "struct statsblob *sb" | |||||
| .Fa "stats_blob_visitcb_t func" | |||||
| .Fa "void *usrctx" | |||||
| .Fc | |||||
| .Sh DESCRIPTION | |||||
| The | |||||
| .Nm | |||||
| framework facilitates real-time kernel and user space statistics gathering. | |||||
| The framework is built around the | |||||
| .Dq statsblob , | |||||
| an object embedded within a contiguous memory allocation that is mostly opaque | |||||
| to consumers and stores all required state. | |||||
| A | |||||
| .Dq statsblob | |||||
| object can itself be embedded within other objects either directly or indirectly | |||||
| using a pointer. | |||||
| .Pp | |||||
| Objects or subsystems for which statistics are to be gathered are initialized | |||||
| from a template | |||||
| .Dq statsblob , | |||||
| which acts as the blueprint for an arbitrary set of | |||||
sef: I think I'd like "Variables of Interest" to be capitalized there. | |||||
| Variables Of Interest (VOIs) and their associated statistics. | |||||
| Each template defines a schema plus associated metadata, which are kept separate | |||||
Done Inline Actionss/minimise/minimize/ In general, we use American English in FreeBSD's docs and man pages. I've seen some other instances like this in the file. Can you do a sweep over the man page to change these occurances? bcr: s/minimise/minimize/
In general, we use American English in FreeBSD's docs and man pages. I've… | |||||
Done Inline ActionsHm, igor doesn't seem to do that. I've fixed a bunch of /initialis.*/, though. trasz: Hm, igor doesn't seem to do that. I've fixed a bunch of /initialis.*/, though.
| |||||
| to minimize the memory footprint of blobs. | |||||
| .Pp | |||||
| Data gathering hook functions added at appropriate locations within the code | |||||
| base of interest feed VOI data into the framework for processing. | |||||
| .Pp | |||||
| Each | |||||
| .Dq statsblob , | |||||
| consists of a | |||||
| .Vt struct statsblob | |||||
| header and opaque internal blob structure per the following diagram: | |||||
| .Bd -literal -offset indent | |||||
| --------------------------------------------------------- | |||||
| | struct | uint8_t | | |||||
| | statsblob | opaque[] | | |||||
| --------------------------------------------------------- | |||||
| .Ed | |||||
| .Pp | |||||
Not Done Inline ActionsThat's an _at least_ 8 byte header, so why say that it is 8 bytes there? I'd recommend something along the lines of, "The publicly-visible header is at least 8 bytes, currently defined as:") sef: That's an _at least_ 8 byte header, so why say that it is 8 bytes there? I'd recommend… | |||||
Done Inline ActionsTo me this means the header is exactly 8 bytes; the variable length 'opaque' is not really part of the header - it follows the header. trasz: To me this means the header is exactly 8 bytes; the variable length 'opaque' is not really part… | |||||
| The publicly visible 8-byte header is defined as: | |||||
| .Bd -literal -offset indent | |||||
| struct statsblob { | |||||
| uint8_t abi; | |||||
| uint8_t endian; | |||||
| uint16_t flags; | |||||
| uint16_t maxsz; | |||||
| uint16_t cursz; | |||||
| uint8_t opaque[]; | |||||
| }; | |||||
| .Ed | |||||
| .Pp | |||||
| .Va abi | |||||
Done Inline ActionsI think that should be '.Va opaque' there. sef: I think that should be '.Va opaque' there. | |||||
| specifies which API version the blob's | |||||
| .Va opaque | |||||
| internals conform to | |||||
| .Pq Dv STATS_ABI_V1 is the only version currently defined . | |||||
| .Va endian | |||||
| specifies the endianness of the blob's fields | |||||
| .Po | |||||
| .Dv SB_LE | |||||
| for little endian, | |||||
| .Dv SB_BE | |||||
| for big endian, or | |||||
| .Dv SB_UE | |||||
| for unknown endianness | |||||
| .Pc . | |||||
| .Va cursz | |||||
| specifies the size of the blob, while | |||||
Not Done Inline ActionsThis confuses me a bit, although I haven't dug into the implementation yet, so perhaps it's clearer there. Specifically... if it's opaque, why do I need to know the underlying memory allocation size? I can understand needing to know the size of the individual statsblob object, but shouldn't any thing object-specific be _in_ the opaque part? And that would include any difference between object size and opaque size. sef: This confuses me a bit, although I haven't dug into the implementation yet, so perhaps it's… | |||||
Done Inline ActionsIt's because the API consumer can provide their own buffer to eg stats_blob_init(). trasz: It's because the API consumer can provide their own buffer to eg stats_blob_init(). | |||||
| .Va maxsz | |||||
| specifies the size of the underlying memory allocation in which the | |||||
| blob is embedded. | |||||
| Both | |||||
| .Va cursz | |||||
| and | |||||
| .Va maxsz | |||||
| default to units of bytes, unless a flag is set in | |||||
| .Va flags | |||||
| that dictates otherwise. | |||||
| .Pp | |||||
| Templates are constructed by associating arbitrary VOI IDs with a set of | |||||
| statistics, where each statistic is specified using a | |||||
| .Vt struct voistatspec | |||||
| per the definition below: | |||||
| .Bd -literal -offset indent | |||||
| struct voistatspec { | |||||
| vss_hlpr_fn hlpr; | |||||
| struct vss_hlpr_info *hlprinfo; | |||||
| struct voistatdata *iv; | |||||
| size_t vsdsz; | |||||
| uint32_t flags; | |||||
| enum vsd_dtype vs_dtype : 8; | |||||
| enum voi_stype stype : 8; | |||||
| }; | |||||
| .Ed | |||||
| .Pp | |||||
| It is generally expected that consumers will not work with | |||||
| .Vt struct voistatspec | |||||
| directly, and instead use the | |||||
| .Fn STATS_VSS_* | |||||
| helper macros. | |||||
| .Pp | |||||
| The | |||||
| .Nm | |||||
| framework offers the following statistics for association with VOIs: | |||||
| .Bl -tag -width ".Dv VS_STYPE_TDGST" | |||||
| .It Dv VS_STYPE_SUM | |||||
| The sum of VOI values. | |||||
| .It Dv VS_STYPE_MAX | |||||
| The maximum VOI value. | |||||
| .It Dv VS_STYPE_MIN | |||||
| The minimum VOI value. | |||||
| .It Dv VS_STYPE_HIST | |||||
| A static bucket histogram of VOI values, including a count of | |||||
| .Dq out-of-band/bucket Dc | |||||
| values which did not match any bucket. | |||||
| Histograms can be specified as | |||||
| .Dq Em C Ns ontinuous Em R Ns ange Dc | |||||
| .Pq CRHIST Pc , | |||||
| .Dq Em D Ns iscrete Em R Ns ange Dc | |||||
| .Pq DRHIST Pc | |||||
| or | |||||
| .Dq Em D Ns iscrete Em V Ns alue Dc | |||||
| .Pq DVHIST Pc , | |||||
| with 32 or 64 bit bucket counters, depending on the VOI semantics. | |||||
| .It Dv VS_STYPE_TDGST | |||||
| A dynamic bucket histogram of VOI values based on the t-digest method | |||||
| .Po refer to the t-digest paper in the | |||||
| .Sx SEE ALSO | |||||
| section below | |||||
| .Pc . | |||||
| .El | |||||
| .Pp | |||||
| A | |||||
| .Dq visitor software design pattern Ns | |||||
| -like scheme is employed to facilitate iterating over a blob's data without | |||||
| concern for the blob's structure. | |||||
| The data provided to visitor callback functions is encapsulated in | |||||
| .Vt struct sb_visit | |||||
| per the definition below: | |||||
| .Bd -literal -offset indent | |||||
| struct sb_visit { | |||||
| struct voistatdata *vs_data; | |||||
| uint32_t tplhash; | |||||
| uint32_t flags; | |||||
| int16_t voi_id; | |||||
| int16_t vs_dsz; | |||||
| enum vsd_dtype voi_dtype : 8; | |||||
| enum vsd_dtype vs_dtype : 8; | |||||
| int8_t vs_stype; | |||||
| uint16_t vs_errs; | |||||
| }; | |||||
| .Ed | |||||
| .Pp | |||||
| The | |||||
| .Fn stats_tpl_sample_rates | |||||
| and | |||||
| .Fn stats_tpl_sample_rollthedice | |||||
| functions utilize | |||||
| .Vt struct stats_tpl_sample_rate | |||||
| to encapsulate per-template sample rate information per the definition below: | |||||
| .Bd -literal -offset indent | |||||
| struct stats_tpl_sample_rate { | |||||
| int32_t tpl_slot_id; | |||||
| uint32_t tpl_sample_pct; | |||||
| }; | |||||
| .Ed | |||||
| .Pp | |||||
| The | |||||
| .Va tpl_slot_id | |||||
| member holds the template's slot ID obtained from | |||||
| .Fn stats_tpl_alloc | |||||
| or | |||||
| .Fn stats_tpl_fetch_allocid . | |||||
| The | |||||
| .Va tpl_sample_pct | |||||
| member holds the template's sample rate as an integer percentage in the range | |||||
| [0,100]. | |||||
| .Pp | |||||
| The | |||||
| .Vt stats_tpl_sr_cb_t | |||||
| conformant function pointer that is required as the | |||||
| .Fa arg1 | |||||
| of | |||||
| .Fn stats_tpl_sample_rates | |||||
| is defined as: | |||||
| .Bd -literal -offset indent | |||||
| enum stats_tpl_sr_cb_action { | |||||
| TPL_SR_UNLOCKED_GET, | |||||
| TPL_SR_RLOCKED_GET, | |||||
| TPL_SR_RUNLOCK, | |||||
| TPL_SR_PUT | |||||
| }; | |||||
| typedef int (*stats_tpl_sr_cb_t)(enum stats_tpl_sr_cb_action action, | |||||
| struct stats_tpl_sample_rate **rates, int *nrates, void *ctx); | |||||
| .Ed | |||||
| .Pp | |||||
| It is required that a conformant function: | |||||
| .Bl -dash | |||||
| .It | |||||
| Return an appropriate | |||||
| .Xr errno 2 | |||||
| on error, otherwise 0. | |||||
| .It | |||||
| When called with | |||||
| .Qq action == TPL_SR_*_GET , | |||||
| return the subsystem's rates list ptr and count, locked or unlocked as | |||||
| requested. | |||||
| .It | |||||
| When called with | |||||
| .Qq action == TPL_SR_RUNLOCK , | |||||
| unlock the subsystem's rates list ptr and count. | |||||
| Pair with a prior | |||||
| .Qq action == TPL_SR_RLOCKED_GET | |||||
| call. | |||||
| .It | |||||
| When called with | |||||
| .Qq action == TPL_SR_PUT , | |||||
| update the subsystem's rates list ptr and count to the sysctl processed values | |||||
| and return the inactive list details in | |||||
| .Fa rates | |||||
| and | |||||
| .Fa nrates | |||||
| for garbage collection by | |||||
| .Fn stats_tpl_sample_rates . | |||||
| .El | |||||
| .Pp | |||||
| Where templates need to be referenced via textual means, for example via a MIB | |||||
| variable, the following string based template spec formats can be used: | |||||
| .Bl -enum | |||||
| .It | |||||
| .Qq <tplname> Qc Ns | |||||
| :<tplhash> | |||||
| .Ns , for example | |||||
| .Qq TCP_DEFAULT Qc Ns | |||||
| :1731235399 | |||||
| .It | |||||
| .Qq <tplname> Qc | |||||
| .Ns , for example | |||||
| .Qq TCP_DEFAULT Qc | |||||
| .It | |||||
| :<tplhash> | |||||
| .Ns , for example | |||||
| :1731235399 | |||||
| .El | |||||
| .Pp | |||||
| The first form is the normative spec format generated by the framework, while | |||||
| the second and third forms are convenience formats primarily for user input. | |||||
| The use of inverted commas around the template name is optional. | |||||
| .Ss MIB Variables | |||||
| The in-kernel | |||||
| .Nm | |||||
| framework exposes the following framework-specific variables in the | |||||
| .Va kern.stats | |||||
| branch of the | |||||
| .Xr sysctl 3 | |||||
| MIB. | |||||
| .Bl -tag -width "templates" | |||||
| .It templates | |||||
| Read-only CSV list of registered templates in normative template spec form. | |||||
| .El | |||||
| .Ss Template Management Functions | |||||
| The | |||||
| .Fn stats_tpl_alloc | |||||
| function allocates a new template with the specified unique name and returns its | |||||
| runtime-stable template slot ID for use with other API functions. | |||||
| The | |||||
| .Fa flags | |||||
| argument is currently unused. | |||||
| .Pp | |||||
| The | |||||
| .Fn stats_tpl_fetch_allocid | |||||
| function returns the runtime-stable template slot ID of any registered template | |||||
| matching the specified name and hash. | |||||
| .Pp | |||||
| The | |||||
| .Fn stats_tpl_fetch | |||||
| function returns the pointer to the registered template object at the specified | |||||
| template slot ID. | |||||
| .Pp | |||||
| The | |||||
| .Fn stats_tpl_id2name | |||||
| function returns the name of the registered template object at the specified | |||||
| template slot ID. | |||||
| .Pp | |||||
| The | |||||
| .Fn stats_tpl_sample_rates | |||||
| function provides a generic handler for template sample rates management and | |||||
| reporting via | |||||
| .Xr sysctl 3 | |||||
| MIB variables. | |||||
| Subsystems can use this function to create a subsystem-specific | |||||
| .Xr SYSCTL_PROC 9 | |||||
| MIB variable that manages and reports subsystem-specific template sampling | |||||
| rates. | |||||
| Subsystems must supply a | |||||
| .Vt stats_tpl_sr_cb_t | |||||
| conformant function pointer as the sysctl's | |||||
| .Fa arg1 , | |||||
| which is a callback used to interact with the subsystem's stats template sample | |||||
| rates list. | |||||
| Subsystems can optionally specify the sysctl's | |||||
| .Fa arg2 | |||||
| as non-zero, which causes a zero-initialized allocation of arg2-sized contextual | |||||
| memory to be heap-allocated and passed in to all subsystem callbacks made during | |||||
| the operation of | |||||
| .Fn stats_tpl_sample_rates . | |||||
| .Pp | |||||
| The | |||||
| .Fn stats_tpl_sample_rollthedice | |||||
| function makes a weighted random template selection from the supplied array of | |||||
| template sampling rates. | |||||
| The cumulative percentage of all sampling rates should not exceed 100. | |||||
| If no seed is supplied, a PRNG is used to generate a true random number so that | |||||
| every selection is independent. | |||||
| If a seed is supplied, selection will be made randomly across different seeds, but | |||||
| deterministically given the same seed. | |||||
| .Pp | |||||
| The | |||||
| .Fn stats_tpl_add_voistats | |||||
| function is used to add a VOI and associated set of statistics to the registered | |||||
| template object at the specified template slot ID. | |||||
| The set of statistics is passed as an array of | |||||
| .Vt struct voistatspec | |||||
| which can be initialized using the | |||||
| .Fn STATS_VSS_* | |||||
| helper macros or manually for non-standard use cases. | |||||
| For static | |||||
| .Fa vss | |||||
| arrays, the | |||||
| .Fa nvss | |||||
| count of array elements can be determined by passing | |||||
| .Fa vss | |||||
| to the | |||||
| .Fn NVSS | |||||
| macro. | |||||
| The | |||||
| .Dv SB_VOI_RELUPDATE | |||||
| flag can be passed to configure the VOI for use with | |||||
| .Fn stats_voi_update_rel_<dtype> , | |||||
| which entails maintaining an extra 8 bytes of state in the blob at each update. | |||||
| .Ss Data Gathering Functions | |||||
| The | |||||
| .Fn stats_voi_update_abs_<dtype> | |||||
| and | |||||
| .Fn stats_voi_update_rel_<dtype> | |||||
| functions both update all the statistics associated with the VOI identified by | |||||
| .Fa voi_id . | |||||
| The | |||||
| .Dq abs | |||||
| call uses | |||||
| .Fa voival | |||||
| as an absolute value, whereas the | |||||
| .Dq rel | |||||
| call uses | |||||
| .Fa voival | |||||
| as a value relative to that of the previous update function call, by adding it | |||||
| to the previous value and using the result for the update. | |||||
| Relative updates are only possible for VOIs that were added to the template with | |||||
| the | |||||
| .Dv SB_VOI_RELUPDATE | |||||
| flag specified to | |||||
| .Fn stats_tpl_add_voistats . | |||||
| .Ss Utility Functions | |||||
| The | |||||
| .Fn stats_blob_alloc | |||||
| function allocates and initializes a new blob based on the registered template | |||||
| object at the specified template slot ID. | |||||
| .Pp | |||||
| The | |||||
| .Fn stats_blob_init | |||||
| function initializes a new blob in an existing memory allocation based on the | |||||
| registered template object at the specified template slot ID. | |||||
| .Pp | |||||
| The | |||||
| .Fn stats_blob_clone | |||||
| function duplicates the | |||||
| .Fa src | |||||
| blob into | |||||
| .Fa dst , | |||||
| leaving only the | |||||
| .Va maxsz | |||||
| field of | |||||
| .Fa dst | |||||
| untouched. | |||||
| The | |||||
| .Dv SB_CLONE_ALLOCDST | |||||
| flag can be passed to instruct the function to allocate a new blob of | |||||
| appropriate size into which to clone | |||||
| .Fa src , | |||||
| storing the new pointer in | |||||
| .Fa *dst . | |||||
| The | |||||
| .Dv SB_CLONE_USRDSTNOFAULT | |||||
| or | |||||
| .Dv SB_CLONE_USRDST | |||||
| flags can be set to respectively signal that | |||||
| .Xr copyout_nofault 9 | |||||
| or | |||||
| .Xr copyout 9 | |||||
| should be used because | |||||
| .Fa *dst | |||||
| is a user space address. | |||||
| .Pp | |||||
| The | |||||
| .Fn stats_blob_snapshot | |||||
| function calls | |||||
| .Fn stats_blob_clone | |||||
| to obtain a copy of | |||||
| .Fa src | |||||
| and then performs any additional functions required to produce a coherent | |||||
| blob snapshot. | |||||
| The flags interpreted by | |||||
| .Fn stats_blob_clone | |||||
| also apply to | |||||
| .Fn stats_blob_snapshot . | |||||
| Additionally, the | |||||
| .Dv SB_CLONE_RSTSRC | |||||
| flag can be used to effect a reset of the | |||||
| .Fa src | |||||
| blob's statistics after a snapshot is successfully taken. | |||||
| .Pp | |||||
| The | |||||
| .Fn stats_blob_destroy | |||||
| function destroys a blob previously created with | |||||
| .Fn stats_blob_alloc , | |||||
| .Fn stats_blob_clone | |||||
| or | |||||
| .Fn stats_blob_snapshot . | |||||
| .Pp | |||||
| The | |||||
| .Fn stats_blob_visit | |||||
| function allows the caller to iterate over the contents of a blob. | |||||
| The callback function | |||||
| .Fa func | |||||
| is called for every VOI and statistic in the blob, passing a | |||||
| .Vt struct sb_visit | |||||
| and the user context argument | |||||
| .Fa usrctx | |||||
| to the callback function. | |||||
| The | |||||
| .Fa sbv | |||||
| passed to the callback function may have one or more of the following flags set | |||||
| in the | |||||
| .Va flags | |||||
| struct member to provide useful metadata about the iteration: | |||||
| .Dv SB_IT_FIRST_CB , | |||||
| .Dv SB_IT_LAST_CB , | |||||
| .Dv SB_IT_FIRST_VOI , | |||||
| .Dv SB_IT_LAST_VOI , | |||||
| .Dv SB_IT_FIRST_VOISTAT , | |||||
| .Dv SB_IT_LAST_VOISTAT , | |||||
| .Dv SB_IT_NULLVOI | |||||
| and | |||||
| .Dv SB_IT_NULLVOISTAT . | |||||
| Returning a non-zero value from the callback function terminates the iteration. | |||||
| .Pp | |||||
| The | |||||
| .Fn stats_blob_tostr | |||||
| renders a string representation of a blob into the | |||||
| .Xr sbuf 9 | |||||
| .Fa buf . | |||||
| Currently supported render formats are | |||||
| .Dv SB_STRFMT_FREEFORM | |||||
| and | |||||
| .Dv SB_STRFMT_JSON . | |||||
| The | |||||
| .Dv SB_TOSTR_OBJDUMP | |||||
| flag can be passed to render version specific opaque implementation detail for | |||||
| debugging or string-to-binary blob reconstruction purposes. | |||||
| The | |||||
| .Dv SB_TOSTR_META | |||||
| flag can be passed to render template metadata into the string representation, | |||||
| using the blob's template hash to lookup the corresponding template. | |||||
| .Pp | |||||
| The | |||||
| .Fn stats_voistatdata_tostr | |||||
| renders a string representation of an individual statistic's data into the | |||||
| .Xr sbuf 9 | |||||
| .Fa buf . | |||||
| The same render formats supported by the | |||||
| .Fn stats_blob_tostr | |||||
| function can be specified, and the | |||||
| .Fa objdump | |||||
| boolean has the same meaning as the | |||||
| .Dv SB_TOSTR_OBJDUMP | |||||
| flag. | |||||
| .Pp | |||||
| The | |||||
| .Fn stats_voistat_fetch_dptr | |||||
| function returns an internal blob pointer to the specified | |||||
| .Fa stype | |||||
| statistic data for the VOI | |||||
| .Fa voi_id . | |||||
| The | |||||
| .Fn stats_voistat_fetch_<dtype> | |||||
| functions are convenience wrappers around | |||||
| .Fn stats_voistat_fetch_dptr | |||||
| to perform the extraction for simple data types. | |||||
| .Sh IMPLEMENTATION NOTES | |||||
| The following notes apply to STATS_ABI_V1 format statsblobs. | |||||
| .Ss Space-Time Complexity | |||||
| Blobs are laid out as three distinct memory regions following the header: | |||||
| .Bd -literal -offset indent | |||||
| ------------------------------------------------------ | |||||
| | struct | struct | struct | struct | | |||||
| | statsblobv1 | voi [] | voistat [] | voistatdata [] | | |||||
| ------------------------------------------------------ | |||||
| .Ed | |||||
| .Pp | |||||
Done Inline Actions"8b"? sef: "8b"? | |||||
Not Done Inline ActionsOops, should have been caps B for SI bytes suffix. Similarly true for the annotated memory layout further down. lstewart: Oops, should have been caps B for SI bytes suffix. Similarly true for the annotated memory… | |||||
| Blobs store VOI and statistic blob state | |||||
| .Po | |||||
| 8 bytes for | |||||
| .Vt struct voi | |||||
| and 8 bytes for | |||||
| .Vt struct voistat | |||||
| respectively | |||||
| .Pc | |||||
| in sparse arrays, using the | |||||
| .Fa voi_id | |||||
| and | |||||
| .Vt enum voi_stype | |||||
| as array indices. | |||||
| This allows O(1) access to any voi/voistat pair in the blob, at the expense of | |||||
| 8 bytes of wasted memory per vacant slot for templates which do not specify | |||||
| contiguously numbered VOIs and/or statistic types. | |||||
| Data storage for statistics is only allocated for non-vacant slot pairs. | |||||
| .Pp | |||||
| To provide a concrete example, a blob with the following specification: | |||||
| .Bl -dash | |||||
| .It | |||||
| Two VOIs; ID 0 and 2; added to the template in that order | |||||
| .It | |||||
| VOI 0 is of data type | |||||
| .Vt int64_t , | |||||
| is configured with | |||||
| .Dv SB_VOI_RELUPDATE | |||||
| to enable support for relative updates using | |||||
| .Fn stats_voi_update_rel_<dtype> , | |||||
| and has a | |||||
| .Dv VS_STYPE_MIN | |||||
| statistic associated with it. | |||||
| .It | |||||
| VOI 2 is of data type | |||||
| .Vt uint32_t | |||||
| with | |||||
| .Dv VS_STYPE_SUM | |||||
| and | |||||
| .Dv VS_STYPE_MAX | |||||
| statistics associated with it. | |||||
| .El | |||||
| .Pp | |||||
| would have the following memory layout: | |||||
| .Bd -literal | |||||
| -------------------------------------- | |||||
| | header | struct statsblobv1, 32 bytes | |||||
| |------------------------------------| | |||||
Done Inline ActionsI think the same '8b' vs '8B' or '8 bytes' change may be needed here. allanjude: I think the same '8b' vs '8B' or '8 bytes' change may be needed here. | |||||
| | voi[0] | struct voi, 8 bytes | |||||
| | voi[1] (vacant) | struct voi, 8 bytes | |||||
| | voi[2] | struct voi, 8 bytes | |||||
| |------------------------------------| | |||||
| | voi[2]voistat[VOISTATE] (vacant) | struct voistat, 8 bytes | |||||
| | voi[2]voistat[SUM] | struct voistat, 8 bytes | |||||
| | voi[2]voistat[MAX] | struct voistat, 8 bytes | |||||
| | voi[0]voistat[VOISTATE] | struct voistat, 8 bytes | |||||
| | voi[0]voistat[SUM] (vacant) | struct voistat, 8 bytes | |||||
| | voi[0]voistat[MAX] (vacant) | struct voistat, 8 bytes | |||||
| | voi[0]voistat[MIN] | struct voistat, 8 bytes | |||||
| |------------------------------------| | |||||
| | voi[2]voistat[SUM]voistatdata | struct voistatdata_int32, 4 bytes | |||||
| | voi[2]voistat[MAX]voistatdata | struct voistatdata_int32, 4 bytes | |||||
| | voi[0]voistat[VOISTATE]voistatdata | struct voistatdata_numeric, 8 bytes | |||||
| | voi[0]voistat[MIN]voistatdata | struct voistatdata_int64, 8 bytes | |||||
| -------------------------------------- | |||||
| TOTAL 136 bytes | |||||
| .Ed | |||||
| .Pp | |||||
| When rendered to string format using | |||||
| .Fn stats_blob_tostr , | |||||
| the | |||||
| .Dv SB_STRFMT_FREEFORM | |||||
| .Fa fmt | |||||
| and the | |||||
| .Dv SB_TOSTR_OBJDUMP | |||||
| flag, the rendered output is: | |||||
| .Bd -literal | |||||
| struct statsblobv1@0x8016250a0, abi=1, endian=1, maxsz=136, cursz=136, \\ | |||||
| created=6294158585626144, lastrst=6294158585626144, flags=0x0000, \\ | |||||
| stats_off=56, statsdata_off=112, tplhash=2994056564 | |||||
| vois[0]: id=0, name="", flags=0x0001, dtype=INT_S64, voistatmaxid=3, \\ | |||||
| stats_off=80 | |||||
| vois[0]stat[0]: stype=VOISTATE, flags=0x0000, dtype=VOISTATE, \\ | |||||
| dsz=8, data_off=120 | |||||
| voistatdata: prev=0 | |||||
| vois[0]stat[1]: stype=-1 | |||||
| vois[0]stat[2]: stype=-1 | |||||
| vois[0]stat[3]: stype=MIN, flags=0x0000, dtype=INT_S64, \\ | |||||
| dsz=8, data_off=128 | |||||
| voistatdata: 9223372036854775807 | |||||
| vois[1]: id=-1 | |||||
| vois[2]: id=2, name="", flags=0x0000, dtype=INT_U32, voistatmaxid=2, \\ | |||||
| stats_off=56 | |||||
| vois[2]stat[0]: stype=-1 | |||||
| vois[2]stat[1]: stype=SUM, flags=0x0000, dtype=INT_U32, dsz=4, \\ | |||||
| data_off=112 | |||||
| voistatdata: 0 | |||||
| vois[2]stat[2]: stype=MAX, flags=0x0000, dtype=INT_U32, dsz=4, \\ | |||||
| data_off=116 | |||||
| voistatdata: 0 | |||||
| .Ed | |||||
| .Pp | |||||
| Note: The | |||||
| .Qq \e | |||||
| present in the rendered output above indicates a manual line break inserted to | |||||
| keep the man page within 80 columns and is not part of the actual output. | |||||
| .Ss Locking | |||||
| The | |||||
| .Nm | |||||
| framework does not provide any concurrency protection at the individual blob | |||||
| level, instead requiring that consumers guarantee mutual exclusion when calling | |||||
| API functions that reference a non-template blob. | |||||
| .Pp | |||||
| The list of templates is protected with a | |||||
| .Xr rwlock 9 | |||||
| in-kernel, and | |||||
| .Xr pthread 3 | |||||
| rw lock in user space to support concurrency between template management and | |||||
| blob initialization operations. | |||||
| .Sh RETURN VALUES | |||||
| .Fn stats_tpl_alloc | |||||
| returns a runtime-stable template slot ID on success, or a negative errno on | |||||
| failure. | |||||
| -EINVAL is returned if any problems are detected with the arguments. | |||||
| -EEXIST is returned if an existing template is registered with the same name. | |||||
| -ENOMEM is returned if a required memory allocation fails. | |||||
| .Pp | |||||
| .Fn stats_tpl_fetch_allocid | |||||
| returns a runtime-stable template slot ID, or negative errno on failure. | |||||
| -ESRCH is returned if no registered template matches the specified name and/or | |||||
| hash. | |||||
| .Pp | |||||
| .Fn stats_tpl_fetch | |||||
| returns 0 on success, or ENOENT if an invalid | |||||
| .Fa tpl_id | |||||
| is specified. | |||||
| .Pp | |||||
| .Fn stats_tpl_id2name | |||||
| returns 0 on success, or an errno on failure. | |||||
| EOVERFLOW is returned if the length of | |||||
| .Fa buf | |||||
| specified by | |||||
| .Fa len | |||||
| is too short to hold the template's name. | |||||
| ENOENT is returned if an invalid | |||||
| .Fa tpl_id | |||||
| is specified. | |||||
| .Pp | |||||
| .Fn stats_tpl_sample_rollthedice | |||||
| returns a valid template slot id selected from | |||||
| .Fa rates | |||||
| or -1 if a NULL selection was made, that is no stats collection this roll. | |||||
| .Pp | |||||
| .Fn stats_tpl_add_voistats | |||||
| return 0 on success, or an errno on failure. | |||||
| EINVAL is returned if any problems are detected with the arguments. | |||||
| EFBIG is returned if the resulting blob would have exceeded the maximum size. | |||||
| EOPNOTSUPP is returned if an attempt is made to add more VOI stats to a | |||||
| previously configured VOI. | |||||
| ENOMEM is returned if a required memory allocation fails. | |||||
| .Pp | |||||
| .Fn stats_voi_update_abs_<dtype> | |||||
| and | |||||
| .Fn stats_voi_update_rel_<dtype> | |||||
| return 0 on success, or EINVAL if any problems are detected with the arguments. | |||||
| .Pp | |||||
| .Fn stats_blob_init | |||||
| returns 0 on success, or an errno on failure. | |||||
| EINVAL is returned if any problems are detected with the arguments. | |||||
| EOVERFLOW is returned if the template blob's | |||||
| .Fa cursz | |||||
| is larger than the | |||||
| .Fa maxsz | |||||
| of the blob being initialized. | |||||
| .Pp | |||||
| .Fn stats_blob_alloc | |||||
| returns a pointer to a newly allocated and initialized blob based on the | |||||
| specified template with slot ID | |||||
| .Fa tpl_id , | |||||
| or NULL if the memory allocation failed. | |||||
| .Pp | |||||
| .Fn stats_blob_clone | |||||
| and | |||||
| .Fn stats_blob_snapshot | |||||
| return 0 on success, or an errno on failure. | |||||
| EINVAL is returned if any problems are detected with the arguments. | |||||
| ENOMEM is returned if the SB_CLONE_ALLOCDST flag was specified and the memory | |||||
| allocation for | |||||
| .Fa dst | |||||
| fails. | |||||
| EOVERFLOW is returned if the src blob's | |||||
| .Fa cursz | |||||
| is larger than the | |||||
| .Fa maxsz | |||||
| of the | |||||
| .Fa dst | |||||
| blob. | |||||
| .Pp | |||||
| .Fn stats_blob_visit | |||||
| returns 0 on success, or EINVAL if any problems are detected with the arguments. | |||||
| .Pp | |||||
| .Fn stats_blob_tostr | |||||
| and | |||||
| .Fn stats_voistatdata_tostr | |||||
| return 0 on success, or an errno on failure. | |||||
| EINVAL is returned if any problems are detected with the arguments, otherwise | |||||
| any error returned by | |||||
| .Fn sbuf_error | |||||
| for | |||||
| .Fa buf | |||||
| is returned. | |||||
| .Pp | |||||
| .Fn stats_voistat_fetch_dptr | |||||
| returns 0 on success, or EINVAL if any problems are detected with the arguments. | |||||
| .Pp | |||||
| .Fn stats_voistat_fetch_<dtype> | |||||
| returns 0 on success, or an errno on failure. | |||||
| EINVAL is returned if any problems are detected with the arguments. | |||||
| EFTYPE is returned if the requested data type does not match the blob's data | |||||
| type for the specified | |||||
| .Fa voi_id | |||||
| and | |||||
| .Fa stype . | |||||
| .Sh SEE ALSO | |||||
| .Xr errno 2 , | |||||
| .Xr arb 3 , | |||||
| .Xr qmath 3 , | |||||
| .Xr tcp 4 , | |||||
| .Xr sbuf 9 | |||||
| .Rs | |||||
| .%A "Ted Dunning" | |||||
| .%A "Otmar Ertl" | |||||
| .%T "Computing Extremely Accurate Quantiles Using t-digests" | |||||
| .%U "https://github.com/tdunning/t-digest/raw/master/docs/t-digest-paper/histo.pdf" | |||||
| .Re | |||||
| .Sh HISTORY | |||||
| The | |||||
| .Nm | |||||
| framework first appeared in | |||||
| .Fx 13.0 . | |||||
| .Sh AUTHORS | |||||
| .An -nosplit | |||||
| The | |||||
| .Nm | |||||
| framework and this manual page were written by | |||||
| .An Lawrence Stewart Aq lstewart@FreeBSD.org | |||||
| and sponsored by Netflix, Inc. | |||||
I think I'd like "Variables of Interest" to be capitalized there.