Skip to content

Instantly share code, notes, and snippets.

@mystor
Created August 20, 2020 18:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mystor/3c979b1a903986b2d30c2f74bfe4d6e8 to your computer and use it in GitHub Desktop.
Save mystor/3c979b1a903986b2d30c2f74bfe4d6e8 to your computer and use it in GitHub Desktop.
RFC: tracing-core C FFI proposal
#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