blob: dfa3bd7e0df70d530f7607a3060865ef46806b42 [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()). */
Nicolas "Pixel" Noblecd41a0b2016-02-08 22:53:14 +010062CENSUSAPI int census_initialize(int features);
63CENSUSAPI void 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). */
Nicolas "Pixel" Noblecd41a0b2016-02-08 22:53:14 +010067CENSUSAPI int census_supported(void);
Alistair Veitch925e4a62015-07-26 16:51:23 -070068
69/** Return the census features currently enabled. */
Nicolas "Pixel" Noblecd41a0b2016-02-08 22:53:14 +010070CENSUSAPI int census_enabled(void);
Alistair Veitchfc62ddd2015-06-29 02:52:46 -070071
Alistair Veitche6d0ad32015-08-13 09:59:48 -070072/**
Alistair Veitch75d5c0f2016-02-02 09:43:02 -080073 A Census Context is a handle used by Census to represent the current tracing
74 and stats collection information. Contexts should be propagated across RPC's
75 (this is the responsibility of the local RPC system). A context is typically
76 used as the first argument to most census functions. Conceptually, they
77 should be thought of as specific to a single RPC/thread. The user visible
78 context representation is that of a collection of key:value string pairs,
79 each of which is termed a 'tag'; these form the basis against which Census
80 metrics will be recorded. Keys are unique within a context. */
Alistair Veitch9686dab2015-05-26 14:26:47 -070081typedef struct census_context census_context;
82
Alistair Veitch75d5c0f2016-02-02 09:43:02 -080083/* A tag is a key:value pair. The key is a non-empty, printable (UTF-8
84 encoded), nil-terminated string. The value is a binary string, that may be
85 printable. There are limits on the sizes of both keys and values (see
86 CENSUS_MAX_TAG_KB_LEN definition below), and the number of tags that can be
87 propagated (CENSUS_MAX_PROPAGATED_TAGS). Users should also remember that
88 some systems may have limits on, e.g., the number of bytes that can be
89 transmitted as metadata, and that larger tags means more memory consumed
90 and time in processing. */
91typedef struct {
92 const char *key;
93 const char *value;
94 size_t value_len;
95 uint8_t flags;
96} census_tag;
97
98/* Maximum length of a tag's key or value. */
99#define CENSUS_MAX_TAG_KV_LEN 255
100/* Maximum number of propagatable tags. */
101#define CENSUS_MAX_PROPAGATED_TAGS 255
102
103/* Tag flags. */
104#define CENSUS_TAG_PROPAGATE 1 /* Tag should be propagated over RPC */
105#define CENSUS_TAG_STATS 2 /* Tag will be used for statistics aggregation */
106#define CENSUS_TAG_BINARY 4 /* Tag value is not printable */
107#define CENSUS_TAG_RESERVED 8 /* Reserved for internal use. */
108/* Flag values 8,16,32,64,128 are reserved for future/internal use. Clients
109 should not use or rely on their values. */
110
111#define CENSUS_TAG_IS_PROPAGATED(flags) (flags & CENSUS_TAG_PROPAGATE)
112#define CENSUS_TAG_IS_STATS(flags) (flags & CENSUS_TAG_STATS)
113#define CENSUS_TAG_IS_BINARY(flags) (flags & CENSUS_TAG_BINARY)
114
115/* An instance of this structure is kept by every context, and records the
116 basic information associated with the creation of that context. */
117typedef struct {
118 int n_propagated_tags; /* number of propagated printable tags */
119 int n_propagated_binary_tags; /* number of propagated binary tags */
120 int n_local_tags; /* number of non-propagated (local) tags */
121 int n_deleted_tags; /* number of tags that were deleted */
122 int n_added_tags; /* number of tags that were added */
123 int n_modified_tags; /* number of tags that were modified */
124 int n_invalid_tags; /* number of tags with bad keys or values (e.g.
125 longer than CENSUS_MAX_TAG_KV_LEN) */
126 int n_ignored_tags; /* number of tags ignored because of
127 CENSUS_MAX_PROPAGATED_TAGS limit. */
128} census_context_status;
129
130/* Create a new context, adding and removing tags from an existing context.
131 This will copy all tags from the 'tags' input, so it is recommended
132 to add as many tags in a single operation as is practical for the client.
133 @param base Base context to build upon. Can be NULL.
134 @param tags A set of tags to be added/changed/deleted. Tags with keys that
135 are in 'tags', but not 'base', are added to the tag set. Keys that are in
136 both 'tags' and 'base' will have their value/flags modified. Tags with keys
137 in both, but with NULL or zero-length values, will be deleted from the tag
138 set. Tags with invalid (too long or short) keys or values will be ignored.
139 If adding a tag will result in more than CENSUS_MAX_PROPAGATED_TAGS in either
140 binary or non-binary tags, they will be ignored, as will deletions of
141 tags that don't exist.
142 @param ntags number of tags in 'tags'
143 @param status If not NULL, will return a pointer to a census_context_status
144 structure containing information about the new context and status of the
145 tags used in its creation.
146 @return A new, valid census_context.
147*/
Nicolas "Pixel" Noblecd41a0b2016-02-08 22:53:14 +0100148CENSUSAPI census_context *census_context_create(
Alistair Veitch2e6c1822016-02-02 09:51:56 -0800149 const census_context *base, const census_tag *tags, int ntags,
150 census_context_status const **status);
Alistair Veitch75d5c0f2016-02-02 09:43:02 -0800151
152/* Destroy a context. Once this function has been called, the context cannot
153 be reused. */
Nicolas "Pixel" Noblecd41a0b2016-02-08 22:53:14 +0100154CENSUSAPI void census_context_destroy(census_context *context);
Alistair Veitch75d5c0f2016-02-02 09:43:02 -0800155
156/* Get a pointer to the original status from the context creation. */
Nicolas "Pixel" Noblecd41a0b2016-02-08 22:53:14 +0100157CENSUSAPI const census_context_status *census_context_get_status(
Alistair Veitch75d5c0f2016-02-02 09:43:02 -0800158 const census_context *context);
159
160/* Structure used for iterating over the tegs in a context. API clients should
161 not use or reference internal fields - neither their contents or
162 presence/absence are guaranteed. */
163typedef struct {
164 const census_context *context;
165 int base;
166 int index;
167 char *kvm;
168} census_context_iterator;
169
170/* Initialize a census_tag_iterator. Must be called before first use. */
Nicolas "Pixel" Noblecd41a0b2016-02-08 22:53:14 +0100171CENSUSAPI void census_context_initialize_iterator(
Alistair Veitch2e6c1822016-02-02 09:51:56 -0800172 const census_context *context, census_context_iterator *iterator);
Alistair Veitch75d5c0f2016-02-02 09:43:02 -0800173
174/* Get the contents of the "next" tag in the context. If there are no more
175 tags, returns 0 (and 'tag' contents will be unchanged), otherwise returns 1.
176 */
Nicolas "Pixel" Noblecd41a0b2016-02-08 22:53:14 +0100177CENSUSAPI int census_context_next_tag(census_context_iterator *iterator,
178 census_tag *tag);
Alistair Veitch75d5c0f2016-02-02 09:43:02 -0800179
180/* Get a context tag by key. Returns 0 if the key is not present. */
Nicolas "Pixel" Noblecd41a0b2016-02-08 22:53:14 +0100181CENSUSAPI int census_context_get_tag(const census_context *context,
182 const char *key, census_tag *tag);
Alistair Veitch75d5c0f2016-02-02 09:43:02 -0800183
184/* Tag set encode/decode functionality. These functionas are intended
185 for use by RPC systems only, for purposes of transmitting/receiving contexts.
186 */
187
188/* Encode a context into a buffer. The propagated tags are encoded into the
189 buffer in two regions: one for printable tags, and one for binary tags.
190 @param context context to be encoded
191 @param buffer pointer to buffer. This address will be used to encode the
192 printable tags.
193 @param buf_size number of available bytes in buffer.
194 @param print_buf_size Will be set to the number of bytes consumed by
195 printable tags.
196 @param bin_buf_size Will be set to the number of bytes used to encode the
197 binary tags.
198 @return A pointer to the binary tag's encoded, or NULL if the buffer was
199 insufficiently large to hold the encoded tags. Thus, if successful,
200 printable tags are encoded into
201 [buffer, buffer + *print_buf_size) and binary tags into
202 [returned-ptr, returned-ptr + *bin_buf_size) (and the returned
203 pointer should be buffer + *print_buf_size) */
Nicolas "Pixel" Noblecd41a0b2016-02-08 22:53:14 +0100204CENSUSAPI char *census_context_encode(const census_context *context,
205 char *buffer, size_t buf_size,
206 size_t *print_buf_size,
207 size_t *bin_buf_size);
Alistair Veitch75d5c0f2016-02-02 09:43:02 -0800208
209/* Decode context buffers encoded with census_context_encode(). Returns NULL
210 if there is an error in parsing either buffer. */
Nicolas "Pixel" Noblecd41a0b2016-02-08 22:53:14 +0100211CENSUSAPI census_context *census_context_decode(const char *buffer, size_t size,
212 const char *bin_buffer,
213 size_t bin_size);
Alistair Veitch9686dab2015-05-26 14:26:47 -0700214
Alistair Veitchaf5002f2015-07-26 15:11:50 -0700215/* Distributed traces can have a number of options. */
216enum census_trace_mask_values {
Alistair Veitch0383d492015-07-26 15:29:00 -0700217 CENSUS_TRACE_MASK_NONE = 0, /* Default, empty flags */
218 CENSUS_TRACE_MASK_IS_SAMPLED = 1 /* RPC tracing enabled for this context. */
Alistair Veitchaf5002f2015-07-26 15:11:50 -0700219};
Alistair Veitch9686dab2015-05-26 14:26:47 -0700220
Alistair Veitchaf5002f2015-07-26 15:11:50 -0700221/** Get the current trace mask associated with this context. The value returned
222 will be the logical or of census_trace_mask_values values. */
Nicolas "Pixel" Noblecd41a0b2016-02-08 22:53:14 +0100223CENSUSAPI int census_trace_mask(const census_context *context);
Alistair Veitch491a9d42015-07-21 10:08:37 -0700224
Alistair Veitche6d0ad32015-08-13 09:59:48 -0700225/** Set the trace mask associated with a context. */
Nicolas "Pixel" Noblecd41a0b2016-02-08 22:53:14 +0100226CENSUSAPI void census_set_trace_mask(int trace_mask);
Alistair Veitche6d0ad32015-08-13 09:59:48 -0700227
228/* The concept of "operation" is a fundamental concept for Census. In an RPC
229 system, and operation typcially represents a single RPC, or a significant
230 sub-part thereof (e.g. a single logical "read" RPC to a distributed storage
231 system might do several other actions in parallel, from looking up metadata
Alistair Veitchaf5002f2015-07-26 15:11:50 -0700232 indices to making requests of other services - each of these could be a
Alistair Veitche6d0ad32015-08-13 09:59:48 -0700233 sub-operation with the larger RPC operation). Census uses operations for the
Alistair Veitchaf5002f2015-07-26 15:11:50 -0700234 following:
Alistair Veitch491a9d42015-07-21 10:08:37 -0700235
Alistair Veitchaf5002f2015-07-26 15:11:50 -0700236 CPU accounting: If enabled, census will measure the thread CPU time
237 consumed between operation start and end times.
238
239 Active operations: Census will maintain information on all currently
240 active operations.
241
242 Distributed tracing: Each operation serves as a logical trace span.
243
Alistair Veitche6d0ad32015-08-13 09:59:48 -0700244 Stats collection: Stats are broken down by operation (e.g. latency
245 breakdown for each unique RPC path).
Alistair Veitchaf5002f2015-07-26 15:11:50 -0700246
247 The following functions serve to delineate the start and stop points for
248 each logical operation. */
Alistair Veitche6d0ad32015-08-13 09:59:48 -0700249
Alistair Veitchaf5002f2015-07-26 15:11:50 -0700250/**
Alistair Veitchf8869852015-08-25 15:24:49 -0700251 This structure represents a timestamp as used by census to record the time
252 at which an operation begins.
Alistair Veitche6d0ad32015-08-13 09:59:48 -0700253*/
Alistair Veitchf8869852015-08-25 15:24:49 -0700254typedef struct {
255 /* Use gpr_timespec for default implementation. High performance
256 * implementations should use a cycle-counter based timestamp. */
257 gpr_timespec ts;
258} census_timestamp;
Alistair Veitche6d0ad32015-08-13 09:59:48 -0700259
260/**
261 Mark the beginning of an RPC operation. The information required to call the
262 functions to record the start of RPC operations (both client and server) may
263 not be callable at the true start time of the operation, due to information
264 not being available (e.g. the census context data will not be available in a
265 server RPC until at least initial metadata has been processed). To ensure
266 correct CPU accounting and latency recording, RPC systems can call this
267 function to get the timestamp of operation beginning. This can later be used
268 as an argument to census_start_{client,server}_rpc_op(). NB: for correct
269 CPU accounting, the system must guarantee that the same thread is used
270 for all request processing after this function is called.
271
272 @return A timestamp representing the operation start time.
273*/
Nicolas "Pixel" Noblecd41a0b2016-02-08 22:53:14 +0100274CENSUSAPI census_timestamp census_start_rpc_op_timestamp(void);
Alistair Veitche6d0ad32015-08-13 09:59:48 -0700275
276/**
277 Represent functions to map RPC name ID to service/method names. Census
278 breaks down all RPC stats by service and method names. We leave the
279 definition and format of these to the RPC system. For efficiency purposes,
280 we encode these as a single 64 bit identifier, and allow the RPC system to
281 provide a structure for functions that can convert these to service and
282 method strings.
283
284 TODO(aveitch): Instead of providing this as an argument to the rpc_start_op()
285 functions, maybe it should be set once at census initialization.
286*/
287typedef struct {
Craig Tiller7536af02015-12-22 13:49:30 -0800288 const char *(*get_rpc_service_name)(int64_t id);
289 const char *(*get_rpc_method_name)(int64_t id);
Alistair Veitche6d0ad32015-08-13 09:59:48 -0700290} census_rpc_name_info;
291
292/**
293 Start a client rpc operation. This function should be called as early in the
294 client RPC path as possible. This function will create a new context. If
Alistair Veitchaf5002f2015-07-26 15:11:50 -0700295 the context argument is non-null, then the new context will inherit all
296 its properties, with the following changes:
297 - create a new operation ID for the new context, marking it as a child of
298 the previous operation.
Alistair Veitche6d0ad32015-08-13 09:59:48 -0700299 - use the new RPC path and peer information for tracing and stats
Alistair Veitchaf5002f2015-07-26 15:11:50 -0700300 collection purposes, rather than those from the original context
Alistair Veitchaf5002f2015-07-26 15:11:50 -0700301
Alistair Veitche6d0ad32015-08-13 09:59:48 -0700302 If the context argument is NULL, then a new root context is created. This
Alistair Veitchaf5002f2015-07-26 15:11:50 -0700303 is particularly important for tracing purposes (the trace spans generated
304 will be unassociated with any other trace spans, except those
Alistair Veitche6d0ad32015-08-13 09:59:48 -0700305 downstream). The trace_mask will be used for tracing operations associated
306 with the new context.
Alistair Veitchaf5002f2015-07-26 15:11:50 -0700307
Alistair Veitche6d0ad32015-08-13 09:59:48 -0700308 In some RPC systems (e.g. where load balancing is used), peer information
309 may not be available at the time the operation starts. In this case, use a
310 NULL value for peer, and set it later using the
311 census_set_rpc_client_peer() function.
312
313 @param context The parent context. Can be NULL.
314 @param rpc_name_id The rpc name identifier to be associated with this RPC.
315 @param rpc_name_info Used to decode rpc_name_id.
316 @param peer RPC peer. If not available at the time, NULL can be used,
317 and a later census_set_rpc_client_peer() call made.
318 @param trace_mask An OR of census_trace_mask_values values. Only used in
319 the creation of a new root context (context == NULL).
320 @param start_time A timestamp returned from census_start_rpc_op_timestamp().
321 Can be NULL. Used to set the true time the operation
322 begins.
Alistair Veitchaf5002f2015-07-26 15:11:50 -0700323
324 @return A new census context.
325 */
Nicolas "Pixel" Noblecd41a0b2016-02-08 22:53:14 +0100326CENSUSAPI census_context *census_start_client_rpc_op(
Craig Tiller7536af02015-12-22 13:49:30 -0800327 const census_context *context, int64_t rpc_name_id,
Alistair Veitche6d0ad32015-08-13 09:59:48 -0700328 const census_rpc_name_info *rpc_name_info, const char *peer, int trace_mask,
329 const census_timestamp *start_time);
Alistair Veitchaf5002f2015-07-26 15:11:50 -0700330
331/**
Alistair Veitche6d0ad32015-08-13 09:59:48 -0700332 Add peer information to a context representing a client RPC operation.
333*/
Nicolas "Pixel" Noblecd41a0b2016-02-08 22:53:14 +0100334CENSUSAPI void census_set_rpc_client_peer(census_context *context,
335 const char *peer);
Alistair Veitchaf5002f2015-07-26 15:11:50 -0700336
Alistair Veitche6d0ad32015-08-13 09:59:48 -0700337/**
338 Start a server RPC operation. Returns a new context to be used in future
339 census calls. If buffer is non-NULL, then the buffer contents should
340 represent the client context, as generated by census_context_serialize().
341 If buffer is NULL, a new root context is created.
342
343 @param buffer Buffer containing bytes output from census_context_serialize().
344 @param rpc_name_id The rpc name identifier to be associated with this RPC.
345 @param rpc_name_info Used to decode rpc_name_id.
346 @param peer RPC peer.
347 @param trace_mask An OR of census_trace_mask_values values. Only used in
348 the creation of a new root context (buffer == NULL).
349 @param start_time A timestamp returned from census_start_rpc_op_timestamp().
350 Can be NULL. Used to set the true time the operation
351 begins.
352
353 @return A new census context.
Alistair Veitchaf5002f2015-07-26 15:11:50 -0700354 */
Nicolas "Pixel" Noblecd41a0b2016-02-08 22:53:14 +0100355CENSUSAPI census_context *census_start_server_rpc_op(
Craig Tiller7536af02015-12-22 13:49:30 -0800356 const char *buffer, int64_t rpc_name_id,
Alistair Veitche6d0ad32015-08-13 09:59:48 -0700357 const census_rpc_name_info *rpc_name_info, const char *peer, int trace_mask,
358 census_timestamp *start_time);
Alistair Veitchaf5002f2015-07-26 15:11:50 -0700359
360/**
Alistair Veitche6d0ad32015-08-13 09:59:48 -0700361 Start a new, non-RPC operation. In general, this function works very
362 similarly to census_start_client_rpc_op, with the primary difference being
363 the replacement of host/path information with the more generic family/name
364 tags. If the context argument is non-null, then the new context will
365 inherit all its properties, with the following changes:
Alistair Veitchaf5002f2015-07-26 15:11:50 -0700366 - create a new operation ID for the new context, marking it as a child of
367 the previous operation.
368 - use the family and name information for tracing and stats collection
369 purposes, rather than those from the original context
Alistair Veitchaf5002f2015-07-26 15:11:50 -0700370
Alistair Veitche6d0ad32015-08-13 09:59:48 -0700371 If the context argument is NULL, then a new root context is created. This
Alistair Veitchaf5002f2015-07-26 15:11:50 -0700372 is particularly important for tracing purposes (the trace spans generated
373 will be unassociated with any other trace spans, except those
Alistair Veitche6d0ad32015-08-13 09:59:48 -0700374 downstream). The trace_mask will be used for tracing
Alistair Veitchaf5002f2015-07-26 15:11:50 -0700375 operations associated with the new context.
376
377 @param context The base context. Can be NULL.
378 @param family Family name to associate with the trace
379 @param name Name within family to associated with traces/stats
Alistair Veitche6d0ad32015-08-13 09:59:48 -0700380 @param trace_mask An OR of census_trace_mask_values values. Only used if
381 context is NULL.
Alistair Veitchaf5002f2015-07-26 15:11:50 -0700382
383 @return A new census context.
384 */
Nicolas "Pixel" Noblecd41a0b2016-02-08 22:53:14 +0100385CENSUSAPI census_context *census_start_op(census_context *context,
386 const char *family, const char *name,
387 int trace_mask);
Alistair Veitchaf5002f2015-07-26 15:11:50 -0700388
Alistair Veitch0879df22015-08-13 14:32:05 -0700389/**
390 End an operation started by any of the census_start_*_op*() calls. The
391 context used in this call will no longer be valid once this function
392 completes.
393
394 @param context Context associated with operation which is ending.
395 @param status status associated with the operation. Not interpreted by
396 census.
397*/
Nicolas "Pixel" Noblecd41a0b2016-02-08 22:53:14 +0100398CENSUSAPI void census_end_op(census_context *context, int status);
Alistair Veitchaf5002f2015-07-26 15:11:50 -0700399
Craig Tiller7536af02015-12-22 13:49:30 -0800400#define CENSUS_TRACE_RECORD_START_OP ((uint32_t)0)
401#define CENSUS_TRACE_RECORD_END_OP ((uint32_t)1)
Alistair Veitch6afe53f2015-08-28 14:05:15 -0700402
Alistair Veitchaf5002f2015-07-26 15:11:50 -0700403/** Insert a trace record into the trace stream. The record consists of an
Alistair Veitch6afe53f2015-08-28 14:05:15 -0700404 arbitrary size buffer, the size of which is provided in 'n'.
405 @param context Trace context
406 @param type User-defined type to associate with trace entry.
407 @param buffer Pointer to buffer to use
408 @param n Number of bytes in buffer
409*/
Nicolas "Pixel" Noblecd41a0b2016-02-08 22:53:14 +0100410CENSUSAPI void census_trace_print(census_context *context, uint32_t type,
411 const char *buffer, size_t n);
Alistair Veitch6afe53f2015-08-28 14:05:15 -0700412
413/** Trace record. */
414typedef struct {
415 census_timestamp timestamp; /* Time of record creation */
Craig Tiller7536af02015-12-22 13:49:30 -0800416 uint64_t trace_id; /* Trace ID associated with record */
417 uint64_t op_id; /* Operation ID associated with record */
418 uint32_t type; /* Type (as used in census_trace_print() */
Alistair Veitch6afe53f2015-08-28 14:05:15 -0700419 const char *buffer; /* Buffer (from census_trace_print() */
420 size_t buf_size; /* Number of bytes inside buffer */
421} census_trace_record;
422
423/** Start a scan of existing trace records. While a scan is ongoing, addition
424 of new trace records will be blocked if the underlying trace buffers
425 fill up, so trace processing systems should endeavor to complete
426 reading as soon as possible.
427 @param consume if non-zero, indicates that reading records also "consumes"
428 the previously read record - i.e. releases space in the trace log
429 while scanning is ongoing.
430 @returns 0 on success, non-zero on failure (e.g. if a scan is already ongoing)
431*/
Nicolas "Pixel" Noblecd41a0b2016-02-08 22:53:14 +0100432CENSUSAPI int census_trace_scan_start(int consume);
Alistair Veitch6afe53f2015-08-28 14:05:15 -0700433
434/** Get a trace record. The data pointed to by the trace buffer is guaranteed
435 stable until the next census_get_trace_record() call (if the consume
436 argument to census_trace_scan_start was non-zero) or census_trace_scan_end()
437 is called (otherwise).
438 @param trace_record structure that will be filled in with oldest trace record.
439 @returns -1 if an error occurred (e.g. no previous call to
440 census_trace_scan_start()), 0 if there is no more trace data (and
441 trace_record will not be modified) or 1 otherwise.
442*/
Nicolas "Pixel" Noblecd41a0b2016-02-08 22:53:14 +0100443CENSUSAPI int census_get_trace_record(census_trace_record *trace_record);
Alistair Veitch6afe53f2015-08-28 14:05:15 -0700444
445/** End a scan previously started by census_trace_scan_start() */
Nicolas "Pixel" Noblecd41a0b2016-02-08 22:53:14 +0100446CENSUSAPI void census_trace_scan_end();
Alistair Veitch9686dab2015-05-26 14:26:47 -0700447
Alistair Veitche62f68c2015-08-27 16:24:27 -0700448/* Core stats collection API's. The following concepts are used:
Alistair Veitch9a099822015-08-27 13:16:00 -0700449 * Aggregation: A collection of values. Census supports the following
450 aggregation types:
Alistair Veitchaafe9722015-08-31 13:15:00 -0700451 Sum - a single summation type. Typically used for keeping (e.g.)
Alistair Veitch9a099822015-08-27 13:16:00 -0700452 counts of events.
453 Distribution - statistical distribution information, used for
454 recording average, standard deviation etc.
455 Histogram - a histogram of measurements falling in defined bucket
456 boundaries.
457 Window - a count of events that happen in reolling time window.
458 New aggregation types can be added by the user, if desired (see
459 census_register_aggregation()).
460 * Metric: Each measurement is for a single metric. Examples include RPC
461 latency, CPU seconds consumed, and bytes transmitted.
Alistair Veitchb8552022015-08-28 10:54:17 -0700462 * View: A view is a combination of a metric, a tag set (in which the tag
463 values are regular expressions) and a set of aggregations. When a
464 measurement for a metric matches the view tags, it is recorded (for each
465 unique set of tags) against each aggregation. Each metric can have an
466 arbitrary number of views by which it will be broken down.
Alistair Veitch9a099822015-08-27 13:16:00 -0700467*/
468
469/* A single value to be recorded comprises two parts: an ID for the particular
470 * metric and the value to be recorded against it. */
Alistair Veitch851032a2015-07-20 11:59:13 -0700471typedef struct {
Craig Tiller7536af02015-12-22 13:49:30 -0800472 uint32_t metric_id;
Alistair Veitch851032a2015-07-20 11:59:13 -0700473 double value;
Alistair Veitch9a099822015-08-27 13:16:00 -0700474} census_value;
Alistair Veitch851032a2015-07-20 11:59:13 -0700475
Alistair Veitch9a099822015-08-27 13:16:00 -0700476/* Record new usage values against the given context. */
Nicolas "Pixel" Noblecd41a0b2016-02-08 22:53:14 +0100477CENSUSAPI void census_record_values(census_context *context,
478 census_value *values, size_t nvalues);
Alistair Veitch4d1589a2015-07-17 15:13:04 -0700479
Alistair Veitch1c09acc2015-08-31 16:57:32 -0700480/** Type representing a particular aggregation */
481typedef struct census_aggregation_ops census_aggregation_ops;
Alistair Veitchade00212015-08-25 15:00:26 -0700482
Alistair Veitch1c09acc2015-08-31 16:57:32 -0700483/* Predefined aggregation types, for use with census_view_create(). */
Alistair Veitchaafe9722015-08-31 13:15:00 -0700484extern census_aggregation_ops census_agg_sum;
Alistair Veitcha24148e2015-08-31 08:30:32 -0700485extern census_aggregation_ops census_agg_distribution;
486extern census_aggregation_ops census_agg_histogram;
487extern census_aggregation_ops census_agg_window;
Alistair Veitchade00212015-08-25 15:00:26 -0700488
Alistair Veitch9a099822015-08-27 13:16:00 -0700489/** Information needed to instantiate a new aggregation. Used in view
490 construction via census_define_view(). */
491typedef struct {
Alistair Veitcha24148e2015-08-31 08:30:32 -0700492 const census_aggregation_ops *ops;
Alistair Veitcha628ac92016-02-02 10:02:30 -0800493 const void *create_arg; /* Aaggregation initialization argument. */
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 Veitch75d5c0f2016-02-02 09:43:02 -0800501 @param tags tags that define the view.
Alistair Veitch9a099822015-08-27 13:16:00 -0700502 @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*/
Alistair Veitchddb163a2016-02-02 13:33:44 -0800507
Alistair Veitch75d5c0f2016-02-02 09:43:02 -0800508/* TODO(aveitch): consider if context is the right argument type to pass in
509 tags. */
Nicolas "Pixel" Noblecd41a0b2016-02-08 22:53:14 +0100510CENSUSAPI census_view *census_view_create(
Alistair Veitch2e6c1822016-02-02 09:51:56 -0800511 uint32_t metric_id, const census_context *tags,
512 const census_aggregation *aggregations, size_t naggregations);
Alistair Veitchb8552022015-08-28 10:54:17 -0700513
514/** Destroy a previously created view. */
Nicolas "Pixel" Noblecd41a0b2016-02-08 22:53:14 +0100515CENSUSAPI void census_view_delete(census_view *view);
Alistair Veitchade00212015-08-25 15:00:26 -0700516
Alistair Veitche62f68c2015-08-27 16:24:27 -0700517/** Metric ID associated with a view */
Nicolas "Pixel" Noblecd41a0b2016-02-08 22:53:14 +0100518CENSUSAPI size_t census_view_metric(const census_view *view);
Alistair Veitche62f68c2015-08-27 16:24:27 -0700519
Alistair Veitch9a099822015-08-27 13:16:00 -0700520/** Number of aggregations associated with view. */
Nicolas "Pixel" Noblecd41a0b2016-02-08 22:53:14 +0100521CENSUSAPI size_t census_view_naggregations(const census_view *view);
Alistair Veitchade00212015-08-25 15:00:26 -0700522
Alistair Veitch9a099822015-08-27 13:16:00 -0700523/** Get tags associated with view. */
Nicolas "Pixel" Noblecd41a0b2016-02-08 22:53:14 +0100524CENSUSAPI const census_context *census_view_tags(const census_view *view);
Alistair Veitch9a099822015-08-27 13:16:00 -0700525
Alistair Veitchb8552022015-08-28 10:54:17 -0700526/** Get aggregation descriptors associated with a view. */
Nicolas "Pixel" Noblecd41a0b2016-02-08 22:53:14 +0100527CENSUSAPI const census_aggregation *census_view_aggregrations(
Alistair Veitch2e6c1822016-02-02 09:51:56 -0800528 const census_view *view);
Alistair Veitchade00212015-08-25 15:00:26 -0700529
Alistair Veitch9a099822015-08-27 13:16:00 -0700530/** Holds all the aggregation data for a particular view instantiation. Forms
Alistair Veitchb8552022015-08-28 10:54:17 -0700531 part of the data returned by census_view_data(). */
Alistair Veitch9a099822015-08-27 13:16:00 -0700532typedef struct {
Alistair Veitch75d5c0f2016-02-02 09:43:02 -0800533 const census_context *tags; /* Tags for this set of aggregations. */
Alistair Veitchb8552022015-08-28 10:54:17 -0700534 const void **data; /* One data set for every aggregation in the view. */
Alistair Veitch9a099822015-08-27 13:16:00 -0700535} census_view_aggregation_data;
Alistair Veitchade00212015-08-25 15:00:26 -0700536
Alistair Veitchb8552022015-08-28 10:54:17 -0700537/** Census view data as returned by census_view_get_data(). */
Alistair Veitch9a099822015-08-27 13:16:00 -0700538typedef struct {
Alistair Veitche62f68c2015-08-27 16:24:27 -0700539 size_t n_tag_sets; /* Number of unique tag sets that matched view. */
Alistair Veitch9a099822015-08-27 13:16:00 -0700540 const census_view_aggregation_data *data; /* n_tag_sets entries */
541} census_view_data;
Alistair Veitchade00212015-08-25 15:00:26 -0700542
Alistair Veitch9a099822015-08-27 13:16:00 -0700543/** Get data from aggregations associated with a view.
Alistair Veitche62f68c2015-08-27 16:24:27 -0700544 @param view View from which to get data.
Alistair Veitchb8552022015-08-28 10:54:17 -0700545 @return Full set of data for all aggregations for the view.
Alistair Veitch9a099822015-08-27 13:16:00 -0700546*/
Nicolas "Pixel" Noblecd41a0b2016-02-08 22:53:14 +0100547CENSUSAPI const census_view_data *census_view_get_data(const census_view *view);
Alistair Veitch9a099822015-08-27 13:16:00 -0700548
Alistair Veitchb8552022015-08-28 10:54:17 -0700549/** Reset all view data to zero for the specified view */
Nicolas "Pixel" Noblecd41a0b2016-02-08 22:53:14 +0100550CENSUSAPI void census_view_reset(census_view *view);
Alistair Veitchade00212015-08-25 15:00:26 -0700551
Nicolas "Pixel" Noble1ed15e22015-06-09 02:24:35 +0200552#ifdef __cplusplus
553}
554#endif
555
Alistair Veitch9686dab2015-05-26 14:26:47 -0700556#endif /* CENSUS_CENSUS_H */