blob: ab0e0e48026f0feba1cff57e3c0a45f91b20fd1c [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 Veitch4bbdb822016-01-19 13:56:52 -0800332/* A tag is a key:value pair. The key is a non-empty, printable (UTF-8
333 encoded), nil-terminated string. The value is a binary string, that may be
334 printable. There are limits on the sizes of both keys and values (see
335 CENSUS_MAX_TAG_KB_LEN definition below), and the number of tags that can be
336 propagated (CENSUS_MAX_PROPAGATED_TAGS). Users should also remember that
337 some systems may have limits on, e.g., the number of bytes that can be
338 transmitted as metadata, and that larger tags means more memory consumed
339 and time in processing. */
Alistair Veitchbb30d252016-01-12 17:36:05 -0800340typedef struct {
341 const char *key;
342 const char *value;
343 size_t value_len;
Alistair Veitch0f690722016-01-13 09:08:38 -0800344 uint8_t flags;
Alistair Veitchbb30d252016-01-12 17:36:05 -0800345} census_tag;
Alistair Veitchf68bf382015-07-28 14:27:28 -0700346
Alistair Veitch4bbdb822016-01-19 13:56:52 -0800347/* Maximum length of a tag's key or value. */
348#define CENSUS_MAX_TAG_KV_LEN 255
349/* Maximum number of propagatable tags. */
350#define CENSUS_MAX_PROPAGATED_TAGS 255
351
Alistair Veitchbb30d252016-01-12 17:36:05 -0800352/* Tag flags. */
353#define CENSUS_TAG_PROPAGATE 1 /* Tag should be propagated over RPC */
354#define CENSUS_TAG_STATS 2 /* Tag will be used for statistics aggregation */
355#define CENSUS_TAG_BINARY 4 /* Tag value is not printable */
356#define CENSUS_TAG_RESERVED 8 /* Reserved for internal use. */
357/* Flag values 8,16,32,64,128 are reserved for future/internal use. Clients
358 should not use or rely on their values. */
Alistair Veitchf68bf382015-07-28 14:27:28 -0700359
Alistair Veitchbb30d252016-01-12 17:36:05 -0800360#define CENSUS_TAG_IS_PROPAGATED(flags) (flags & CENSUS_TAG_PROPAGATE)
361#define CENSUS_TAG_IS_STATS(flags) (flags & CENSUS_TAG_STATS)
362#define CENSUS_TAG_IS_BINARY(flags) (flags & CENSUS_TAG_BINARY)
363
Alistair Veitchfc999ad2016-01-14 17:05:46 -0800364typedef struct {
365 int n_propagated_tags; /* number of propagated printable tags */
366 int n_propagated_binary_tags; /* number of propagated binary tags */
367 int n_local_tags; /* number of non-propagated (local) tags */
368 int n_deleted_tags; /* number of tags that were deleted */
369 int n_added_tags; /* number of tags that were added */
370 int n_modified_tags; /* number of tags that were modified */
371 int n_invalid_tags; /* number of tags with bad keys or values (e.g.
372 longer than CENSUS_MAX_TAG_KV_LEN) */
Alistair Veitcha88a2212016-01-15 12:13:36 -0800373 int n_ignored_tags; /* number of tags ignored because of
374 CENSUS_MAX_PROPAGATED_TAGS limit. */
375} census_tag_set_create_status;
Alistair Veitchbb30d252016-01-12 17:36:05 -0800376
377/* Create a new tag set, adding and removing tags from an existing tag set.
Alistair Veitch8e5b21f2016-01-20 09:17:11 -0800378 This will copy all tags from it's input parameters, so it is recommended
379 to add as many tags in a single operation as is practical for the client.
Alistair Veitchbb30d252016-01-12 17:36:05 -0800380 @param base Base tag set to build upon. Can be NULL.
381 @param tags A set of tags to be added/changed/deleted. Tags with keys that
382 are in 'tags', but not 'base', are added to the tag set. Keys that are in
Alistair Veitcha88a2212016-01-15 12:13:36 -0800383 both 'tags' and 'base' will have their value/flags modified. Tags with keys
384 in both, but with NULL or zero-length values, will be deleted from the tag
385 set. Tags with invalid (too long or short) keys or values will be ignored.
386 If adding a tag will result in more than CENSUS_MAX_PROPAGATED_TAGS in either
387 binary or non-binary tags, they will be ignored, as will deletions of
388 tags that don't exist.
Alistair Veitchbb30d252016-01-12 17:36:05 -0800389 @param ntags number of tags in 'tags'
Alistair Veitch0c1cdcd2016-01-21 17:25:41 -0800390 @param status If not NULL, will return a pointer to a
391 census_tag_set_create_status structure containing information about the new
392 tag set and status of the tags used in its creation.
Alistair Veitch8e5b21f2016-01-20 09:17:11 -0800393 @return A new, valid census_tag_set.
Alistair Veitchbb30d252016-01-12 17:36:05 -0800394*/
Alistair Veitch6670add2016-01-21 17:21:53 -0800395census_tag_set *census_tag_set_create(
396 const census_tag_set *base, const census_tag *tags, int ntags,
397 census_tag_set_create_status const **status);
Alistair Veitchbb30d252016-01-12 17:36:05 -0800398
399/* Destroy a tag set created by census_tag_set_create(). Once this function
400 has been called, the tag set cannot be reused. */
Alistair Veitchf68bf382015-07-28 14:27:28 -0700401void census_tag_set_destroy(census_tag_set *tags);
402
Alistair Veitch0c1cdcd2016-01-21 17:25:41 -0800403/* Get a pointer to the original status from the creation of this tag set. */
Alistair Veitch6670add2016-01-21 17:21:53 -0800404const census_tag_set_create_status *census_tag_set_get_create_status(
405 const census_tag_set *tags);
Alistair Veitchbb30d252016-01-12 17:36:05 -0800406
Alistair Veitchfc999ad2016-01-14 17:05:46 -0800407/* Structure used for tag set iteration. API clients should not use or
408 reference internal fields - neither their contents or presence/absence are
409 guaranteed. */
410typedef struct {
411 const census_tag_set *tags;
412 int base;
413 int index;
414 char *kvm;
415} census_tag_set_iterator;
416
417/* Initialize a tag set iterator. Must be called before first use of the
418 iterator. */
419void census_tag_set_initialize_iterator(const census_tag_set *tags,
420 census_tag_set_iterator *iterator);
421
422/* Get the contents of the "next" tag in the tag set. If there are no more
423 tags in the tag set, returns 0 (and 'tag' contents will be unchanged),
424 otherwise returns 1. */
425int census_tag_set_next_tag(census_tag_set_iterator *iterator, census_tag *tag);
Alistair Veitchbb30d252016-01-12 17:36:05 -0800426
427/* Get a tag by its key. Returns 0 if the key is not present in the tag
428 set. */
429int census_tag_set_get_tag_by_key(const census_tag_set *tags, const char *key,
430 census_tag *tag);
431
Alistair Veitch04de8c12016-01-15 13:15:03 -0800432/* Tag set encode/decode functionality. These functionas are intended
433 for use by RPC systems only, for purposes of transmitting/receiving tag
434 sets. */
435
Alistair Veitchc45d0882016-01-22 11:43:30 -0800436/* Encode a tag set into a buffer. The propagated tags are encoded into the
437 buffer in two regions: one for printable tags, and one for binary tags.
438 @param tags tag set to be encoded
439 @param buffer pointer to buffer. This address will be used to encode the
440 printable tags.
Alistair Veitchff14b442016-01-22 13:01:49 -0800441 @param buf_size number of available bytes in buffer.
442 @param print_buf_size Will be set to the number of bytes consumed by
443 printable tags.
444 @param bin_buf_size Will be set to the number of bytes used to encode the
445 binary tags.
Alistair Veitchc45d0882016-01-22 11:43:30 -0800446 @return A pointer to the binary tag's encoded, or NULL if the buffer was
447 insufficiently large to hold the encoded tags. Thus, if successful,
448 printable tags are encoded into
Alistair Veitchff14b442016-01-22 13:01:49 -0800449 [buffer, buffer + *print_buf_size) and binary tags into
Alistair Veitchc45d0882016-01-22 11:43:30 -0800450 [returned-ptr, returned-ptr + *bin_buf_size) (and the return value
Alistair Veitchff14b442016-01-22 13:01:49 -0800451 should be buffer + *print_buf_size) */
Alistair Veitchc45d0882016-01-22 11:43:30 -0800452char *census_tag_set_encode(const census_tag_set *tags, char *buffer,
Alistair Veitchff14b442016-01-22 13:01:49 -0800453 size_t buf_size, size_t *print_buf_size,
454 size_t *bin_buf_size);
Alistair Veitch0f690722016-01-13 09:08:38 -0800455
Alistair Veitcha88a2212016-01-15 12:13:36 -0800456/* Decode tag set buffers encoded with census_tag_set_encode_*(). Returns NULL
Alistair Veitch6670add2016-01-21 17:21:53 -0800457 if there is an error in parsing either buffer. */
Alistair Veitch0f690722016-01-13 09:08:38 -0800458census_tag_set *census_tag_set_decode(const char *buffer, size_t size,
Alistair Veitch6670add2016-01-21 17:21:53 -0800459 const char *bin_buffer, size_t bin_size);
Alistair Veitch0f690722016-01-13 09:08:38 -0800460
Alistair Veitchf68bf382015-07-28 14:27:28 -0700461/* Get a contexts tag set. */
462census_tag_set *census_context_tag_set(census_context *context);
463
Alistair Veitche62f68c2015-08-27 16:24:27 -0700464/* Core stats collection API's. The following concepts are used:
Alistair Veitch9a099822015-08-27 13:16:00 -0700465 * Aggregation: A collection of values. Census supports the following
466 aggregation types:
Alistair Veitchaafe9722015-08-31 13:15:00 -0700467 Sum - a single summation type. Typically used for keeping (e.g.)
Alistair Veitch9a099822015-08-27 13:16:00 -0700468 counts of events.
469 Distribution - statistical distribution information, used for
470 recording average, standard deviation etc.
471 Histogram - a histogram of measurements falling in defined bucket
472 boundaries.
473 Window - a count of events that happen in reolling time window.
474 New aggregation types can be added by the user, if desired (see
475 census_register_aggregation()).
476 * Metric: Each measurement is for a single metric. Examples include RPC
477 latency, CPU seconds consumed, and bytes transmitted.
Alistair Veitchb8552022015-08-28 10:54:17 -0700478 * View: A view is a combination of a metric, a tag set (in which the tag
479 values are regular expressions) and a set of aggregations. When a
480 measurement for a metric matches the view tags, it is recorded (for each
481 unique set of tags) against each aggregation. Each metric can have an
482 arbitrary number of views by which it will be broken down.
Alistair Veitch9a099822015-08-27 13:16:00 -0700483*/
484
485/* A single value to be recorded comprises two parts: an ID for the particular
486 * metric and the value to be recorded against it. */
Alistair Veitch851032a2015-07-20 11:59:13 -0700487typedef struct {
Craig Tiller7536af02015-12-22 13:49:30 -0800488 uint32_t metric_id;
Alistair Veitch851032a2015-07-20 11:59:13 -0700489 double value;
Alistair Veitch9a099822015-08-27 13:16:00 -0700490} census_value;
Alistair Veitch851032a2015-07-20 11:59:13 -0700491
Alistair Veitch9a099822015-08-27 13:16:00 -0700492/* Record new usage values against the given context. */
Alistair Veitch5b614792015-08-31 08:43:37 -0700493void census_record_values(census_context *context, census_value *values,
494 size_t nvalues);
Alistair Veitch4d1589a2015-07-17 15:13:04 -0700495
Alistair Veitch1c09acc2015-08-31 16:57:32 -0700496/** Type representing a particular aggregation */
497typedef struct census_aggregation_ops census_aggregation_ops;
Alistair Veitchade00212015-08-25 15:00:26 -0700498
Alistair Veitch1c09acc2015-08-31 16:57:32 -0700499/* Predefined aggregation types, for use with census_view_create(). */
Alistair Veitchaafe9722015-08-31 13:15:00 -0700500extern census_aggregation_ops census_agg_sum;
Alistair Veitcha24148e2015-08-31 08:30:32 -0700501extern census_aggregation_ops census_agg_distribution;
502extern census_aggregation_ops census_agg_histogram;
503extern census_aggregation_ops census_agg_window;
Alistair Veitchade00212015-08-25 15:00:26 -0700504
Alistair Veitch9a099822015-08-27 13:16:00 -0700505/** Information needed to instantiate a new aggregation. Used in view
506 construction via census_define_view(). */
507typedef struct {
Alistair Veitcha24148e2015-08-31 08:30:32 -0700508 const census_aggregation_ops *ops;
Alistair Veitchbb30d252016-01-12 17:36:05 -0800509 const void
510 *create_arg; /* Argument to be used for aggregation initialization. */
Alistair Veitcha24148e2015-08-31 08:30:32 -0700511} census_aggregation;
Alistair Veitchade00212015-08-25 15:00:26 -0700512
Alistair Veitchb8552022015-08-28 10:54:17 -0700513/** A census view type. Opaque. */
Alistair Veitch9a099822015-08-27 13:16:00 -0700514typedef struct census_view census_view;
Alistair Veitchade00212015-08-25 15:00:26 -0700515
Alistair Veitch9a099822015-08-27 13:16:00 -0700516/** Create a new view.
Alistair Veitche62f68c2015-08-27 16:24:27 -0700517 @param metric_id Metric with which this view is associated.
Alistair Veitch9a099822015-08-27 13:16:00 -0700518 @param tags tags that define the view
519 @param aggregations aggregations to associate with the view
520 @param naggregations number of aggregations
521
522 @return A new census view
Alistair Veitchade00212015-08-25 15:00:26 -0700523*/
Craig Tiller7536af02015-12-22 13:49:30 -0800524census_view *census_view_create(uint32_t metric_id, const census_tag_set *tags,
Alistair Veitcha24148e2015-08-31 08:30:32 -0700525 const census_aggregation *aggregations,
526 size_t naggregations);
Alistair Veitchb8552022015-08-28 10:54:17 -0700527
528/** Destroy a previously created view. */
529void census_view_delete(census_view *view);
Alistair Veitchade00212015-08-25 15:00:26 -0700530
Alistair Veitche62f68c2015-08-27 16:24:27 -0700531/** Metric ID associated with a view */
532size_t census_view_metric(const census_view *view);
533
Alistair Veitch9a099822015-08-27 13:16:00 -0700534/** Number of aggregations associated with view. */
535size_t census_view_naggregations(const census_view *view);
Alistair Veitchade00212015-08-25 15:00:26 -0700536
Alistair Veitch9a099822015-08-27 13:16:00 -0700537/** Get tags associated with view. */
538const census_tag_set *census_view_tags(const census_view *view);
539
Alistair Veitchb8552022015-08-28 10:54:17 -0700540/** Get aggregation descriptors associated with a view. */
Alistair Veitcha24148e2015-08-31 08:30:32 -0700541const census_aggregation *census_view_aggregrations(const census_view *view);
Alistair Veitchade00212015-08-25 15:00:26 -0700542
Alistair Veitch9a099822015-08-27 13:16:00 -0700543/** Holds all the aggregation data for a particular view instantiation. Forms
Alistair Veitchb8552022015-08-28 10:54:17 -0700544 part of the data returned by census_view_data(). */
Alistair Veitch9a099822015-08-27 13:16:00 -0700545typedef struct {
Alistair Veitchb8552022015-08-28 10:54:17 -0700546 const census_tag_set *tags; /* Tags for this set of aggregations. */
547 const void **data; /* One data set for every aggregation in the view. */
Alistair Veitch9a099822015-08-27 13:16:00 -0700548} census_view_aggregation_data;
Alistair Veitchade00212015-08-25 15:00:26 -0700549
Alistair Veitchb8552022015-08-28 10:54:17 -0700550/** Census view data as returned by census_view_get_data(). */
Alistair Veitch9a099822015-08-27 13:16:00 -0700551typedef struct {
Alistair Veitche62f68c2015-08-27 16:24:27 -0700552 size_t n_tag_sets; /* Number of unique tag sets that matched view. */
Alistair Veitch9a099822015-08-27 13:16:00 -0700553 const census_view_aggregation_data *data; /* n_tag_sets entries */
554} census_view_data;
Alistair Veitchade00212015-08-25 15:00:26 -0700555
Alistair Veitch9a099822015-08-27 13:16:00 -0700556/** Get data from aggregations associated with a view.
Alistair Veitche62f68c2015-08-27 16:24:27 -0700557 @param view View from which to get data.
Alistair Veitchb8552022015-08-28 10:54:17 -0700558 @return Full set of data for all aggregations for the view.
Alistair Veitch9a099822015-08-27 13:16:00 -0700559*/
Alistair Veitchb8552022015-08-28 10:54:17 -0700560const census_view_data *census_view_get_data(const census_view *view);
Alistair Veitch9a099822015-08-27 13:16:00 -0700561
Alistair Veitchb8552022015-08-28 10:54:17 -0700562/** Reset all view data to zero for the specified view */
563void census_view_reset(census_view *view);
Alistair Veitchade00212015-08-25 15:00:26 -0700564
Nicolas "Pixel" Noble1ed15e22015-06-09 02:24:35 +0200565#ifdef __cplusplus
566}
567#endif
568
Alistair Veitch9686dab2015-05-26 14:26:47 -0700569#endif /* CENSUS_CENSUS_H */