Created
August 20, 2020 18:33
-
-
Save mystor/3c979b1a903986b2d30c2f74bfe4d6e8 to your computer and use it in GitHub Desktop.
RFC: tracing-core C FFI proposal
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef tracing_core_h | |
#define tracing_core_h | |
#include <stdbool.h> | |
#include <stdint.h> | |
#ifdef __cplusplus | |
extern "C" { | |
#endif | |
typedef struct tracing_metadata tracing_metadata; | |
typedef uint32_t tracing_id_t; | |
#define TRACING_ID_INVALID ((tracing_id_t)0) | |
typedef struct { | |
const char *value; /**< must contain valid UTF-8 */ | |
uintptr_t len; | |
} tracing_str; | |
typedef enum { | |
TRACING_LEVEL_TRACE = 0, | |
TRACING_LEVEL_DEBUG = 1, | |
TRACING_LEVEL_INFO = 2, | |
TRACING_LEVEL_WARN = 3, | |
TRACING_LEVEL_ERROR = 4, | |
} tracing_level_t; | |
typedef enum { | |
TRACING_KIND_EVENT = 0, | |
TRACING_KIND_SPAN = 1, | |
} tracing_kind_t; | |
typedef enum { | |
TRACING_INTEREST_NEVER = 0, | |
TRACING_INTEREST_SOMETIMES = 1, | |
TRACING_INTEREST_ALWAYS = 2, | |
} tracing_interest_t; | |
typedef struct { | |
uint32_t version; /**< version for the struct */ | |
void (*set_interest)(void *, tracing_interest_t); | |
const tracing_metadata *(*get_metadata)(void *); | |
} tracing_callsite_vtable; | |
#define TRACING_CALLSITE_VTABLE_VERSION 1 | |
typedef struct { | |
void *callsite; | |
const tracing_callsite_vtable *vtable; | |
} tracing_callsite_ref; | |
typedef struct { | |
/** names of key-value fields attached to the described span or event. */ | |
const tracing_str *names; | |
uintptr_t names_len; | |
tracing_callsite_ref callsite; | |
} tracing_field_set; | |
typedef struct { | |
uintptr_t field_index; /**< Index of field in field_set */ | |
tracing_str value_repr; /**< Debug repr of value */ | |
} tracing_field_value; | |
/** | |
* C reflection of the Tracing `tracing_core::metadata::Metadata` struct. | |
*/ | |
struct tracing_metadata { | |
uint32_t version; /**< version for the struct. */ | |
/** | |
* Kind of the callsite. | |
* | |
* MUST be either TRACING_KIND_EVENT or TRACING_KIND_SPAN. | |
*/ | |
uint32_t kind; | |
/** | |
* The name of the span or event described by this metadata. Cannot be NULL. | |
*/ | |
tracing_str name; | |
/** | |
* Name of the rust module where the span or event occurred, or NULL if this | |
* could not be determined. | |
*/ | |
tracing_str module_path; | |
/** | |
* Name of the source code file where the span or event occurred, or NULL if | |
* this could not be determined. | |
*/ | |
tracing_str file; | |
/** | |
* The level of verbosity of the described span or event. | |
* | |
* MUST have one of the values from the |TracingLevel| enum. | |
*/ | |
uintptr_t level; | |
/** | |
* Line number in the source where the span occurred. | |
*/ | |
uint32_t line; | |
// XXX: As a line number of `0` should not occur, it may be possible to use | |
// that as a sentinel. (breaking change) | |
bool line_is_some; | |
/** | |
* Fields defined for this event or span. | |
*/ | |
tracing_field_set field_set; | |
}; | |
#define TRACING_METADATA_VERSION 1 | |
// metadata cannot be NULL | |
tracing_interest_t tracing_callsite_register(const tracing_metadata *metadata); | |
// metadata cannot be NULL | |
bool tracing_callsite_enabled(const tracing_metadata *metadata); | |
// metadata cannot be NULL | |
void tracing_event_dispatch(const tracing_metadata *metadata, | |
const tracing_field_value *values, | |
uintptr_t values_len); | |
// If parent == 0, dispatches an event with no parent | |
// metadata cannot be NULL | |
void tracing_event_dispatch_child_of(tracing_id_t parent, | |
const tracing_metadata *metadata, | |
const tracing_field_value *values, | |
uintptr_t values_len); | |
// metadata cannot be NULL | |
tracing_id_t tracing_span_new(const tracing_metadata *metadata, | |
const tracing_field_value *values, | |
uintptr_t values_len); | |
// If parent == 0, creates a span with no parent | |
// metadata cannot be NULL | |
tracing_id_t tracing_span_new_child_of(tracing_id_t parent, | |
const tracing_metadata *metadata, | |
const tracing_field_value *values, | |
uintptr_t values_len); | |
// span cannot be 0 | |
// field_set and values cannot be NULL | |
void tracing_span_record(tracing_id_t span, const tracing_field_set *field_set, | |
const tracing_str *values); | |
// neither span nor follows_from can be 0 | |
void tracing_span_record_follows_from(tracing_id_t span, | |
tracing_id_t follows_from); | |
// span cannot be 0 | |
void tracing_span_enter(tracing_id_t span); | |
// span cannot be 0 | |
void tracing_span_exit(tracing_id_t span); | |
// span cannot be 0 | |
tracing_id_t tracing_span_clone(tracing_id_t span); | |
// span cannot be 0 | |
bool tracing_span_try_close(tracing_id_t span); | |
// NULL outparameters will be ignored | |
void tracing_span_current(tracing_id_t *span_out, | |
const tracing_metadata **metadata_out, | |
bool *is_known_out); | |
#ifdef __cplusplus | |
} // extern "C" | |
#endif | |
#endif // !defined(tracing_core_h) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment