Alistair Veitch | 9686dab | 2015-05-26 14:26:47 -0700 | [diff] [blame] | 1 | /* |
| 2 | * |
Alistair Veitch | 4aaba75 | 2016-06-02 17:11:46 -0700 | [diff] [blame] | 3 | * Copyright 2015-2016, Google Inc. |
Alistair Veitch | 9686dab | 2015-05-26 14:26:47 -0700 | [diff] [blame] | 4 | * 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 | |
David Garcia Quintas | 3598d44 | 2016-03-15 14:53:05 -0700 | [diff] [blame] | 38 | #ifndef GRPC_CENSUS_H |
| 39 | #define GRPC_CENSUS_H |
Alistair Veitch | 9686dab | 2015-05-26 14:26:47 -0700 | [diff] [blame] | 40 | |
| 41 | #include <grpc/grpc.h> |
Alistair Veitch | 9686dab | 2015-05-26 14:26:47 -0700 | [diff] [blame] | 42 | |
Nicolas "Pixel" Noble | 1ed15e2 | 2015-06-09 02:24:35 +0200 | [diff] [blame] | 43 | #ifdef __cplusplus |
| 44 | extern "C" { |
| 45 | #endif |
| 46 | |
Alistair Veitch | 925e4a6 | 2015-07-26 16:51:23 -0700 | [diff] [blame] | 47 | /* Identify census features that can be enabled via census_initialize(). */ |
| 48 | enum 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 Veitch | 9686dab | 2015-05-26 14:26:47 -0700 | [diff] [blame] | 55 | }; |
| 56 | |
Alistair Veitch | a4c4d3c | 2015-07-28 14:36:22 -0700 | [diff] [blame] | 57 | /** Shutdown and startup census subsystem. The 'features' argument should be |
Alistair Veitch | 925e4a6 | 2015-07-26 16:51:23 -0700 | [diff] [blame] | 58 | * the OR (|) of census_features values. If census fails to initialize, then |
Alistair Veitch | 4aaba75 | 2016-06-02 17:11:46 -0700 | [diff] [blame] | 59 | * census_initialize() will return -1, otherwise the set of enabled features |
| 60 | * (which may be smaller than that provided in the `features` argument, see |
| 61 | * census_supported()) is returned. It is an error to call census_initialize() |
| 62 | * more than once (without an intervening census_shutdown()). These functions |
| 63 | * are not thread-safe. */ |
Nicolas "Pixel" Noble | cd41a0b | 2016-02-08 22:53:14 +0100 | [diff] [blame] | 64 | CENSUSAPI int census_initialize(int features); |
| 65 | CENSUSAPI void census_shutdown(void); |
Alistair Veitch | 9686dab | 2015-05-26 14:26:47 -0700 | [diff] [blame] | 66 | |
Alistair Veitch | 925e4a6 | 2015-07-26 16:51:23 -0700 | [diff] [blame] | 67 | /** Return the features supported by the current census implementation (not all |
| 68 | * features will be available on all platforms). */ |
Nicolas "Pixel" Noble | cd41a0b | 2016-02-08 22:53:14 +0100 | [diff] [blame] | 69 | CENSUSAPI int census_supported(void); |
Alistair Veitch | 925e4a6 | 2015-07-26 16:51:23 -0700 | [diff] [blame] | 70 | |
| 71 | /** Return the census features currently enabled. */ |
Nicolas "Pixel" Noble | cd41a0b | 2016-02-08 22:53:14 +0100 | [diff] [blame] | 72 | CENSUSAPI int census_enabled(void); |
Alistair Veitch | fc62ddd | 2015-06-29 02:52:46 -0700 | [diff] [blame] | 73 | |
Alistair Veitch | e6d0ad3 | 2015-08-13 09:59:48 -0700 | [diff] [blame] | 74 | /** |
Alistair Veitch | 75d5c0f | 2016-02-02 09:43:02 -0800 | [diff] [blame] | 75 | A Census Context is a handle used by Census to represent the current tracing |
| 76 | and stats collection information. Contexts should be propagated across RPC's |
| 77 | (this is the responsibility of the local RPC system). A context is typically |
| 78 | used as the first argument to most census functions. Conceptually, they |
| 79 | should be thought of as specific to a single RPC/thread. The user visible |
| 80 | context representation is that of a collection of key:value string pairs, |
| 81 | each of which is termed a 'tag'; these form the basis against which Census |
| 82 | metrics will be recorded. Keys are unique within a context. */ |
Alistair Veitch | 9686dab | 2015-05-26 14:26:47 -0700 | [diff] [blame] | 83 | typedef struct census_context census_context; |
| 84 | |
Alistair Veitch | 188563f | 2016-02-25 14:27:44 -0800 | [diff] [blame] | 85 | /* A tag is a key:value pair. Both keys and values are nil-terminated strings, |
| 86 | containing printable ASCII characters (decimal 32-126). Keys must be at |
| 87 | least one character in length. Both keys and values can have at most |
| 88 | CENSUS_MAX_TAG_KB_LEN characters (including the terminating nil). The |
| 89 | maximum number of tags that can be propagated is |
| 90 | CENSUS_MAX_PROPAGATED_TAGS. Users should also remember that some systems |
| 91 | may have limits on, e.g., the number of bytes that can be transmitted as |
| 92 | metadata, and that larger tags means more memory consumed and time in |
| 93 | processing. */ |
Alistair Veitch | 75d5c0f | 2016-02-02 09:43:02 -0800 | [diff] [blame] | 94 | typedef struct { |
| 95 | const char *key; |
| 96 | const char *value; |
Alistair Veitch | 75d5c0f | 2016-02-02 09:43:02 -0800 | [diff] [blame] | 97 | uint8_t flags; |
| 98 | } census_tag; |
| 99 | |
| 100 | /* Maximum length of a tag's key or value. */ |
| 101 | #define CENSUS_MAX_TAG_KV_LEN 255 |
| 102 | /* Maximum number of propagatable tags. */ |
| 103 | #define CENSUS_MAX_PROPAGATED_TAGS 255 |
| 104 | |
| 105 | /* Tag flags. */ |
| 106 | #define CENSUS_TAG_PROPAGATE 1 /* Tag should be propagated over RPC */ |
| 107 | #define CENSUS_TAG_STATS 2 /* Tag will be used for statistics aggregation */ |
Alistair Veitch | 188563f | 2016-02-25 14:27:44 -0800 | [diff] [blame] | 108 | #define CENSUS_TAG_RESERVED 4 /* Reserved for internal use. */ |
| 109 | /* Flag values 4,8,16,32,64,128 are reserved for future/internal use. Clients |
Alistair Veitch | 75d5c0f | 2016-02-02 09:43:02 -0800 | [diff] [blame] | 110 | should not use or rely on their values. */ |
| 111 | |
| 112 | #define CENSUS_TAG_IS_PROPAGATED(flags) (flags & CENSUS_TAG_PROPAGATE) |
| 113 | #define CENSUS_TAG_IS_STATS(flags) (flags & CENSUS_TAG_STATS) |
Alistair Veitch | 75d5c0f | 2016-02-02 09:43:02 -0800 | [diff] [blame] | 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. */ |
| 117 | typedef struct { |
Alistair Veitch | 188563f | 2016-02-25 14:27:44 -0800 | [diff] [blame] | 118 | int n_propagated_tags; /* number of propagated tags */ |
| 119 | int n_local_tags; /* number of non-propagated (local) tags */ |
| 120 | int n_deleted_tags; /* number of tags that were deleted */ |
| 121 | int n_added_tags; /* number of tags that were added */ |
| 122 | int n_modified_tags; /* number of tags that were modified */ |
| 123 | int n_invalid_tags; /* number of tags with bad keys or values (e.g. |
| 124 | longer than CENSUS_MAX_TAG_KV_LEN) */ |
| 125 | int n_ignored_tags; /* number of tags ignored because of |
| 126 | CENSUS_MAX_PROPAGATED_TAGS limit. */ |
Alistair Veitch | 75d5c0f | 2016-02-02 09:43:02 -0800 | [diff] [blame] | 127 | } census_context_status; |
| 128 | |
| 129 | /* Create a new context, adding and removing tags from an existing context. |
| 130 | This will copy all tags from the 'tags' input, so it is recommended |
| 131 | to add as many tags in a single operation as is practical for the client. |
| 132 | @param base Base context to build upon. Can be NULL. |
| 133 | @param tags A set of tags to be added/changed/deleted. Tags with keys that |
Alistair Veitch | 188563f | 2016-02-25 14:27:44 -0800 | [diff] [blame] | 134 | are in 'tags', but not 'base', are added to the context. Keys that are in |
Alistair Veitch | 75d5c0f | 2016-02-02 09:43:02 -0800 | [diff] [blame] | 135 | both 'tags' and 'base' will have their value/flags modified. Tags with keys |
Alistair Veitch | 188563f | 2016-02-25 14:27:44 -0800 | [diff] [blame] | 136 | in both, but with NULL values, will be deleted from the context. Tags with |
| 137 | invalid (too long or short) keys or values will be ignored. |
Alistair Veitch | 75d5c0f | 2016-02-02 09:43:02 -0800 | [diff] [blame] | 138 | If adding a tag will result in more than CENSUS_MAX_PROPAGATED_TAGS in either |
| 139 | binary or non-binary tags, they will be ignored, as will deletions of |
| 140 | tags that don't exist. |
| 141 | @param ntags number of tags in 'tags' |
| 142 | @param status If not NULL, will return a pointer to a census_context_status |
| 143 | structure containing information about the new context and status of the |
| 144 | tags used in its creation. |
| 145 | @return A new, valid census_context. |
| 146 | */ |
Nicolas "Pixel" Noble | cd41a0b | 2016-02-08 22:53:14 +0100 | [diff] [blame] | 147 | CENSUSAPI census_context *census_context_create( |
Alistair Veitch | 2e6c182 | 2016-02-02 09:51:56 -0800 | [diff] [blame] | 148 | const census_context *base, const census_tag *tags, int ntags, |
| 149 | census_context_status const **status); |
Alistair Veitch | 75d5c0f | 2016-02-02 09:43:02 -0800 | [diff] [blame] | 150 | |
| 151 | /* Destroy a context. Once this function has been called, the context cannot |
| 152 | be reused. */ |
Nicolas "Pixel" Noble | cd41a0b | 2016-02-08 22:53:14 +0100 | [diff] [blame] | 153 | CENSUSAPI void census_context_destroy(census_context *context); |
Alistair Veitch | 75d5c0f | 2016-02-02 09:43:02 -0800 | [diff] [blame] | 154 | |
| 155 | /* Get a pointer to the original status from the context creation. */ |
Nicolas "Pixel" Noble | cd41a0b | 2016-02-08 22:53:14 +0100 | [diff] [blame] | 156 | CENSUSAPI const census_context_status *census_context_get_status( |
Alistair Veitch | 75d5c0f | 2016-02-02 09:43:02 -0800 | [diff] [blame] | 157 | const census_context *context); |
| 158 | |
Kristen Kozak | 40c5974 | 2016-08-02 14:12:18 -0700 | [diff] [blame] | 159 | /* Structure used for iterating over the tags in a context. API clients should |
Alistair Veitch | 75d5c0f | 2016-02-02 09:43:02 -0800 | [diff] [blame] | 160 | not use or reference internal fields - neither their contents or |
| 161 | presence/absence are guaranteed. */ |
| 162 | typedef struct { |
| 163 | const census_context *context; |
| 164 | int base; |
| 165 | int index; |
| 166 | char *kvm; |
| 167 | } census_context_iterator; |
| 168 | |
| 169 | /* Initialize a census_tag_iterator. Must be called before first use. */ |
Nicolas "Pixel" Noble | cd41a0b | 2016-02-08 22:53:14 +0100 | [diff] [blame] | 170 | CENSUSAPI void census_context_initialize_iterator( |
Alistair Veitch | 2e6c182 | 2016-02-02 09:51:56 -0800 | [diff] [blame] | 171 | const census_context *context, census_context_iterator *iterator); |
Alistair Veitch | 75d5c0f | 2016-02-02 09:43:02 -0800 | [diff] [blame] | 172 | |
| 173 | /* Get the contents of the "next" tag in the context. If there are no more |
| 174 | tags, returns 0 (and 'tag' contents will be unchanged), otherwise returns 1. |
| 175 | */ |
Nicolas "Pixel" Noble | cd41a0b | 2016-02-08 22:53:14 +0100 | [diff] [blame] | 176 | CENSUSAPI int census_context_next_tag(census_context_iterator *iterator, |
| 177 | census_tag *tag); |
Alistair Veitch | 75d5c0f | 2016-02-02 09:43:02 -0800 | [diff] [blame] | 178 | |
| 179 | /* Get a context tag by key. Returns 0 if the key is not present. */ |
Nicolas "Pixel" Noble | cd41a0b | 2016-02-08 22:53:14 +0100 | [diff] [blame] | 180 | CENSUSAPI int census_context_get_tag(const census_context *context, |
| 181 | const char *key, census_tag *tag); |
Alistair Veitch | 75d5c0f | 2016-02-02 09:43:02 -0800 | [diff] [blame] | 182 | |
Kristen Kozak | 40c5974 | 2016-08-02 14:12:18 -0700 | [diff] [blame] | 183 | /* Tag set encode/decode functionality. These functions are intended |
Alistair Veitch | 75d5c0f | 2016-02-02 09:43:02 -0800 | [diff] [blame] | 184 | for use by RPC systems only, for purposes of transmitting/receiving contexts. |
| 185 | */ |
| 186 | |
Alistair Veitch | 188563f | 2016-02-25 14:27:44 -0800 | [diff] [blame] | 187 | /* Encode a context into a buffer. |
Alistair Veitch | 75d5c0f | 2016-02-02 09:43:02 -0800 | [diff] [blame] | 188 | @param context context to be encoded |
Alistair Veitch | 188563f | 2016-02-25 14:27:44 -0800 | [diff] [blame] | 189 | @param buffer buffer into which the context will be encoded. |
Alistair Veitch | 75d5c0f | 2016-02-02 09:43:02 -0800 | [diff] [blame] | 190 | @param buf_size number of available bytes in buffer. |
Alistair Veitch | 188563f | 2016-02-25 14:27:44 -0800 | [diff] [blame] | 191 | @return The number of buffer bytes consumed for the encoded context, or |
| 192 | zero if the buffer was of insufficient size. */ |
| 193 | CENSUSAPI size_t census_context_encode(const census_context *context, |
| 194 | char *buffer, size_t buf_size); |
Alistair Veitch | 75d5c0f | 2016-02-02 09:43:02 -0800 | [diff] [blame] | 195 | |
Alistair Veitch | 188563f | 2016-02-25 14:27:44 -0800 | [diff] [blame] | 196 | /* Decode context buffer encoded with census_context_encode(). Returns NULL |
Alistair Veitch | 75d5c0f | 2016-02-02 09:43:02 -0800 | [diff] [blame] | 197 | if there is an error in parsing either buffer. */ |
Alistair Veitch | 188563f | 2016-02-25 14:27:44 -0800 | [diff] [blame] | 198 | CENSUSAPI census_context *census_context_decode(const char *buffer, |
| 199 | size_t size); |
Alistair Veitch | 9686dab | 2015-05-26 14:26:47 -0700 | [diff] [blame] | 200 | |
Alistair Veitch | af5002f | 2015-07-26 15:11:50 -0700 | [diff] [blame] | 201 | /* Distributed traces can have a number of options. */ |
| 202 | enum census_trace_mask_values { |
Alistair Veitch | 0383d49 | 2015-07-26 15:29:00 -0700 | [diff] [blame] | 203 | CENSUS_TRACE_MASK_NONE = 0, /* Default, empty flags */ |
| 204 | CENSUS_TRACE_MASK_IS_SAMPLED = 1 /* RPC tracing enabled for this context. */ |
Alistair Veitch | af5002f | 2015-07-26 15:11:50 -0700 | [diff] [blame] | 205 | }; |
Alistair Veitch | 9686dab | 2015-05-26 14:26:47 -0700 | [diff] [blame] | 206 | |
Alistair Veitch | af5002f | 2015-07-26 15:11:50 -0700 | [diff] [blame] | 207 | /** Get the current trace mask associated with this context. The value returned |
Kristen Kozak | 40c5974 | 2016-08-02 14:12:18 -0700 | [diff] [blame] | 208 | will be the logical OR of census_trace_mask_values values. */ |
Nicolas "Pixel" Noble | cd41a0b | 2016-02-08 22:53:14 +0100 | [diff] [blame] | 209 | CENSUSAPI int census_trace_mask(const census_context *context); |
Alistair Veitch | 491a9d4 | 2015-07-21 10:08:37 -0700 | [diff] [blame] | 210 | |
Alistair Veitch | e6d0ad3 | 2015-08-13 09:59:48 -0700 | [diff] [blame] | 211 | /** Set the trace mask associated with a context. */ |
Nicolas "Pixel" Noble | cd41a0b | 2016-02-08 22:53:14 +0100 | [diff] [blame] | 212 | CENSUSAPI void census_set_trace_mask(int trace_mask); |
Alistair Veitch | e6d0ad3 | 2015-08-13 09:59:48 -0700 | [diff] [blame] | 213 | |
| 214 | /* The concept of "operation" is a fundamental concept for Census. In an RPC |
Kristen Kozak | 40c5974 | 2016-08-02 14:12:18 -0700 | [diff] [blame] | 215 | system, an operation typically represents a single RPC, or a significant |
Alistair Veitch | e6d0ad3 | 2015-08-13 09:59:48 -0700 | [diff] [blame] | 216 | sub-part thereof (e.g. a single logical "read" RPC to a distributed storage |
| 217 | system might do several other actions in parallel, from looking up metadata |
Alistair Veitch | af5002f | 2015-07-26 15:11:50 -0700 | [diff] [blame] | 218 | indices to making requests of other services - each of these could be a |
Alistair Veitch | e6d0ad3 | 2015-08-13 09:59:48 -0700 | [diff] [blame] | 219 | sub-operation with the larger RPC operation). Census uses operations for the |
Alistair Veitch | af5002f | 2015-07-26 15:11:50 -0700 | [diff] [blame] | 220 | following: |
Alistair Veitch | 491a9d4 | 2015-07-21 10:08:37 -0700 | [diff] [blame] | 221 | |
Alistair Veitch | af5002f | 2015-07-26 15:11:50 -0700 | [diff] [blame] | 222 | CPU accounting: If enabled, census will measure the thread CPU time |
| 223 | consumed between operation start and end times. |
| 224 | |
| 225 | Active operations: Census will maintain information on all currently |
| 226 | active operations. |
| 227 | |
| 228 | Distributed tracing: Each operation serves as a logical trace span. |
| 229 | |
Alistair Veitch | e6d0ad3 | 2015-08-13 09:59:48 -0700 | [diff] [blame] | 230 | Stats collection: Stats are broken down by operation (e.g. latency |
| 231 | breakdown for each unique RPC path). |
Alistair Veitch | af5002f | 2015-07-26 15:11:50 -0700 | [diff] [blame] | 232 | |
| 233 | The following functions serve to delineate the start and stop points for |
| 234 | each logical operation. */ |
Alistair Veitch | e6d0ad3 | 2015-08-13 09:59:48 -0700 | [diff] [blame] | 235 | |
Alistair Veitch | af5002f | 2015-07-26 15:11:50 -0700 | [diff] [blame] | 236 | /** |
Alistair Veitch | f886985 | 2015-08-25 15:24:49 -0700 | [diff] [blame] | 237 | This structure represents a timestamp as used by census to record the time |
| 238 | at which an operation begins. |
Alistair Veitch | e6d0ad3 | 2015-08-13 09:59:48 -0700 | [diff] [blame] | 239 | */ |
Alistair Veitch | f886985 | 2015-08-25 15:24:49 -0700 | [diff] [blame] | 240 | typedef struct { |
| 241 | /* Use gpr_timespec for default implementation. High performance |
| 242 | * implementations should use a cycle-counter based timestamp. */ |
| 243 | gpr_timespec ts; |
| 244 | } census_timestamp; |
Alistair Veitch | e6d0ad3 | 2015-08-13 09:59:48 -0700 | [diff] [blame] | 245 | |
| 246 | /** |
| 247 | Mark the beginning of an RPC operation. The information required to call the |
| 248 | functions to record the start of RPC operations (both client and server) may |
| 249 | not be callable at the true start time of the operation, due to information |
| 250 | not being available (e.g. the census context data will not be available in a |
| 251 | server RPC until at least initial metadata has been processed). To ensure |
| 252 | correct CPU accounting and latency recording, RPC systems can call this |
| 253 | function to get the timestamp of operation beginning. This can later be used |
| 254 | as an argument to census_start_{client,server}_rpc_op(). NB: for correct |
| 255 | CPU accounting, the system must guarantee that the same thread is used |
| 256 | for all request processing after this function is called. |
| 257 | |
| 258 | @return A timestamp representing the operation start time. |
| 259 | */ |
Nicolas "Pixel" Noble | cd41a0b | 2016-02-08 22:53:14 +0100 | [diff] [blame] | 260 | CENSUSAPI census_timestamp census_start_rpc_op_timestamp(void); |
Alistair Veitch | e6d0ad3 | 2015-08-13 09:59:48 -0700 | [diff] [blame] | 261 | |
| 262 | /** |
| 263 | Represent functions to map RPC name ID to service/method names. Census |
| 264 | breaks down all RPC stats by service and method names. We leave the |
| 265 | definition and format of these to the RPC system. For efficiency purposes, |
| 266 | we encode these as a single 64 bit identifier, and allow the RPC system to |
| 267 | provide a structure for functions that can convert these to service and |
| 268 | method strings. |
| 269 | |
| 270 | TODO(aveitch): Instead of providing this as an argument to the rpc_start_op() |
| 271 | functions, maybe it should be set once at census initialization. |
| 272 | */ |
| 273 | typedef struct { |
Craig Tiller | 7536af0 | 2015-12-22 13:49:30 -0800 | [diff] [blame] | 274 | const char *(*get_rpc_service_name)(int64_t id); |
| 275 | const char *(*get_rpc_method_name)(int64_t id); |
Alistair Veitch | e6d0ad3 | 2015-08-13 09:59:48 -0700 | [diff] [blame] | 276 | } census_rpc_name_info; |
| 277 | |
| 278 | /** |
| 279 | Start a client rpc operation. This function should be called as early in the |
| 280 | client RPC path as possible. This function will create a new context. If |
Alistair Veitch | af5002f | 2015-07-26 15:11:50 -0700 | [diff] [blame] | 281 | the context argument is non-null, then the new context will inherit all |
| 282 | its properties, with the following changes: |
| 283 | - create a new operation ID for the new context, marking it as a child of |
| 284 | the previous operation. |
Alistair Veitch | e6d0ad3 | 2015-08-13 09:59:48 -0700 | [diff] [blame] | 285 | - use the new RPC path and peer information for tracing and stats |
Alistair Veitch | af5002f | 2015-07-26 15:11:50 -0700 | [diff] [blame] | 286 | collection purposes, rather than those from the original context |
Alistair Veitch | af5002f | 2015-07-26 15:11:50 -0700 | [diff] [blame] | 287 | |
Alistair Veitch | e6d0ad3 | 2015-08-13 09:59:48 -0700 | [diff] [blame] | 288 | If the context argument is NULL, then a new root context is created. This |
Alistair Veitch | af5002f | 2015-07-26 15:11:50 -0700 | [diff] [blame] | 289 | is particularly important for tracing purposes (the trace spans generated |
| 290 | will be unassociated with any other trace spans, except those |
Alistair Veitch | e6d0ad3 | 2015-08-13 09:59:48 -0700 | [diff] [blame] | 291 | downstream). The trace_mask will be used for tracing operations associated |
| 292 | with the new context. |
Alistair Veitch | af5002f | 2015-07-26 15:11:50 -0700 | [diff] [blame] | 293 | |
Alistair Veitch | e6d0ad3 | 2015-08-13 09:59:48 -0700 | [diff] [blame] | 294 | In some RPC systems (e.g. where load balancing is used), peer information |
| 295 | may not be available at the time the operation starts. In this case, use a |
| 296 | NULL value for peer, and set it later using the |
| 297 | census_set_rpc_client_peer() function. |
| 298 | |
| 299 | @param context The parent context. Can be NULL. |
| 300 | @param rpc_name_id The rpc name identifier to be associated with this RPC. |
| 301 | @param rpc_name_info Used to decode rpc_name_id. |
| 302 | @param peer RPC peer. If not available at the time, NULL can be used, |
| 303 | and a later census_set_rpc_client_peer() call made. |
| 304 | @param trace_mask An OR of census_trace_mask_values values. Only used in |
| 305 | the creation of a new root context (context == NULL). |
| 306 | @param start_time A timestamp returned from census_start_rpc_op_timestamp(). |
| 307 | Can be NULL. Used to set the true time the operation |
| 308 | begins. |
Alistair Veitch | af5002f | 2015-07-26 15:11:50 -0700 | [diff] [blame] | 309 | |
| 310 | @return A new census context. |
| 311 | */ |
Nicolas "Pixel" Noble | cd41a0b | 2016-02-08 22:53:14 +0100 | [diff] [blame] | 312 | CENSUSAPI census_context *census_start_client_rpc_op( |
Craig Tiller | 7536af0 | 2015-12-22 13:49:30 -0800 | [diff] [blame] | 313 | const census_context *context, int64_t rpc_name_id, |
Alistair Veitch | e6d0ad3 | 2015-08-13 09:59:48 -0700 | [diff] [blame] | 314 | const census_rpc_name_info *rpc_name_info, const char *peer, int trace_mask, |
| 315 | const census_timestamp *start_time); |
Alistair Veitch | af5002f | 2015-07-26 15:11:50 -0700 | [diff] [blame] | 316 | |
| 317 | /** |
Alistair Veitch | e6d0ad3 | 2015-08-13 09:59:48 -0700 | [diff] [blame] | 318 | Add peer information to a context representing a client RPC operation. |
| 319 | */ |
Nicolas "Pixel" Noble | cd41a0b | 2016-02-08 22:53:14 +0100 | [diff] [blame] | 320 | CENSUSAPI void census_set_rpc_client_peer(census_context *context, |
| 321 | const char *peer); |
Alistair Veitch | af5002f | 2015-07-26 15:11:50 -0700 | [diff] [blame] | 322 | |
Alistair Veitch | e6d0ad3 | 2015-08-13 09:59:48 -0700 | [diff] [blame] | 323 | /** |
| 324 | Start a server RPC operation. Returns a new context to be used in future |
| 325 | census calls. If buffer is non-NULL, then the buffer contents should |
| 326 | represent the client context, as generated by census_context_serialize(). |
| 327 | If buffer is NULL, a new root context is created. |
| 328 | |
| 329 | @param buffer Buffer containing bytes output from census_context_serialize(). |
| 330 | @param rpc_name_id The rpc name identifier to be associated with this RPC. |
| 331 | @param rpc_name_info Used to decode rpc_name_id. |
| 332 | @param peer RPC peer. |
| 333 | @param trace_mask An OR of census_trace_mask_values values. Only used in |
| 334 | the creation of a new root context (buffer == NULL). |
| 335 | @param start_time A timestamp returned from census_start_rpc_op_timestamp(). |
| 336 | Can be NULL. Used to set the true time the operation |
| 337 | begins. |
| 338 | |
| 339 | @return A new census context. |
Alistair Veitch | af5002f | 2015-07-26 15:11:50 -0700 | [diff] [blame] | 340 | */ |
Nicolas "Pixel" Noble | cd41a0b | 2016-02-08 22:53:14 +0100 | [diff] [blame] | 341 | CENSUSAPI census_context *census_start_server_rpc_op( |
Craig Tiller | 7536af0 | 2015-12-22 13:49:30 -0800 | [diff] [blame] | 342 | const char *buffer, int64_t rpc_name_id, |
Alistair Veitch | e6d0ad3 | 2015-08-13 09:59:48 -0700 | [diff] [blame] | 343 | const census_rpc_name_info *rpc_name_info, const char *peer, int trace_mask, |
| 344 | census_timestamp *start_time); |
Alistair Veitch | af5002f | 2015-07-26 15:11:50 -0700 | [diff] [blame] | 345 | |
| 346 | /** |
Alistair Veitch | e6d0ad3 | 2015-08-13 09:59:48 -0700 | [diff] [blame] | 347 | Start a new, non-RPC operation. In general, this function works very |
| 348 | similarly to census_start_client_rpc_op, with the primary difference being |
| 349 | the replacement of host/path information with the more generic family/name |
| 350 | tags. If the context argument is non-null, then the new context will |
| 351 | inherit all its properties, with the following changes: |
Alistair Veitch | af5002f | 2015-07-26 15:11:50 -0700 | [diff] [blame] | 352 | - create a new operation ID for the new context, marking it as a child of |
| 353 | the previous operation. |
| 354 | - use the family and name information for tracing and stats collection |
| 355 | purposes, rather than those from the original context |
Alistair Veitch | af5002f | 2015-07-26 15:11:50 -0700 | [diff] [blame] | 356 | |
Alistair Veitch | e6d0ad3 | 2015-08-13 09:59:48 -0700 | [diff] [blame] | 357 | If the context argument is NULL, then a new root context is created. This |
Alistair Veitch | af5002f | 2015-07-26 15:11:50 -0700 | [diff] [blame] | 358 | is particularly important for tracing purposes (the trace spans generated |
| 359 | will be unassociated with any other trace spans, except those |
Alistair Veitch | e6d0ad3 | 2015-08-13 09:59:48 -0700 | [diff] [blame] | 360 | downstream). The trace_mask will be used for tracing |
Alistair Veitch | af5002f | 2015-07-26 15:11:50 -0700 | [diff] [blame] | 361 | operations associated with the new context. |
| 362 | |
| 363 | @param context The base context. Can be NULL. |
| 364 | @param family Family name to associate with the trace |
Kristen Kozak | 40c5974 | 2016-08-02 14:12:18 -0700 | [diff] [blame] | 365 | @param name Name within family to associate with traces/stats |
Alistair Veitch | e6d0ad3 | 2015-08-13 09:59:48 -0700 | [diff] [blame] | 366 | @param trace_mask An OR of census_trace_mask_values values. Only used if |
| 367 | context is NULL. |
Alistair Veitch | af5002f | 2015-07-26 15:11:50 -0700 | [diff] [blame] | 368 | |
| 369 | @return A new census context. |
| 370 | */ |
Nicolas "Pixel" Noble | cd41a0b | 2016-02-08 22:53:14 +0100 | [diff] [blame] | 371 | CENSUSAPI census_context *census_start_op(census_context *context, |
| 372 | const char *family, const char *name, |
| 373 | int trace_mask); |
Alistair Veitch | af5002f | 2015-07-26 15:11:50 -0700 | [diff] [blame] | 374 | |
Alistair Veitch | 0879df2 | 2015-08-13 14:32:05 -0700 | [diff] [blame] | 375 | /** |
| 376 | End an operation started by any of the census_start_*_op*() calls. The |
| 377 | context used in this call will no longer be valid once this function |
| 378 | completes. |
| 379 | |
| 380 | @param context Context associated with operation which is ending. |
| 381 | @param status status associated with the operation. Not interpreted by |
| 382 | census. |
| 383 | */ |
Nicolas "Pixel" Noble | cd41a0b | 2016-02-08 22:53:14 +0100 | [diff] [blame] | 384 | CENSUSAPI void census_end_op(census_context *context, int status); |
Alistair Veitch | af5002f | 2015-07-26 15:11:50 -0700 | [diff] [blame] | 385 | |
Craig Tiller | 7536af0 | 2015-12-22 13:49:30 -0800 | [diff] [blame] | 386 | #define CENSUS_TRACE_RECORD_START_OP ((uint32_t)0) |
| 387 | #define CENSUS_TRACE_RECORD_END_OP ((uint32_t)1) |
Alistair Veitch | 6afe53f | 2015-08-28 14:05:15 -0700 | [diff] [blame] | 388 | |
Alistair Veitch | af5002f | 2015-07-26 15:11:50 -0700 | [diff] [blame] | 389 | /** Insert a trace record into the trace stream. The record consists of an |
Alistair Veitch | 6afe53f | 2015-08-28 14:05:15 -0700 | [diff] [blame] | 390 | arbitrary size buffer, the size of which is provided in 'n'. |
| 391 | @param context Trace context |
| 392 | @param type User-defined type to associate with trace entry. |
| 393 | @param buffer Pointer to buffer to use |
| 394 | @param n Number of bytes in buffer |
| 395 | */ |
Nicolas "Pixel" Noble | cd41a0b | 2016-02-08 22:53:14 +0100 | [diff] [blame] | 396 | CENSUSAPI void census_trace_print(census_context *context, uint32_t type, |
| 397 | const char *buffer, size_t n); |
Alistair Veitch | 6afe53f | 2015-08-28 14:05:15 -0700 | [diff] [blame] | 398 | |
| 399 | /** Trace record. */ |
| 400 | typedef struct { |
| 401 | census_timestamp timestamp; /* Time of record creation */ |
Craig Tiller | 7536af0 | 2015-12-22 13:49:30 -0800 | [diff] [blame] | 402 | uint64_t trace_id; /* Trace ID associated with record */ |
| 403 | uint64_t op_id; /* Operation ID associated with record */ |
| 404 | uint32_t type; /* Type (as used in census_trace_print() */ |
Alistair Veitch | 6afe53f | 2015-08-28 14:05:15 -0700 | [diff] [blame] | 405 | const char *buffer; /* Buffer (from census_trace_print() */ |
| 406 | size_t buf_size; /* Number of bytes inside buffer */ |
| 407 | } census_trace_record; |
| 408 | |
| 409 | /** Start a scan of existing trace records. While a scan is ongoing, addition |
| 410 | of new trace records will be blocked if the underlying trace buffers |
| 411 | fill up, so trace processing systems should endeavor to complete |
| 412 | reading as soon as possible. |
| 413 | @param consume if non-zero, indicates that reading records also "consumes" |
| 414 | the previously read record - i.e. releases space in the trace log |
| 415 | while scanning is ongoing. |
| 416 | @returns 0 on success, non-zero on failure (e.g. if a scan is already ongoing) |
| 417 | */ |
Nicolas "Pixel" Noble | cd41a0b | 2016-02-08 22:53:14 +0100 | [diff] [blame] | 418 | CENSUSAPI int census_trace_scan_start(int consume); |
Alistair Veitch | 6afe53f | 2015-08-28 14:05:15 -0700 | [diff] [blame] | 419 | |
| 420 | /** Get a trace record. The data pointed to by the trace buffer is guaranteed |
| 421 | stable until the next census_get_trace_record() call (if the consume |
| 422 | argument to census_trace_scan_start was non-zero) or census_trace_scan_end() |
| 423 | is called (otherwise). |
| 424 | @param trace_record structure that will be filled in with oldest trace record. |
| 425 | @returns -1 if an error occurred (e.g. no previous call to |
| 426 | census_trace_scan_start()), 0 if there is no more trace data (and |
| 427 | trace_record will not be modified) or 1 otherwise. |
| 428 | */ |
Nicolas "Pixel" Noble | cd41a0b | 2016-02-08 22:53:14 +0100 | [diff] [blame] | 429 | CENSUSAPI int census_get_trace_record(census_trace_record *trace_record); |
Alistair Veitch | 6afe53f | 2015-08-28 14:05:15 -0700 | [diff] [blame] | 430 | |
| 431 | /** End a scan previously started by census_trace_scan_start() */ |
Nicolas "Pixel" Noble | cd41a0b | 2016-02-08 22:53:14 +0100 | [diff] [blame] | 432 | CENSUSAPI void census_trace_scan_end(); |
Alistair Veitch | 9686dab | 2015-05-26 14:26:47 -0700 | [diff] [blame] | 433 | |
Alistair Veitch | e62f68c | 2015-08-27 16:24:27 -0700 | [diff] [blame] | 434 | /* Core stats collection API's. The following concepts are used: |
Alistair Veitch | 4aaba75 | 2016-06-02 17:11:46 -0700 | [diff] [blame] | 435 | * Resource: Users record measurements for a single resource. Examples |
| 436 | include RPC latency, CPU seconds consumed, and bytes transmitted. |
| 437 | * Aggregation: An aggregation of a set of measurements. Census supports the |
| 438 | following aggregation types: |
| 439 | * Distribution - statistical distribution information, used for |
| 440 | recording average, standard deviation etc. Can include a histogram. |
| 441 | * Interval - a count of events that happen in a rolling time window. |
| 442 | * View: A view is a combination of a Resource, a set of tag keys and an |
| 443 | Aggregation. When a measurement for a Resource matches the View tags, it is |
| 444 | recorded (for each unique set of tag values) using the Aggregation type. |
| 445 | Each resource can have an arbitrary number of views by which it will be |
| 446 | broken down. |
| 447 | |
| 448 | Census uses protos to define each of the above, and output results. This |
| 449 | ensures unification across the different language and runtime |
| 450 | implementations. The proto definitions can be found in src/proto/census. |
Alistair Veitch | 9a09982 | 2015-08-27 13:16:00 -0700 | [diff] [blame] | 451 | */ |
| 452 | |
Alistair Veitch | 4aaba75 | 2016-06-02 17:11:46 -0700 | [diff] [blame] | 453 | /* Define a new resource. `resource_pb` should contain an encoded Resource |
| 454 | protobuf, `resource_pb_size` being the size of the buffer. Returns a -ve |
| 455 | value on error, or a positive (>= 0) resource id (for use in |
| 456 | census_delete_resource() and census_record_values()). In order to be valid, a |
Kristen Kozak | 40c5974 | 2016-08-02 14:12:18 -0700 | [diff] [blame] | 457 | resource must have a name, and at least one numerator in its unit type. The |
Alistair Veitch | 4aaba75 | 2016-06-02 17:11:46 -0700 | [diff] [blame] | 458 | resource name must be unique, and an error will be returned if it is not. */ |
| 459 | CENSUSAPI int32_t census_define_resource(const uint8_t *resource_pb, |
| 460 | size_t resource_pb_size); |
| 461 | |
| 462 | /* Delete a resource created by census_define_resource(). */ |
| 463 | CENSUSAPI void census_delete_resource(int32_t resource_id); |
| 464 | |
Kristen Kozak | 40c5974 | 2016-08-02 14:12:18 -0700 | [diff] [blame] | 465 | /* Determine the id of a resource, given its name. returns -1 if the resource |
Alistair Veitch | 4aaba75 | 2016-06-02 17:11:46 -0700 | [diff] [blame] | 466 | does not exist. */ |
| 467 | CENSUSAPI int32_t census_resource_id(const char *name); |
| 468 | |
Alistair Veitch | 9a09982 | 2015-08-27 13:16:00 -0700 | [diff] [blame] | 469 | /* A single value to be recorded comprises two parts: an ID for the particular |
Alistair Veitch | 4aaba75 | 2016-06-02 17:11:46 -0700 | [diff] [blame] | 470 | * resource and the value to be recorded against it. */ |
Alistair Veitch | 851032a | 2015-07-20 11:59:13 -0700 | [diff] [blame] | 471 | typedef struct { |
Alistair Veitch | 4aaba75 | 2016-06-02 17:11:46 -0700 | [diff] [blame] | 472 | int32_t resource_id; |
Alistair Veitch | 851032a | 2015-07-20 11:59:13 -0700 | [diff] [blame] | 473 | double value; |
Alistair Veitch | 9a09982 | 2015-08-27 13:16:00 -0700 | [diff] [blame] | 474 | } census_value; |
Alistair Veitch | 851032a | 2015-07-20 11:59:13 -0700 | [diff] [blame] | 475 | |
Alistair Veitch | 9a09982 | 2015-08-27 13:16:00 -0700 | [diff] [blame] | 476 | /* Record new usage values against the given context. */ |
Nicolas "Pixel" Noble | cd41a0b | 2016-02-08 22:53:14 +0100 | [diff] [blame] | 477 | CENSUSAPI void census_record_values(census_context *context, |
| 478 | census_value *values, size_t nvalues); |
Alistair Veitch | 4d1589a | 2015-07-17 15:13:04 -0700 | [diff] [blame] | 479 | |
Nicolas "Pixel" Noble | 1ed15e2 | 2015-06-09 02:24:35 +0200 | [diff] [blame] | 480 | #ifdef __cplusplus |
| 481 | } |
| 482 | #endif |
| 483 | |
David Garcia Quintas | 3598d44 | 2016-03-15 14:53:05 -0700 | [diff] [blame] | 484 | #endif /* GRPC_CENSUS_H */ |