• Stars
    star
    33
  • Rank 783,877 (Top 16 %)
  • Language
    C
  • License
    Apache License 2.0
  • Created over 6 years ago
  • Updated almost 6 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

ANSI C API for OpenTracing

opentracing-c

Build Status Coverage

ANSI C implementation of the OpenTracing API http://opentracing.io.

Required Reading

In order to understand the C platform API, one must first be familiar with the OpenTracing project and terminology more generally.

Doxygen

API docs generated using Doxygen are hosted here on GitHub pages.

Compile and install

$ mkdir build
$ cd build
$ cmake ..
$ make
$ sudo make install

To test:

$ make test

API overview for those adding instrumentation

Everyday consumers of this opentracing-c package really only need to worry about a couple of key abstractions: the opentracing_tracer start_span function, the opentracing_span interface, and binding an opentracing_tracer at main()-time. Here are code snippets demonstrating some important use cases.

Singleton initialization

The simplest starting point is opentracing-c/tracer.h. As early as possible, call

#include "tracing_impl.h"
#include <assert.h>
#include <opentracing-c/tracer.h>

int main(void)
{
    opentracing_tracer* tracer;
    tracer = make_tracing_impl();
    assert(tracer != NULL);
    opentracing_init_global_tracer(tracer);
}

Non-singleton initialization

If you prefer direct control to singletons, manage ownership of the opentracing_tracer implementation explicitly.

Starting an empty trace by creating a "root span"

It’s always possible to create a "root" opentracing_span with no parent or other causal reference.

#include <stdlib.h>
#include <opentracing-c/tracer.h>

void abc(void)
{
    opentracing_tracer* tracer;
    opentracing_span* span;
    /* ... */
    tracer = opentracing_global_tracer();
    span = tracer->start_span(tracer, "operation_name");
    if (span == NULL) {
        /* Error creating span. */
    }
    /* ... */
    span->finish(span);
    /* ... */
    ((opentracing_destructible*) span)
        ->destroy((opentracing_destructible*) span);
}

Creating a (child) span given an existing (parent) span

void xyz(opentracing_span* parent_span)
{
    opentracing_tracer* tracer;
    opentracing_span* span;
    opentracing_start_span_options options = {0};
    opentracing_span_reference refs[1];
    opentracing_span_context* parent_context;

    parent_context = parent_span->span_context(parent_span);
    /* ... */
    tracer = opentracing_global_tracer();
    memset(&options, 0, sizeof(options));
    refs[0] =
        (opentracing_span_reference) OPENTRACINGC_CHILD_OF(*parent_context);
    options.references = refs;
    options.num_references = 1;
    span = tracer->start_span_with_options(tracer, "operation_name", &options);
    if (span == NULL) {
        /* Error creating span. */
    }
    /* Finishing the span operation. */
    span->finish(span);
    /* Freeing the span. */
    ((opentracing_destructible*) span)
        ->destroy((opentracing_destructible*) span);
}

Inject span context into an opentracing_text_map_writer

typedef struct text_map_writer {
    /* Base class instance. */
    opentracing_text_map_writer base;

    /* Map object. */
    text_map* map;
} text_map_writer;

static void noop_destroy(opentracing_destructible* d)
{
    /* noop */
}

static opentracing_propagation_error_code text_map_writer_set(
    opentracing_text_map_writer* writer, const char* key, const char* value)
{
    text_map_writer* w;

    assert(writer != NULL);
    assert(key != NULL);
    assert(value != NULL);

    w = (text_map_writer*) writer;
    if (text_map_has_key(w->map, key) || !text_map_insert(w->map, key, value)) {
        return opentracing_propagation_error_code_unknown;
    }
    return opentracing_propagation_error_code_success;
}

opentracing_bool text_map_writer_init(text_map_writer* writer)
{
    assert(writer != NULL);
    ((opentracing_destructible*) writer)->destroy = &noop_destroy;
    ((opentracing_text_map_writer*) writer)->set = &text_map_writer_set;
    writer->map = text_map_new();
    return (writer->map != NULL) ? opentracing_true : opentracing_false;
}

void inject(void)
{
    text_map_writer writer;
    opentracing_tracer* tracer;
    opentracing_span* span;
    opentracing_propagation_error_code return_code;
    if (!text_map_writer_init(&writer)) {
        return;
    }
    tracer = opentracing_global_tracer();
    span = tracer->start_span(tracer, "test-inject");
    return_code =
        tracer->inject_text_map(tracer,
                                (opentracing_text_map_writer*) &writer,
                                span->span_context(span));
    if (return_code != 0) {
        /* Injection failed, log an error message. */
        fprintf(stderr, "Injection failed, return code = %d\n", return_code);
        return;
    }
}

Extract span context from an opentracing_text_map_reader

#include "text_map_iterator.h"
#include <assert.h>
#include <stdio.h>

typedef struct text_map_reader {
    /* Base class instance. */
    opentracing_text_map_reader base;

    /* Pointer to existing map object. */
    const text_map* map;
} text_map_reader;

static opentracing_propagation_error_code text_map_reader_foreach_key(
    opentracing_text_map_reader* reader,
    opentracing_propagation_error_code (*f)(void*, const char*, const char*),
    void* arg)
{
    text_map_reader* r;
    text_map_iterator* it;
    const char* key;
    const char* value;
    opentracing_propagation_error_code return_code;

    assert(reader != NULL);
    assert(f != NULL);

    r = (text_map_reader*) reader;
    it = text_map_get_iterator(r->map);
    if (it == NULL) {
        /* Failed to allocate iterator. */
        return opentracing_propagation_error_code_unknown;
    }

    for (; text_map_iterator_has_next(it);
         text_map_iterator_next(it, &key, &value)) {
        assert(key != NULL);
        assert(value != NULL);
        return_code = f(arg, key, value);
        if (return_code != opentracing_propagation_error_code_success) {
            goto cleanup;
        }
    }

    return_code = opentracing_propagation_error_code_success;

cleanup:
    text_map_iterator_destroy(it);
    return return_code;
}

static void noop_destroy(opentracing_destructible* d)
{
}

/* Initialize new reader with existing map. */
static void text_map_reader_init(text_map_reader* reader, const text_map* map)
{
    assert(reader != NULL);
    ((opentracing_text_map_reader*) &reader)->foreach_key =
        &text_map_reader_foreach_key;
    ((opentracing_destructible*) &reader)->destroy = &noop_destroy;
    reader->map = map;
}

void extract(const text_map* map)
{
    text_map_reader reader;
    opentracing_tracer* tracer;
    opentracing_span_context* span_context;
    opentracing_propagation_error_code return_code;

    text_map_reader_init(&reader, map);
    tracer = opentracing_global_tracer();
    span_context = NULL;
    return_code = tracer->extract_text_map(
        tracer, (opentracing_text_map_reader*) &reader, &span_context);
    if (return_code != opentracing_propagation_error_code_success) {
        fprintf(stderr,
                "Failed to extract span context, error code = %d\n",
                return_code);
        return;
    }
}

More Repositories

1

opentracing-go

OpenTracing API for Go. 🛑 This library is DEPRECATED! https://github.com/opentracing/specification/issues/163
Go
3,493
star
2

opentracing-java

OpenTracing API for Java. 🛑 This library is DEPRECATED! https://github.com/opentracing/specification/issues/163
Java
1,684
star
3

specification

A place to document (and discuss) the OpenTracing specification. 🛑 This project is DEPRECATED! https://github.com/opentracing/specification/issues/163
1,173
star
4

opentracing-javascript

OpenTracing API for Javascript (both Node and browser). 🛑 This library is DEPRECATED! https://github.com/opentracing/specification/issues/163
TypeScript
1,091
star
5

opentracing-python

OpenTracing API for Python. 🛑 This library is DEPRECATED! https://github.com/opentracing/specification/issues/163
Python
755
star
6

opentracing-csharp

OpenTracing API for C# (.NET). 🛑 This library is DEPRECATED! https://github.com/opentracing/specification/issues/163
C#
517
star
7

opentracing-php

OpenTracing API for PHP
PHP
507
star
8

opentracing-cpp

OpenTracing API for C++. 🛑 This library is DEPRECATED! https://github.com/opentracing/specification/issues/163
C++
320
star
9

opentracing-ruby

OpenTracing API for Ruby
Ruby
173
star
10

opentracing.io

OpenTracing website
SCSS
116
star
11

basictracer-go

Basic implementation of the OpenTracing API for Go. 🛑 This library is DEPRECATED!
Go
81
star
12

opentracing-rust

OpenTracing API for Rust
Rust
76
star
13

opentracing-lua

OpenTracing API for Lua
Lua
29
star
14

opentracing-objc

OpenTracing API for Objective-C. 🛑 This library is DEPRECATED! https://github.com/opentracing/specification/issues/163
Objective-C
28
star
15

basictracer-python

The Python implementation of the "BasicTracer" reference implementation. 🛑 This library is DEPRECATED!
Python
26
star
16

opentracing-swift

This is a prototype OpenTracing API for the Swift language. This is intended to explore and validate decisions about implementing the OpenTracing API in Swift.
Swift
17
star
17

lua-bridge-tracer

Provides an implementation of the Lua OpenTracing API on top of the C++ API
C++
14
star
18

basictracer-csharp

Reference implementation of OpenTracing API in C#
12
star
19

documentation

Please see opentracing.io repo instead
7
star
20

basictracer-javascript

JavaScript
7
star
21

contrib

A place (or, really, a pointer) for community contributions to OpenTracing
5
star
22

opentracing-java-v030

Backwards compatibility layer for Java v0.30
Java
3
star
23

c-bridge-tracer

Experimental C binding for C++ tracers
1
star