blob: 04b2c9db5fbc705bad18f008514229f9214d3106 [file] [log] [blame]
Alistair Veitch9686dab2015-05-26 14:26:47 -07001/*
2 *
Alistair Veitch0f690722016-01-13 09:08:38 -08003 * Copyright 2015-2016, Google Inc.
Alistair Veitch9686dab2015-05-26 14:26:47 -07004 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following disclaimer
14 * in the documentation and/or other materials provided with the
15 * distribution.
16 * * Neither the name of Google Inc. nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33
34/* RPC-internal Census API's. These are designed to be generic enough that
35 * they can (ultimately) be used in many different RPC systems (with differing
36 * implementations). */
37
38#ifndef CENSUS_CENSUS_H
39#define CENSUS_CENSUS_H
40
41#include <grpc/grpc.h>
Alistair Veitch9686dab2015-05-26 14:26:47 -070042
Nicolas "Pixel" Noble1ed15e22015-06-09 02:24:35 +020043#ifdef __cplusplus
44extern "C" {
45#endif
46
Alistair Veitch925e4a62015-07-26 16:51:23 -070047/* Identify census features that can be enabled via census_initialize(). */
48enum census_features {
49 CENSUS_FEATURE_NONE = 0, /* Do not enable census. */
50 CENSUS_FEATURE_TRACING = 1, /* Enable census tracing. */
51 CENSUS_FEATURE_STATS = 2, /* Enable Census stats collection. */
52 CENSUS_FEATURE_CPU = 4, /* Enable Census CPU usage collection. */
53 CENSUS_FEATURE_ALL =
54 CENSUS_FEATURE_TRACING | CENSUS_FEATURE_STATS | CENSUS_FEATURE_CPU
Alistair Veitch9686dab2015-05-26 14:26:47 -070055};
56
Alistair Veitcha4c4d3c2015-07-28 14:36:22 -070057/** Shutdown and startup census subsystem. The 'features' argument should be
Alistair Veitch925e4a62015-07-26 16:51:23 -070058 * the OR (|) of census_features values. If census fails to initialize, then
Alistair Veitch26967622015-06-01 10:45:54 -070059 * census_initialize() will return a non-zero value. It is an error to call
60 * census_initialize() more than once (without an intervening
61 * census_shutdown()). */
Alistair Veitch925e4a62015-07-26 16:51:23 -070062int census_initialize(int features);
63void census_shutdown(void);
Alistair Veitch9686dab2015-05-26 14:26:47 -070064
Alistair Veitch925e4a62015-07-26 16:51:23 -070065/** Return the features supported by the current census implementation (not all
66 * features will be available on all platforms). */
67int census_supported(void);
68
69/** Return the census features currently enabled. */
70int census_enabled(void);
Alistair Veitchfc62ddd2015-06-29 02:52:46 -070071
Alistair Veitche6d0ad32015-08-13 09:59:48 -070072/**
73 Context is a handle used by census to represent the current tracing and
74 tagging information. Contexts should be propagated across RPC's. Contexts
75 are created by any of the census_start_*_op() functions. A context is
76 typically used as argument to most census functions. Conceptually, contexts
77 should be thought of as specific to single RPC/thread. The context can be
78 serialized for passing across the wire, via census_context_serialize().
79*/
Alistair Veitch9686dab2015-05-26 14:26:47 -070080typedef struct census_context census_context;
81
82/* This function is called by the RPC subsystem whenever it needs to get a
83 * serialized form of the current census context (presumably to pass across
84 * the wire). Arguments:
85 * 'buffer': pointer to memory into which serialized context will be placed
86 * 'buf_size': size of 'buffer'
87 *
88 * Returns: the number of bytes used in buffer if successful, or 0 if the
89 * buffer is of insufficient size.
90 *
91 * TODO(aveitch): determine how best to communicate required/max buffer size
92 * so caller doesn't have to guess. */
93size_t census_context_serialize(const census_context *context, char *buffer,
94 size_t buf_size);
95
Alistair Veitchaf5002f2015-07-26 15:11:50 -070096/* Distributed traces can have a number of options. */
97enum census_trace_mask_values {
Alistair Veitch0383d492015-07-26 15:29:00 -070098 CENSUS_TRACE_MASK_NONE = 0, /* Default, empty flags */
99 CENSUS_TRACE_MASK_IS_SAMPLED = 1 /* RPC tracing enabled for this context. */
Alistair Veitchaf5002f2015-07-26 15:11:50 -0700100};
Alistair Veitch9686dab2015-05-26 14:26:47 -0700101
Alistair Veitchaf5002f2015-07-26 15:11:50 -0700102/** Get the current trace mask associated with this context. The value returned
103 will be the logical or of census_trace_mask_values values. */
104int census_trace_mask(const census_context *context);
Alistair Veitch491a9d42015-07-21 10:08:37 -0700105
Alistair Veitche6d0ad32015-08-13 09:59:48 -0700106/** Set the trace mask associated with a context. */
107void census_set_trace_mask(int trace_mask);
108
109/* The concept of "operation" is a fundamental concept for Census. In an RPC
110 system, and operation typcially represents a single RPC, or a significant
111 sub-part thereof (e.g. a single logical "read" RPC to a distributed storage
112 system might do several other actions in parallel, from looking up metadata
Alistair Veitchaf5002f2015-07-26 15:11:50 -0700113 indices to making requests of other services - each of these could be a
Alistair Veitche6d0ad32015-08-13 09:59:48 -0700114 sub-operation with the larger RPC operation). Census uses operations for the
Alistair Veitchaf5002f2015-07-26 15:11:50 -0700115 following:
Alistair Veitch491a9d42015-07-21 10:08:37 -0700116
Alistair Veitchaf5002f2015-07-26 15:11:50 -0700117 CPU accounting: If enabled, census will measure the thread CPU time
118 consumed between operation start and end times.
119
120 Active operations: Census will maintain information on all currently
121 active operations.
122
123 Distributed tracing: Each operation serves as a logical trace span.
124
Alistair Veitche6d0ad32015-08-13 09:59:48 -0700125 Stats collection: Stats are broken down by operation (e.g. latency
126 breakdown for each unique RPC path).
Alistair Veitchaf5002f2015-07-26 15:11:50 -0700127
128 The following functions serve to delineate the start and stop points for
129 each logical operation. */
Alistair Veitche6d0ad32015-08-13 09:59:48 -0700130
Alistair Veitchaf5002f2015-07-26 15:11:50 -0700131/**
Alistair Veitchf8869852015-08-25 15:24:49 -0700132 This structure represents a timestamp as used by census to record the time
133 at which an operation begins.
Alistair Veitche6d0ad32015-08-13 09:59:48 -0700134*/
Alistair Veitchf8869852015-08-25 15:24:49 -0700135typedef struct {
136 /* Use gpr_timespec for default implementation. High performance
137 * implementations should use a cycle-counter based timestamp. */
138 gpr_timespec ts;
139} census_timestamp;
Alistair Veitche6d0ad32015-08-13 09:59:48 -0700140
141/**
142 Mark the beginning of an RPC operation. The information required to call the
143 functions to record the start of RPC operations (both client and server) may
144 not be callable at the true start time of the operation, due to information
145 not being available (e.g. the census context data will not be available in a
146 server RPC until at least initial metadata has been processed). To ensure
147 correct CPU accounting and latency recording, RPC systems can call this
148 function to get the timestamp of operation beginning. This can later be used
149 as an argument to census_start_{client,server}_rpc_op(). NB: for correct
150 CPU accounting, the system must guarantee that the same thread is used
151 for all request processing after this function is called.
152
153 @return A timestamp representing the operation start time.
154*/
Alistair Veitchf8869852015-08-25 15:24:49 -0700155census_timestamp census_start_rpc_op_timestamp(void);
Alistair Veitche6d0ad32015-08-13 09:59:48 -0700156
157/**
158 Represent functions to map RPC name ID to service/method names. Census
159 breaks down all RPC stats by service and method names. We leave the
160 definition and format of these to the RPC system. For efficiency purposes,
161 we encode these as a single 64 bit identifier, and allow the RPC system to
162 provide a structure for functions that can convert these to service and
163 method strings.
164
165 TODO(aveitch): Instead of providing this as an argument to the rpc_start_op()
166 functions, maybe it should be set once at census initialization.
167*/
168typedef struct {
Craig Tiller7536af02015-12-22 13:49:30 -0800169 const char *(*get_rpc_service_name)(int64_t id);
170 const char *(*get_rpc_method_name)(int64_t id);
Alistair Veitche6d0ad32015-08-13 09:59:48 -0700171} census_rpc_name_info;
172
173/**
174 Start a client rpc operation. This function should be called as early in the
175 client RPC path as possible. This function will create a new context. If
Alistair Veitchaf5002f2015-07-26 15:11:50 -0700176 the context argument is non-null, then the new context will inherit all
177 its properties, with the following changes:
178 - create a new operation ID for the new context, marking it as a child of
179 the previous operation.
Alistair Veitche6d0ad32015-08-13 09:59:48 -0700180 - use the new RPC path and peer information for tracing and stats
Alistair Veitchaf5002f2015-07-26 15:11:50 -0700181 collection purposes, rather than those from the original context
Alistair Veitchaf5002f2015-07-26 15:11:50 -0700182
Alistair Veitche6d0ad32015-08-13 09:59:48 -0700183 If the context argument is NULL, then a new root context is created. This
Alistair Veitchaf5002f2015-07-26 15:11:50 -0700184 is particularly important for tracing purposes (the trace spans generated
185 will be unassociated with any other trace spans, except those
Alistair Veitche6d0ad32015-08-13 09:59:48 -0700186 downstream). The trace_mask will be used for tracing operations associated
187 with the new context.
Alistair Veitchaf5002f2015-07-26 15:11:50 -0700188
Alistair Veitche6d0ad32015-08-13 09:59:48 -0700189 In some RPC systems (e.g. where load balancing is used), peer information
190 may not be available at the time the operation starts. In this case, use a
191 NULL value for peer, and set it later using the
192 census_set_rpc_client_peer() function.
193
194 @param context The parent context. Can be NULL.
195 @param rpc_name_id The rpc name identifier to be associated with this RPC.
196 @param rpc_name_info Used to decode rpc_name_id.
197 @param peer RPC peer. If not available at the time, NULL can be used,
198 and a later census_set_rpc_client_peer() call made.
199 @param trace_mask An OR of census_trace_mask_values values. Only used in
200 the creation of a new root context (context == NULL).
201 @param start_time A timestamp returned from census_start_rpc_op_timestamp().
202 Can be NULL. Used to set the true time the operation
203 begins.
Alistair Veitchaf5002f2015-07-26 15:11:50 -0700204
205 @return A new census context.
206 */
Alistair Veitche6d0ad32015-08-13 09:59:48 -0700207census_context *census_start_client_rpc_op(
Craig Tiller7536af02015-12-22 13:49:30 -0800208 const census_context *context, int64_t rpc_name_id,
Alistair Veitche6d0ad32015-08-13 09:59:48 -0700209 const census_rpc_name_info *rpc_name_info, const char *peer, int trace_mask,
210 const census_timestamp *start_time);
Alistair Veitchaf5002f2015-07-26 15:11:50 -0700211
212/**
Alistair Veitche6d0ad32015-08-13 09:59:48 -0700213 Add peer information to a context representing a client RPC operation.
214*/
215void census_set_rpc_client_peer(census_context *context, const char *peer);
Alistair Veitchaf5002f2015-07-26 15:11:50 -0700216
Alistair Veitche6d0ad32015-08-13 09:59:48 -0700217/**
218 Start a server RPC operation. Returns a new context to be used in future
219 census calls. If buffer is non-NULL, then the buffer contents should
220 represent the client context, as generated by census_context_serialize().
221 If buffer is NULL, a new root context is created.
222
223 @param buffer Buffer containing bytes output from census_context_serialize().
224 @param rpc_name_id The rpc name identifier to be associated with this RPC.
225 @param rpc_name_info Used to decode rpc_name_id.
226 @param peer RPC peer.
227 @param trace_mask An OR of census_trace_mask_values values. Only used in
228 the creation of a new root context (buffer == NULL).
229 @param start_time A timestamp returned from census_start_rpc_op_timestamp().
230 Can be NULL. Used to set the true time the operation
231 begins.
232
233 @return A new census context.
Alistair Veitchaf5002f2015-07-26 15:11:50 -0700234 */
Alistair Veitche6d0ad32015-08-13 09:59:48 -0700235census_context *census_start_server_rpc_op(
Craig Tiller7536af02015-12-22 13:49:30 -0800236 const char *buffer, int64_t rpc_name_id,
Alistair Veitche6d0ad32015-08-13 09:59:48 -0700237 const census_rpc_name_info *rpc_name_info, const char *peer, int trace_mask,
238 census_timestamp *start_time);
Alistair Veitchaf5002f2015-07-26 15:11:50 -0700239
240/**
Alistair Veitche6d0ad32015-08-13 09:59:48 -0700241 Start a new, non-RPC operation. In general, this function works very
242 similarly to census_start_client_rpc_op, with the primary difference being
243 the replacement of host/path information with the more generic family/name
244 tags. If the context argument is non-null, then the new context will
245 inherit all its properties, with the following changes:
Alistair Veitchaf5002f2015-07-26 15:11:50 -0700246 - create a new operation ID for the new context, marking it as a child of
247 the previous operation.
248 - use the family and name information for tracing and stats collection
249 purposes, rather than those from the original context
Alistair Veitchaf5002f2015-07-26 15:11:50 -0700250
Alistair Veitche6d0ad32015-08-13 09:59:48 -0700251 If the context argument is NULL, then a new root context is created. This
Alistair Veitchaf5002f2015-07-26 15:11:50 -0700252 is particularly important for tracing purposes (the trace spans generated
253 will be unassociated with any other trace spans, except those
Alistair Veitche6d0ad32015-08-13 09:59:48 -0700254 downstream). The trace_mask will be used for tracing
Alistair Veitchaf5002f2015-07-26 15:11:50 -0700255 operations associated with the new context.
256
257 @param context The base context. Can be NULL.
258 @param family Family name to associate with the trace
259 @param name Name within family to associated with traces/stats
Alistair Veitche6d0ad32015-08-13 09:59:48 -0700260 @param trace_mask An OR of census_trace_mask_values values. Only used if
261 context is NULL.
Alistair Veitchaf5002f2015-07-26 15:11:50 -0700262
263 @return A new census context.
264 */
265census_context *census_start_op(census_context *context, const char *family,
Alistair Veitche6d0ad32015-08-13 09:59:48 -0700266 const char *name, int trace_mask);
Alistair Veitchaf5002f2015-07-26 15:11:50 -0700267
Alistair Veitch0879df22015-08-13 14:32:05 -0700268/**
269 End an operation started by any of the census_start_*_op*() calls. The
270 context used in this call will no longer be valid once this function
271 completes.
272
273 @param context Context associated with operation which is ending.
274 @param status status associated with the operation. Not interpreted by
275 census.
276*/
Alistair Veitche6d0ad32015-08-13 09:59:48 -0700277void census_end_op(census_context *context, int status);
Alistair Veitchaf5002f2015-07-26 15:11:50 -0700278
Craig Tiller7536af02015-12-22 13:49:30 -0800279#define CENSUS_TRACE_RECORD_START_OP ((uint32_t)0)
280#define CENSUS_TRACE_RECORD_END_OP ((uint32_t)1)
Alistair Veitch6afe53f2015-08-28 14:05:15 -0700281
Alistair Veitchaf5002f2015-07-26 15:11:50 -0700282/** Insert a trace record into the trace stream. The record consists of an
Alistair Veitch6afe53f2015-08-28 14:05:15 -0700283 arbitrary size buffer, the size of which is provided in 'n'.
284 @param context Trace context
285 @param type User-defined type to associate with trace entry.
286 @param buffer Pointer to buffer to use
287 @param n Number of bytes in buffer
288*/
Craig Tiller7536af02015-12-22 13:49:30 -0800289void census_trace_print(census_context *context, uint32_t type,
Alistair Veitch6afe53f2015-08-28 14:05:15 -0700290 const char *buffer, size_t n);
291
292/** Trace record. */
293typedef struct {
294 census_timestamp timestamp; /* Time of record creation */
Craig Tiller7536af02015-12-22 13:49:30 -0800295 uint64_t trace_id; /* Trace ID associated with record */
296 uint64_t op_id; /* Operation ID associated with record */
297 uint32_t type; /* Type (as used in census_trace_print() */
Alistair Veitch6afe53f2015-08-28 14:05:15 -0700298 const char *buffer; /* Buffer (from census_trace_print() */
299 size_t buf_size; /* Number of bytes inside buffer */
300} census_trace_record;
301
302/** Start a scan of existing trace records. While a scan is ongoing, addition
303 of new trace records will be blocked if the underlying trace buffers
304 fill up, so trace processing systems should endeavor to complete
305 reading as soon as possible.
306 @param consume if non-zero, indicates that reading records also "consumes"
307 the previously read record - i.e. releases space in the trace log
308 while scanning is ongoing.
309 @returns 0 on success, non-zero on failure (e.g. if a scan is already ongoing)
310*/
311int census_trace_scan_start(int consume);
312
313/** Get a trace record. The data pointed to by the trace buffer is guaranteed
314 stable until the next census_get_trace_record() call (if the consume
315 argument to census_trace_scan_start was non-zero) or census_trace_scan_end()
316 is called (otherwise).
317 @param trace_record structure that will be filled in with oldest trace record.
318 @returns -1 if an error occurred (e.g. no previous call to
319 census_trace_scan_start()), 0 if there is no more trace data (and
320 trace_record will not be modified) or 1 otherwise.
321*/
322int census_get_trace_record(census_trace_record *trace_record);
323
324/** End a scan previously started by census_trace_scan_start() */
325void census_trace_scan_end();
Alistair Veitch9686dab2015-05-26 14:26:47 -0700326
Alistair Veitchf68bf382015-07-28 14:27:28 -0700327/* A Census tag set is a collection of key:value string pairs; these form the
328 basis against which Census metrics will be recorded. Keys are unique within
329 a tag set. All contexts have an associated tag set. */
330typedef struct census_tag_set census_tag_set;
331
Alistair Veitchbb30d252016-01-12 17:36:05 -0800332/* A tag is a key:value pair. The key is a printable, nil-terminate
333 string. The value is a binary string, that may be printable. There are no
334 limits on the sizes of either keys or values, but code authors should
335 remember that systems may have inbuilt limits (e.g. for propagated tags,
336 the bytes on the wire) and that larger tags means more memory consumed and
337 time in processing. */
338typedef struct {
339 const char *key;
340 const char *value;
341 size_t value_len;
Alistair Veitch0f690722016-01-13 09:08:38 -0800342 uint8_t flags;
Alistair Veitchbb30d252016-01-12 17:36:05 -0800343} census_tag;
Alistair Veitchf68bf382015-07-28 14:27:28 -0700344
Alistair Veitchbb30d252016-01-12 17:36:05 -0800345/* Tag flags. */
346#define CENSUS_TAG_PROPAGATE 1 /* Tag should be propagated over RPC */
347#define CENSUS_TAG_STATS 2 /* Tag will be used for statistics aggregation */
348#define CENSUS_TAG_BINARY 4 /* Tag value is not printable */
349#define CENSUS_TAG_RESERVED 8 /* Reserved for internal use. */
350/* Flag values 8,16,32,64,128 are reserved for future/internal use. Clients
351 should not use or rely on their values. */
Alistair Veitchf68bf382015-07-28 14:27:28 -0700352
Alistair Veitchbb30d252016-01-12 17:36:05 -0800353#define CENSUS_TAG_IS_PROPAGATED(flags) (flags & CENSUS_TAG_PROPAGATE)
354#define CENSUS_TAG_IS_STATS(flags) (flags & CENSUS_TAG_STATS)
355#define CENSUS_TAG_IS_BINARY(flags) (flags & CENSUS_TAG_BINARY)
356
Alistair Veitchfc999ad2016-01-14 17:05:46 -0800357/* Maximum length of key/value in a tag. */
358#define CENSUS_MAX_TAG_KV_LEN 255
359/* Maximum number of propagatable tags. */
360#define CENSUS_MAX_PROPAGATED_TAGS 255
361
362typedef struct {
363 int n_propagated_tags; /* number of propagated printable tags */
364 int n_propagated_binary_tags; /* number of propagated binary tags */
365 int n_local_tags; /* number of non-propagated (local) tags */
366 int n_deleted_tags; /* number of tags that were deleted */
367 int n_added_tags; /* number of tags that were added */
368 int n_modified_tags; /* number of tags that were modified */
369 int n_invalid_tags; /* number of tags with bad keys or values (e.g.
370 longer than CENSUS_MAX_TAG_KV_LEN) */
Alistair Veitcha88a2212016-01-15 12:13:36 -0800371 int n_ignored_tags; /* number of tags ignored because of
372 CENSUS_MAX_PROPAGATED_TAGS limit. */
373} census_tag_set_create_status;
Alistair Veitchbb30d252016-01-12 17:36:05 -0800374
375/* Create a new tag set, adding and removing tags from an existing tag set.
376 @param base Base tag set to build upon. Can be NULL.
377 @param tags A set of tags to be added/changed/deleted. Tags with keys that
378 are in 'tags', but not 'base', are added to the tag set. Keys that are in
Alistair Veitcha88a2212016-01-15 12:13:36 -0800379 both 'tags' and 'base' will have their value/flags modified. Tags with keys
380 in both, but with NULL or zero-length values, will be deleted from the tag
381 set. Tags with invalid (too long or short) keys or values will be ignored.
382 If adding a tag will result in more than CENSUS_MAX_PROPAGATED_TAGS in either
383 binary or non-binary tags, they will be ignored, as will deletions of
384 tags that don't exist.
Alistair Veitchbb30d252016-01-12 17:36:05 -0800385 @param ntags number of tags in 'tags'
Alistair Veitchfc999ad2016-01-14 17:05:46 -0800386 @param stats Information about the tag set created and actions taken during
387 its creation.
Alistair Veitchbb30d252016-01-12 17:36:05 -0800388*/
389census_tag_set *census_tag_set_create(const census_tag_set *base,
Alistair Veitchfc999ad2016-01-14 17:05:46 -0800390 const census_tag *tags, int ntags,
Alistair Veitcha88a2212016-01-15 12:13:36 -0800391 census_tag_set_create_status *status);
Alistair Veitchbb30d252016-01-12 17:36:05 -0800392
393/* Destroy a tag set created by census_tag_set_create(). Once this function
394 has been called, the tag set cannot be reused. */
Alistair Veitchf68bf382015-07-28 14:27:28 -0700395void census_tag_set_destroy(census_tag_set *tags);
396
Alistair Veitchbb30d252016-01-12 17:36:05 -0800397/* Get the number of tags in the tag set. */
398int census_tag_set_ntags(const census_tag_set *tags);
399
Alistair Veitchfc999ad2016-01-14 17:05:46 -0800400/* Structure used for tag set iteration. API clients should not use or
401 reference internal fields - neither their contents or presence/absence are
402 guaranteed. */
403typedef struct {
404 const census_tag_set *tags;
405 int base;
406 int index;
407 char *kvm;
408} census_tag_set_iterator;
409
410/* Initialize a tag set iterator. Must be called before first use of the
411 iterator. */
412void census_tag_set_initialize_iterator(const census_tag_set *tags,
413 census_tag_set_iterator *iterator);
414
415/* Get the contents of the "next" tag in the tag set. If there are no more
416 tags in the tag set, returns 0 (and 'tag' contents will be unchanged),
417 otherwise returns 1. */
418int census_tag_set_next_tag(census_tag_set_iterator *iterator, census_tag *tag);
Alistair Veitchbb30d252016-01-12 17:36:05 -0800419
420/* Get a tag by its key. Returns 0 if the key is not present in the tag
421 set. */
422int census_tag_set_get_tag_by_key(const census_tag_set *tags, const char *key,
423 census_tag *tag);
424
Alistair Veitch0f690722016-01-13 09:08:38 -0800425/* Encode to-be-propagated non-binary tags from a tag set into a memory
426 buffer. The total number of bytes used in the buffer is returned. If the
427 buffer is too small to contain the encoded tag set, then 0 is returned. */
428size_t census_tag_set_encode_propagated(const census_tag_set *tags,
429 char *buffer, size_t buf_size);
430
431/* Encode to-be-propagated binary tags from a tag set into a memory
432 buffer. The total number of bytes used in the buffer is returned. If the
433 buffer is too small to contain the encoded tag set, then 0 is returned. */
434size_t census_tag_set_encode_propagated_binary(const census_tag_set *tags,
435 char *buffer, size_t buf_size);
436
Alistair Veitcha88a2212016-01-15 12:13:36 -0800437/* Decode tag set buffers encoded with census_tag_set_encode_*(). Returns NULL
438 if there is an error in parsing either buffer. The number of tags in the
439 decoded tag set will be returned in status, if it is non-NULL. */
Alistair Veitch0f690722016-01-13 09:08:38 -0800440census_tag_set *census_tag_set_decode(const char *buffer, size_t size,
Alistair Veitcha88a2212016-01-15 12:13:36 -0800441 const char *bin_buffer, size_t bin_size,
442 census_tag_set_create_status *status);
Alistair Veitch0f690722016-01-13 09:08:38 -0800443
Alistair Veitchf68bf382015-07-28 14:27:28 -0700444/* Get a contexts tag set. */
445census_tag_set *census_context_tag_set(census_context *context);
446
Alistair Veitche62f68c2015-08-27 16:24:27 -0700447/* Core stats collection API's. The following concepts are used:
Alistair Veitch9a099822015-08-27 13:16:00 -0700448 * Aggregation: A collection of values. Census supports the following
449 aggregation types:
Alistair Veitchaafe9722015-08-31 13:15:00 -0700450 Sum - a single summation type. Typically used for keeping (e.g.)
Alistair Veitch9a099822015-08-27 13:16:00 -0700451 counts of events.
452 Distribution - statistical distribution information, used for
453 recording average, standard deviation etc.
454 Histogram - a histogram of measurements falling in defined bucket
455 boundaries.
456 Window - a count of events that happen in reolling time window.
457 New aggregation types can be added by the user, if desired (see
458 census_register_aggregation()).
459 * Metric: Each measurement is for a single metric. Examples include RPC
460 latency, CPU seconds consumed, and bytes transmitted.
Alistair Veitchb8552022015-08-28 10:54:17 -0700461 * View: A view is a combination of a metric, a tag set (in which the tag
462 values are regular expressions) and a set of aggregations. When a
463 measurement for a metric matches the view tags, it is recorded (for each
464 unique set of tags) against each aggregation. Each metric can have an
465 arbitrary number of views by which it will be broken down.
Alistair Veitch9a099822015-08-27 13:16:00 -0700466*/
467
468/* A single value to be recorded comprises two parts: an ID for the particular
469 * metric and the value to be recorded against it. */
Alistair Veitch851032a2015-07-20 11:59:13 -0700470typedef struct {
Craig Tiller7536af02015-12-22 13:49:30 -0800471 uint32_t metric_id;
Alistair Veitch851032a2015-07-20 11:59:13 -0700472 double value;
Alistair Veitch9a099822015-08-27 13:16:00 -0700473} census_value;
Alistair Veitch851032a2015-07-20 11:59:13 -0700474
Alistair Veitch9a099822015-08-27 13:16:00 -0700475/* Record new usage values against the given context. */
Alistair Veitch5b614792015-08-31 08:43:37 -0700476void census_record_values(census_context *context, census_value *values,
477 size_t nvalues);
Alistair Veitch4d1589a2015-07-17 15:13:04 -0700478
Alistair Veitch1c09acc2015-08-31 16:57:32 -0700479/** Type representing a particular aggregation */
480typedef struct census_aggregation_ops census_aggregation_ops;
Alistair Veitchade00212015-08-25 15:00:26 -0700481
Alistair Veitch1c09acc2015-08-31 16:57:32 -0700482/* Predefined aggregation types, for use with census_view_create(). */
Alistair Veitchaafe9722015-08-31 13:15:00 -0700483extern census_aggregation_ops census_agg_sum;
Alistair Veitcha24148e2015-08-31 08:30:32 -0700484extern census_aggregation_ops census_agg_distribution;
485extern census_aggregation_ops census_agg_histogram;
486extern census_aggregation_ops census_agg_window;
Alistair Veitchade00212015-08-25 15:00:26 -0700487
Alistair Veitch9a099822015-08-27 13:16:00 -0700488/** Information needed to instantiate a new aggregation. Used in view
489 construction via census_define_view(). */
490typedef struct {
Alistair Veitcha24148e2015-08-31 08:30:32 -0700491 const census_aggregation_ops *ops;
Alistair Veitchbb30d252016-01-12 17:36:05 -0800492 const void
493 *create_arg; /* Argument to be used for aggregation initialization. */
Alistair Veitcha24148e2015-08-31 08:30:32 -0700494} census_aggregation;
Alistair Veitchade00212015-08-25 15:00:26 -0700495
Alistair Veitchb8552022015-08-28 10:54:17 -0700496/** A census view type. Opaque. */
Alistair Veitch9a099822015-08-27 13:16:00 -0700497typedef struct census_view census_view;
Alistair Veitchade00212015-08-25 15:00:26 -0700498
Alistair Veitch9a099822015-08-27 13:16:00 -0700499/** Create a new view.
Alistair Veitche62f68c2015-08-27 16:24:27 -0700500 @param metric_id Metric with which this view is associated.
Alistair Veitch9a099822015-08-27 13:16:00 -0700501 @param tags tags that define the view
502 @param aggregations aggregations to associate with the view
503 @param naggregations number of aggregations
504
505 @return A new census view
Alistair Veitchade00212015-08-25 15:00:26 -0700506*/
Craig Tiller7536af02015-12-22 13:49:30 -0800507census_view *census_view_create(uint32_t metric_id, const census_tag_set *tags,
Alistair Veitcha24148e2015-08-31 08:30:32 -0700508 const census_aggregation *aggregations,
509 size_t naggregations);
Alistair Veitchb8552022015-08-28 10:54:17 -0700510
511/** Destroy a previously created view. */
512void census_view_delete(census_view *view);
Alistair Veitchade00212015-08-25 15:00:26 -0700513
Alistair Veitche62f68c2015-08-27 16:24:27 -0700514/** Metric ID associated with a view */
515size_t census_view_metric(const census_view *view);
516
Alistair Veitch9a099822015-08-27 13:16:00 -0700517/** Number of aggregations associated with view. */
518size_t census_view_naggregations(const census_view *view);
Alistair Veitchade00212015-08-25 15:00:26 -0700519
Alistair Veitch9a099822015-08-27 13:16:00 -0700520/** Get tags associated with view. */
521const census_tag_set *census_view_tags(const census_view *view);
522
Alistair Veitchb8552022015-08-28 10:54:17 -0700523/** Get aggregation descriptors associated with a view. */
Alistair Veitcha24148e2015-08-31 08:30:32 -0700524const census_aggregation *census_view_aggregrations(const census_view *view);
Alistair Veitchade00212015-08-25 15:00:26 -0700525
Alistair Veitch9a099822015-08-27 13:16:00 -0700526/** Holds all the aggregation data for a particular view instantiation. Forms
Alistair Veitchb8552022015-08-28 10:54:17 -0700527 part of the data returned by census_view_data(). */
Alistair Veitch9a099822015-08-27 13:16:00 -0700528typedef struct {
Alistair Veitchb8552022015-08-28 10:54:17 -0700529 const census_tag_set *tags; /* Tags for this set of aggregations. */
530 const void **data; /* One data set for every aggregation in the view. */
Alistair Veitch9a099822015-08-27 13:16:00 -0700531} census_view_aggregation_data;
Alistair Veitchade00212015-08-25 15:00:26 -0700532
Alistair Veitchb8552022015-08-28 10:54:17 -0700533/** Census view data as returned by census_view_get_data(). */
Alistair Veitch9a099822015-08-27 13:16:00 -0700534typedef struct {
Alistair Veitche62f68c2015-08-27 16:24:27 -0700535 size_t n_tag_sets; /* Number of unique tag sets that matched view. */
Alistair Veitch9a099822015-08-27 13:16:00 -0700536 const census_view_aggregation_data *data; /* n_tag_sets entries */
537} census_view_data;
Alistair Veitchade00212015-08-25 15:00:26 -0700538
Alistair Veitch9a099822015-08-27 13:16:00 -0700539/** Get data from aggregations associated with a view.
Alistair Veitche62f68c2015-08-27 16:24:27 -0700540 @param view View from which to get data.
Alistair Veitchb8552022015-08-28 10:54:17 -0700541 @return Full set of data for all aggregations for the view.
Alistair Veitch9a099822015-08-27 13:16:00 -0700542*/
Alistair Veitchb8552022015-08-28 10:54:17 -0700543const census_view_data *census_view_get_data(const census_view *view);
Alistair Veitch9a099822015-08-27 13:16:00 -0700544
Alistair Veitchb8552022015-08-28 10:54:17 -0700545/** Reset all view data to zero for the specified view */
546void census_view_reset(census_view *view);
Alistair Veitchade00212015-08-25 15:00:26 -0700547
Nicolas "Pixel" Noble1ed15e22015-06-09 02:24:35 +0200548#ifdef __cplusplus
549}
550#endif
551
Alistair Veitch9686dab2015-05-26 14:26:47 -0700552#endif /* CENSUS_CENSUS_H */