Packages

appsignal

2.0.0-beta.4
2.17.4 2.17.3 2.17.2 2.17.1 2.17.0 2.16.0 2.15.11 2.15.10 2.15.9 2.15.8 2.15.7 2.15.6 2.15.5 2.15.4 2.15.3 2.15.2 2.15.1 2.15.0 2.14.1 2.14.0 2.13.4 2.13.3 2.13.2 2.13.1 2.13.0 2.12.3 2.12.2 2.12.1 2.12.0 2.11.0 2.10.2 2.10.1 2.10.0 2.9.2 2.9.1 2.9.0 2.8.3 2.8.2 2.8.1 2.8.0 2.7.13 2.7.12 2.7.11 2.7.10 2.7.9 2.7.8 2.7.7 2.7.6 2.7.5 2.7.4 2.7.3 2.7.2 2.7.1 2.7.0 2.7.0-beta.1 2.6.1 2.6.0 2.5.3 2.5.2 2.5.1 2.5.0 2.4.3 2.4.2 2.4.1 2.4.0 2.3.1 2.3.0 2.2.19 2.2.18 2.2.17 2.2.16 2.2.15 2.2.14 2.2.13 2.2.12 retired 2.2.11 2.2.10 2.2.9 2.2.8 2.2.7 2.2.6 2.2.5 2.2.4 2.2.3 2.2.2 2.2.1 2.2.0 2.1.15 2.1.14 2.1.13 2.1.12 2.1.11 2.1.10 2.1.9 2.1.8 2.1.7 2.1.7-beta.1 2.1.6 2.1.5 2.1.4 2.1.3 2.1.2 2.1.1 2.1.0 2.0.8 2.0.7 2.0.6 2.0.6-beta.1 2.0.5 retired 2.0.4 retired 2.0.3 retired 2.0.2 retired 2.0.1 retired 2.0.0 retired 2.0.0-beta.11 2.0.0-beta.10 2.0.0-beta.9 2.0.0-beta.8 2.0.0-beta.7 2.0.0-beta.6 2.0.0-beta.5 2.0.0-beta.4 2.0.0-beta.3 2.0.0-beta.2 2.0.0-beta.1 2.0.0-alpha.7 2.0.0-alpha.6 2.0.0-alpha.5 2.0.0-alpha.4 2.0.0-alpha.3 2.0.0-alpha.2 2.0.0-alpha.1 1.13.5 1.13.4 1.13.3 1.13.2 1.13.1 1.13.0 1.13.0-beta.2 1.13.0-beta.1 1.12.1 1.12.0 1.12.0-beta.3 1.12.0-beta.2 1.12.0-beta.1 1.11.8 1.11.7 1.11.6 1.11.5 1.11.4 1.11.3 1.11.2 1.11.1 1.11.0 1.11.0-beta.1 1.10.13 1.10.12 1.10.11 1.10.10 1.10.9 1.10.8 1.10.7 1.10.6 1.10.5 1.10.4 1.10.3 1.10.2 1.10.1 1.10.0 1.9.4 1.9.3 1.9.2 1.9.1 1.9.1-beta.1 1.9.0 1.9.0-beta.1 1.9.0-alpha.1 1.8.2 1.8.1 1.8.1-beta.2 1.8.1-beta.1 1.8.0 1.7.2 1.7.1 1.7.0 1.7.0-beta.2 1.7.0-beta.1 1.7.0-alpha.4 1.7.0-alpha.3 1.7.0-alpha.2 1.7.0-alpha.1 1.6.7 1.6.6 1.6.6-beta.2 1.6.6-beta.1 1.6.5 1.6.4 1.6.3 1.6.2 1.6.1 1.6.0 1.6.0-beta.1 1.6.0-alpha.1 1.5.1 1.5.0 1.5.0-beta.2 1.5.0-beta.1 1.4.11-beta.1 1.4.10 1.4.9 1.4.8 1.4.7 1.4.6 1.4.5 1.4.4 1.4.3 1.4.2 1.4.1 1.4.0 1.4.0-alpha.1 1.3.6 1.3.6-beta.1 1.3.5 1.3.4 1.3.4-beta.1 1.3.3 1.3.2 1.3.1 1.3.0 1.3.0-beta.3 1.3.0-beta.2 1.3.0-beta.1 1.2.3 1.2.2 1.2.1 1.2.0 1.1.1 1.1.0 1.0.4 1.0.3 1.0.2 1.0.1 1.0.0 1.0.0-rc.1 0.13.0 0.12.3 0.12.2 0.12.1 0.12.0 0.11.6 0.11.5 0.11.4 0.11.3 0.11.2 0.11.1 0.11.0 0.10.0 0.9.2 0.9.1 0.9.0 0.8.0 0.7.1 0.7.0 0.6.2 0.6.1 0.6.0 0.5.0 0.4.0 0.3.0 0.2.0 0.1.0 0.0.9 0.0.8 0.0.7 0.0.6 0.0.5 0.0.4 0.0.3 0.0.2 0.0.1

Collects error and performance data from your Elixir applications and sends it to AppSignal

Current section

Files

Jump to
appsignal c_src appsignal_extension.c
Raw

c_src/appsignal_extension.c

#ifdef __GNUC__
#define UNUSED(x) UNUSED_ ## x __attribute__((__unused__))
#else
#define UNUSED(x) UNUSED_ ## x
#endif
#include "erl_nif.h"
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <appsignal.h>
static ErlNifResourceType *appsignal_transaction_type = NULL;
static ErlNifResourceType *appsignal_data_type = NULL;
static ErlNifResourceType *appsignal_span_type = NULL;
typedef struct {
appsignal_transaction_t *transaction;
} transaction_ptr;
typedef struct {
appsignal_data_t *data;
} data_ptr;
typedef struct {
appsignal_span_t *span;
} span_ptr;
static ERL_NIF_TERM
make_ok_tuple(ErlNifEnv *env, ERL_NIF_TERM value)
{
return enif_make_tuple2(env, enif_make_atom(env, "ok"), value);
}
static ERL_NIF_TERM
make_error_tuple(ErlNifEnv *env, const char *reason)
{
return enif_make_tuple2(env, enif_make_atom(env, "error"), enif_make_atom(env, reason));
}
static appsignal_string_t make_appsignal_string(ErlNifBinary binary)
{
appsignal_string_t retval;
retval.len = binary.size;
retval.buf = (char *)binary.data;
return retval;
}
static ERL_NIF_TERM make_elixir_string(ErlNifEnv* env, appsignal_string_t binary) {
return enif_make_string_len(env, binary.buf, binary.len, ERL_NIF_LATIN1);
}
static ERL_NIF_TERM _env_put(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
ErlNifBinary key, value;
if (argc != 2) {
return enif_make_badarg(env);
}
if(!enif_inspect_iolist_as_binary(env, argv[0], &key)) {
return enif_make_badarg(env);
}
if(!enif_inspect_iolist_as_binary(env, argv[1], &value)) {
return enif_make_badarg(env);
}
appsignal_env_put(
make_appsignal_string(key),
make_appsignal_string(value)
);
return enif_make_atom(env, "ok");
}
static ERL_NIF_TERM _env_get(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
ErlNifBinary key;
appsignal_string_t value;
if (argc != 1) {
return enif_make_badarg(env);
}
if(!enif_inspect_iolist_as_binary(env, argv[0], &key)) {
return enif_make_badarg(env);
}
value = appsignal_env_get(
make_appsignal_string(key)
);
return enif_make_string(env, value.buf, ERL_NIF_LATIN1);
}
static ERL_NIF_TERM _env_delete(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {
ErlNifBinary key;
if (argc != 1) {
return enif_make_badarg(env);
}
if(!enif_inspect_iolist_as_binary(env, argv[0], &key)) {
return enif_make_badarg(env);
}
appsignal_env_delete(
make_appsignal_string(key)
);
return enif_make_atom(env, "ok");
}
static ERL_NIF_TERM _env_clear(ErlNifEnv* env, int UNUSED(argc), const ERL_NIF_TERM UNUSED(argv[]))
{
appsignal_env_clear();
return enif_make_atom(env, "ok");
}
static ERL_NIF_TERM _start(ErlNifEnv* env, int UNUSED(arc), const ERL_NIF_TERM UNUSED(argv[]))
{
appsignal_start();
return enif_make_atom(env, "ok");
}
static ERL_NIF_TERM _stop(ErlNifEnv* env, int UNUSED(arc), const ERL_NIF_TERM UNUSED(argv[]))
{
appsignal_stop();
return enif_make_atom(env, "ok");
}
static ERL_NIF_TERM _diagnose(ErlNifEnv* env, int UNUSED(arc), const ERL_NIF_TERM UNUSED(argv[])) {
return make_elixir_string(env, appsignal_diagnose());
}
static ERL_NIF_TERM _start_transaction(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
ErlNifBinary transaction_id, namespace;
transaction_ptr *ptr;
ERL_NIF_TERM transaction_ref;
if (argc != 2) {
return enif_make_badarg(env);
}
if(!enif_inspect_iolist_as_binary(env, argv[0], &transaction_id)) {
return enif_make_badarg(env);
}
if(!enif_inspect_iolist_as_binary(env, argv[1], &namespace)) {
return enif_make_badarg(env);
}
ptr = enif_alloc_resource(appsignal_transaction_type, sizeof(transaction_ptr));
if(!ptr)
return make_error_tuple(env, "no_memory");
ptr->transaction = appsignal_start_transaction(
make_appsignal_string(transaction_id),
make_appsignal_string(namespace),
0
);
transaction_ref = enif_make_resource(env, ptr);
enif_release_resource(ptr);
return make_ok_tuple(env, transaction_ref);
}
static ERL_NIF_TERM _start_event(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
transaction_ptr *ptr;
if (argc != 1) {
return enif_make_badarg(env);
}
if(!enif_get_resource(env, argv[0], appsignal_transaction_type, (void**) &ptr)) {
return enif_make_badarg(env);
}
appsignal_start_event(ptr->transaction, 0);
return enif_make_atom(env, "ok");
}
static ERL_NIF_TERM _finish_event(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
transaction_ptr *ptr;
ErlNifBinary name, title, body;
int bodyFormat;
if (argc != 5) {
return enif_make_badarg(env);
}
if(!enif_get_resource(env, argv[0], appsignal_transaction_type, (void**) &ptr)) {
return enif_make_badarg(env);
}
if(!enif_inspect_iolist_as_binary(env, argv[1], &name)) {
return enif_make_badarg(env);
}
if(!enif_inspect_iolist_as_binary(env, argv[2], &title)) {
return enif_make_badarg(env);
}
if(!enif_inspect_iolist_as_binary(env, argv[3], &body)) {
return enif_make_badarg(env);
}
if(!enif_get_int(env, argv[4], &bodyFormat)) {
return enif_make_badarg(env);
}
appsignal_finish_event(
ptr->transaction,
make_appsignal_string(name),
make_appsignal_string(title),
make_appsignal_string(body),
bodyFormat,
0
);
return enif_make_atom(env, "ok");
}
static ERL_NIF_TERM _finish_event_data(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
transaction_ptr *ptr;
ErlNifBinary name, title;
int bodyFormat;
data_ptr *body;
if (argc != 5) {
return enif_make_badarg(env);
}
if(!enif_get_resource(env, argv[0], appsignal_transaction_type, (void**) &ptr)) {
return enif_make_badarg(env);
}
if(!enif_inspect_iolist_as_binary(env, argv[1], &name)) {
return enif_make_badarg(env);
}
if(!enif_inspect_iolist_as_binary(env, argv[2], &title)) {
return enif_make_badarg(env);
}
if(!enif_get_resource(env, argv[3], appsignal_data_type, (void**) &body)) {
return enif_make_badarg(env);
}
if(!enif_get_int(env, argv[4], &bodyFormat)) {
return enif_make_badarg(env);
}
appsignal_finish_event_data(
ptr->transaction,
make_appsignal_string(name),
make_appsignal_string(title),
body->data,
bodyFormat,
0
);
return enif_make_atom(env, "ok");
}
static ERL_NIF_TERM _record_event(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
transaction_ptr *ptr;
ErlNifBinary name, title, body;
long duration;
int bodyFormat;
if (argc != 6) {
return enif_make_badarg(env);
}
if(!enif_get_resource(env, argv[0], appsignal_transaction_type, (void**) &ptr)) {
return enif_make_badarg(env);
}
if(!enif_inspect_iolist_as_binary(env, argv[1], &name)) {
return enif_make_badarg(env);
}
if(!enif_inspect_iolist_as_binary(env, argv[2], &title)) {
return enif_make_badarg(env);
}
if(!enif_inspect_iolist_as_binary(env, argv[3], &body)) {
return enif_make_badarg(env);
}
if(!enif_get_int(env, argv[4], &bodyFormat)) {
return enif_make_badarg(env);
}
if(!enif_get_long(env, argv[5], &duration)) {
return enif_make_badarg(env);
}
appsignal_record_event(
ptr->transaction,
make_appsignal_string(name),
make_appsignal_string(title),
make_appsignal_string(body),
bodyFormat,
duration,
0
);
return enif_make_atom(env, "ok");
}
static ERL_NIF_TERM _set_error(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
transaction_ptr *ptr;
ErlNifBinary error, message;
data_ptr *data_ptr;
if (argc != 4) {
return enif_make_badarg(env);
}
if(!enif_get_resource(env, argv[0], appsignal_transaction_type, (void**) &ptr)) {
return enif_make_badarg(env);
}
if(!enif_inspect_iolist_as_binary(env, argv[1], &error)) {
return enif_make_badarg(env);
}
if(!enif_inspect_iolist_as_binary(env, argv[2], &message)) {
return enif_make_badarg(env);
}
if(!enif_get_resource(env, argv[3], appsignal_data_type, (void**) &data_ptr)) {
return enif_make_badarg(env);
}
appsignal_set_transaction_error(
ptr->transaction,
make_appsignal_string(error),
make_appsignal_string(message),
data_ptr->data
);
return enif_make_atom(env, "ok");
}
static ERL_NIF_TERM _set_sample_data(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
transaction_ptr *ptr;
ErlNifBinary key;
data_ptr *data_ptr;
if (argc != 3) {
return enif_make_badarg(env);
}
if(!enif_get_resource(env, argv[0], appsignal_transaction_type, (void**) &ptr)) {
return enif_make_badarg(env);
}
if(!enif_inspect_iolist_as_binary(env, argv[1], &key)) {
return enif_make_badarg(env);
}
if(!enif_get_resource(env, argv[2], appsignal_data_type, (void**) &data_ptr)) {
return enif_make_badarg(env);
}
appsignal_set_transaction_sample_data(
ptr->transaction,
make_appsignal_string(key),
data_ptr->data
);
return enif_make_atom(env, "ok");
}
static ERL_NIF_TERM _set_action(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
transaction_ptr *ptr;
ErlNifBinary action;
if (argc != 2) {
return enif_make_badarg(env);
}
if(!enif_get_resource(env, argv[0], appsignal_transaction_type, (void**) &ptr)) {
return enif_make_badarg(env);
}
if(!enif_inspect_iolist_as_binary(env, argv[1], &action)) {
return enif_make_badarg(env);
}
appsignal_set_transaction_action(
ptr->transaction,
make_appsignal_string(action)
);
return enif_make_atom(env, "ok");
}
static ERL_NIF_TERM _set_namespace(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
transaction_ptr *ptr;
ErlNifBinary namespace;
if (argc != 2) {
return enif_make_badarg(env);
}
if(!enif_get_resource(env, argv[0], appsignal_transaction_type, (void**) &ptr)) {
return enif_make_badarg(env);
}
if(!enif_inspect_iolist_as_binary(env, argv[1], &namespace)) {
return enif_make_badarg(env);
}
appsignal_set_transaction_namespace(
ptr->transaction,
make_appsignal_string(namespace)
);
return enif_make_atom(env, "ok");
}
static ERL_NIF_TERM _set_queue_start(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
transaction_ptr *ptr;
long start;
if (argc != 2) {
return enif_make_badarg(env);
}
if(!enif_get_resource(env, argv[0], appsignal_transaction_type, (void**) &ptr)) {
return enif_make_badarg(env);
}
if(!enif_get_long(env, argv[1], &start)) {
return enif_make_badarg(env);
}
appsignal_set_transaction_queue_start(
ptr->transaction,
start
);
return enif_make_atom(env, "ok");
}
static ERL_NIF_TERM _set_meta_data(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
transaction_ptr *ptr;
ErlNifBinary key, value;
if (argc != 3) {
return enif_make_badarg(env);
}
if(!enif_get_resource(env, argv[0], appsignal_transaction_type, (void**) &ptr)) {
return enif_make_badarg(env);
}
if(!enif_inspect_iolist_as_binary(env, argv[1], &key)) {
return enif_make_badarg(env);
}
if(!enif_inspect_iolist_as_binary(env, argv[2], &value)) {
return enif_make_badarg(env);
}
appsignal_set_transaction_metadata(
ptr->transaction,
make_appsignal_string(key),
make_appsignal_string(value)
);
return enif_make_atom(env, "ok");
}
static ERL_NIF_TERM _finish(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
transaction_ptr *ptr;
int sample;
if (argc != 1) {
return enif_make_badarg(env);
}
if(!enif_get_resource(env, argv[0], appsignal_transaction_type, (void**) &ptr)) {
return enif_make_badarg(env);
}
sample = appsignal_finish_transaction(ptr->transaction, 0);
if (sample == 1) {
return enif_make_atom(env, "sample");
} else {
return enif_make_atom(env, "no_sample");
}
}
static ERL_NIF_TERM _complete(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
transaction_ptr *ptr;
if (argc != 1) {
return enif_make_badarg(env);
}
if(!enif_get_resource(env, argv[0], appsignal_transaction_type, (void**) &ptr)) {
return enif_make_badarg(env);
}
appsignal_complete_transaction(ptr->transaction);
return enif_make_atom(env, "ok");
}
static void destruct_appsignal_transaction(ErlNifEnv *UNUSED(env), void *arg) {
transaction_ptr *ptr = (transaction_ptr *)arg;
appsignal_free_transaction(ptr->transaction);
}
static void destruct_appsignal_data(ErlNifEnv *UNUSED(env), void *arg) {
data_ptr *ptr = (data_ptr *)arg;
appsignal_free_data(ptr->data);
}
static void destruct_appsignal_span(ErlNifEnv *UNUSED(env), void *arg) {
span_ptr *ptr = (span_ptr *)arg;
appsignal_free_span(ptr->span);
}
static ERL_NIF_TERM _set_gauge(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
ErlNifBinary key;
double value;
data_ptr *data_ptr;
if (argc != 3) {
return enif_make_badarg(env);
}
if(!enif_inspect_iolist_as_binary(env, argv[0], &key)) {
return enif_make_badarg(env);
}
if(!enif_get_double(env, argv[1], &value)) {
return enif_make_badarg(env);
}
if(!enif_get_resource(env, argv[2], appsignal_data_type, (void**) &data_ptr)) {
return enif_make_badarg(env);
}
appsignal_set_gauge(make_appsignal_string(key), value, data_ptr->data);
return enif_make_atom(env, "ok");
}
static ERL_NIF_TERM _increment_counter(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
ErlNifBinary key;
double count;
data_ptr *data_ptr;
if (argc != 3) {
return enif_make_badarg(env);
}
if(!enif_inspect_iolist_as_binary(env, argv[0], &key)) {
return enif_make_badarg(env);
}
if(!enif_get_double(env, argv[1], &count)) {
return enif_make_badarg(env);
}
if(!enif_get_resource(env, argv[2], appsignal_data_type, (void**) &data_ptr)) {
return enif_make_badarg(env);
}
appsignal_increment_counter(make_appsignal_string(key), count, data_ptr->data);
return enif_make_atom(env, "ok");
}
static ERL_NIF_TERM _add_distribution_value(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
ErlNifBinary key;
double value;
data_ptr *data_ptr;
if (argc != 3) {
return enif_make_badarg(env);
}
if(!enif_inspect_iolist_as_binary(env, argv[0], &key)) {
return enif_make_badarg(env);
}
if(!enif_get_double(env, argv[1], &value)) {
return enif_make_badarg(env);
}
if(!enif_get_resource(env, argv[2], appsignal_data_type, (void**) &data_ptr)) {
return enif_make_badarg(env);
}
appsignal_add_distribution_value(make_appsignal_string(key), value, data_ptr->data);
return enif_make_atom(env, "ok");
}
static ERL_NIF_TERM _data_map_new(ErlNifEnv* env, int UNUSED(argc), const ERL_NIF_TERM UNUSED(argv[])) {
data_ptr *ptr;
ERL_NIF_TERM data_ref;
ptr = enif_alloc_resource(appsignal_data_type, sizeof(data_ptr));
if(!ptr)
return make_error_tuple(env, "no_memory");
ptr->data = appsignal_data_map_new();
data_ref = enif_make_resource(env, ptr);
enif_release_resource(ptr);
return make_ok_tuple(env, data_ref);
}
static ERL_NIF_TERM _data_filtered_map_new(ErlNifEnv* env, int UNUSED(argc), const ERL_NIF_TERM UNUSED(argv[])) {
data_ptr *ptr;
ERL_NIF_TERM data_ref;
ptr = enif_alloc_resource(appsignal_data_type, sizeof(data_ptr));
if(!ptr)
return make_error_tuple(env, "no_memory");
ptr->data = appsignal_data_filtered_map_new();
data_ref = enif_make_resource(env, ptr);
enif_release_resource(ptr);
return make_ok_tuple(env, data_ref);
}
static ERL_NIF_TERM _data_set_string(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {
data_ptr *ptr;
ErlNifBinary key, value;
if(!enif_get_resource(env, argv[0], appsignal_data_type, (void**) &ptr)) {
return enif_make_badarg(env);
}
switch(argc) {
case 3:
if(!enif_inspect_iolist_as_binary(env, argv[1], &key)) {
return enif_make_badarg(env);
}
if(!enif_inspect_iolist_as_binary(env, argv[2], &value)) {
return enif_make_badarg(env);
}
appsignal_data_map_set_string(ptr->data, make_appsignal_string(key), make_appsignal_string(value));
break;
case 2:
if(!enif_inspect_iolist_as_binary(env, argv[1], &value)) {
return enif_make_badarg(env);
}
appsignal_data_array_append_string(ptr->data, make_appsignal_string(value));
break;
default:
return enif_make_badarg(env);
}
return enif_make_atom(env, "ok");
}
static ERL_NIF_TERM _data_set_integer(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {
data_ptr *ptr;
ErlNifBinary key;
long value;
if(!enif_get_resource(env, argv[0], appsignal_data_type, (void**) &ptr)) {
return enif_make_badarg(env);
}
switch(argc) {
case 3:
if(!enif_inspect_iolist_as_binary(env, argv[1], &key)) {
return enif_make_badarg(env);
}
if(!enif_get_int64(env, argv[2], &value)) {
return enif_make_badarg(env);
}
appsignal_data_map_set_integer(ptr->data, make_appsignal_string(key), value);
break;
case 2:
if(!enif_get_int64(env, argv[1], &value)) {
return enif_make_badarg(env);
}
appsignal_data_array_append_integer(ptr->data, value);
break;
default:
return enif_make_badarg(env);
}
return enif_make_atom(env, "ok");
}
static ERL_NIF_TERM _data_set_float(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {
data_ptr *ptr;
ErlNifBinary key;
double value;
if(!enif_get_resource(env, argv[0], appsignal_data_type, (void**) &ptr)) {
return enif_make_badarg(env);
}
switch(argc) {
case 3:
if(!enif_inspect_iolist_as_binary(env, argv[1], &key)) {
return enif_make_badarg(env);
}
if(!enif_get_double(env, argv[2], &value)) {
return enif_make_badarg(env);
}
appsignal_data_map_set_float(ptr->data, make_appsignal_string(key), value);
break;
case 2:
if(!enif_get_double(env, argv[1], &value)) {
return enif_make_badarg(env);
}
appsignal_data_array_append_float(ptr->data, value);
break;
default:
return enif_make_badarg(env);
}
return enif_make_atom(env, "ok");
}
static ERL_NIF_TERM _data_set_boolean(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {
data_ptr *ptr;
ErlNifBinary key;
int value;
if(!enif_get_resource(env, argv[0], appsignal_data_type, (void**) &ptr)) {
return enif_make_badarg(env);
}
switch(argc) {
case 3:
if(!enif_inspect_iolist_as_binary(env, argv[1], &key)) {
return enif_make_badarg(env);
}
if (!enif_get_int(env, argv[2], &value)) {
return enif_make_badarg(env);
}
appsignal_data_map_set_boolean(ptr->data, make_appsignal_string(key), value);
break;
case 2:
if (!enif_get_int(env, argv[1], &value)) {
return enif_make_badarg(env);
}
appsignal_data_array_append_boolean(ptr->data, value);
break;
default:
return enif_make_badarg(env);
}
return enif_make_atom(env, "ok");
}
static ERL_NIF_TERM _data_set_nil(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {
data_ptr *ptr;
ErlNifBinary key;
if(!enif_get_resource(env, argv[0], appsignal_data_type, (void**) &ptr)) {
return enif_make_badarg(env);
}
switch(argc) {
case 2:
if(!enif_inspect_iolist_as_binary(env, argv[1], &key)) {
return enif_make_badarg(env);
}
appsignal_data_map_set_null(ptr->data, make_appsignal_string(key));
break;
case 1:
appsignal_data_array_append_null(ptr->data);
break;
default:
return enif_make_badarg(env);
}
return enif_make_atom(env, "ok");
}
static ERL_NIF_TERM _data_set_data(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {
data_ptr *ptr, *value;
ErlNifBinary key;
if(!enif_get_resource(env, argv[0], appsignal_data_type, (void**) &ptr)) {
return enif_make_badarg(env);
}
switch(argc) {
case 3:
if(!enif_inspect_iolist_as_binary(env, argv[1], &key)) {
return enif_make_badarg(env);
}
if(!enif_get_resource(env, argv[2], appsignal_data_type, (void**) &value)) {
return enif_make_badarg(env);
}
appsignal_data_map_set_data(ptr->data, make_appsignal_string(key), value->data);
break;
case 2:
if(!enif_get_resource(env, argv[1], appsignal_data_type, (void**) &value)) {
return enif_make_badarg(env);
}
appsignal_data_array_append_data(ptr->data, value->data);
break;
default:
return enif_make_badarg(env);
}
return enif_make_atom(env, "ok");
}
static ERL_NIF_TERM _data_list_new(ErlNifEnv* env, int UNUSED(argc), const ERL_NIF_TERM UNUSED(argv[])) {
data_ptr *ptr;
ERL_NIF_TERM data_ref;
ptr = enif_alloc_resource(appsignal_data_type, sizeof(data_ptr));
if(!ptr)
return make_error_tuple(env, "no_memory");
ptr->data = appsignal_data_array_new();
data_ref = enif_make_resource(env, ptr);
enif_release_resource(ptr);
return make_ok_tuple(env, data_ref);
}
static ERL_NIF_TERM _running_in_container(ErlNifEnv* env, int UNUSED(argc), const ERL_NIF_TERM UNUSED(argv[])) {
if(appsignal_running_in_container() == 1) {
return enif_make_atom(env, "true");
} else {
return enif_make_atom(env, "false");
}
}
#ifdef TEST
static ERL_NIF_TERM _data_to_json(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {
data_ptr *ptr;
appsignal_string_t json;
if (argc != 1) {
return enif_make_badarg(env);
}
if (!enif_get_resource(env, argv[0], appsignal_data_type, (void**) &ptr)) {
return enif_make_badarg(env);
}
json = appsignal_data_to_json(ptr->data);
return make_ok_tuple(env, enif_make_string(env, json.buf, ERL_NIF_LATIN1));
}
static ERL_NIF_TERM _transaction_to_json(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {
transaction_ptr *ptr;
appsignal_string_t json;
if (argc != 1) {
return enif_make_badarg(env);
}
if (!enif_get_resource(env, argv[0], appsignal_transaction_type, (void**) &ptr)) {
return enif_make_badarg(env);
}
json = appsignal_transaction_to_json(ptr->transaction);
return make_ok_tuple(env, make_elixir_string(env, json));
}
#endif
static ERL_NIF_TERM _loaded(ErlNifEnv *env, int UNUSED(argc), const ERL_NIF_TERM UNUSED(argv[])) {
return enif_make_atom(env, "true");
}
static ERL_NIF_TERM _create_root_span(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {
span_ptr *ptr;
ErlNifBinary namespace;
ERL_NIF_TERM span_ref;
if (argc != 1) {
return enif_make_badarg(env);
}
if(!enif_inspect_iolist_as_binary(env, argv[0], &namespace)) {
return enif_make_badarg(env);
}
ptr = enif_alloc_resource(appsignal_span_type, sizeof(span_ptr));
if(!ptr)
return make_error_tuple(env, "no_memory");
ptr->span = appsignal_create_root_span(make_appsignal_string(namespace));
span_ref = enif_make_resource(env, ptr);
enif_release_resource(ptr);
return make_ok_tuple(env, span_ref);
}
static ERL_NIF_TERM _create_root_span_with_timestamp(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {
span_ptr *ptr;
ErlNifBinary namespace;
long sec;
long nsec;
ERL_NIF_TERM span_ref;
if (argc != 3) {
return enif_make_badarg(env);
}
if(!enif_inspect_iolist_as_binary(env, argv[0], &namespace)) {
return enif_make_badarg(env);
}
if(!enif_get_long(env, argv[1], &sec)) {
return enif_make_badarg(env);
}
if(!enif_get_long(env, argv[2], &nsec)) {
return enif_make_badarg(env);
}
ptr = enif_alloc_resource(appsignal_span_type, sizeof(span_ptr));
if(!ptr)
return make_error_tuple(env, "no_memory");
ptr->span = appsignal_create_root_span_with_timestamp(make_appsignal_string(namespace), sec, nsec);
span_ref = enif_make_resource(env, ptr);
enif_release_resource(ptr);
return make_ok_tuple(env, span_ref);
}
static ERL_NIF_TERM _create_child_span(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {
span_ptr *ptr;
ErlNifBinary trace_id;
ErlNifBinary span_id;
ERL_NIF_TERM span_ref;
if (argc != 2) {
return enif_make_badarg(env);
}
if(!enif_inspect_iolist_as_binary(env, argv[0], &trace_id)) {
return enif_make_badarg(env);
}
if(!enif_inspect_iolist_as_binary(env, argv[1], &span_id)) {
return enif_make_badarg(env);
}
ptr = enif_alloc_resource(appsignal_span_type, sizeof(span_ptr));
if(!ptr)
return make_error_tuple(env, "no_memory");
ptr->span = appsignal_create_child_span(
make_appsignal_string(trace_id),
make_appsignal_string(span_id)
);
span_ref = enif_make_resource(env, ptr);
enif_release_resource(ptr);
return make_ok_tuple(env, span_ref);
}
static ERL_NIF_TERM _create_child_span_with_timestamp(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {
span_ptr *ptr;
ErlNifBinary trace_id;
ErlNifBinary span_id;
long sec;
long nsec;
ERL_NIF_TERM span_ref;
if (argc != 4) {
return enif_make_badarg(env);
}
if(!enif_inspect_iolist_as_binary(env, argv[0], &trace_id)) {
return enif_make_badarg(env);
}
if(!enif_inspect_iolist_as_binary(env, argv[1], &span_id)) {
return enif_make_badarg(env);
}
if(!enif_get_long(env, argv[2], &sec)) {
return enif_make_badarg(env);
}
if(!enif_get_long(env, argv[3], &nsec)) {
return enif_make_badarg(env);
}
ptr = enif_alloc_resource(appsignal_span_type, sizeof(span_ptr));
if(!ptr)
return make_error_tuple(env, "no_memory");
ptr->span = appsignal_create_child_span_with_timestamp(
make_appsignal_string(trace_id),
make_appsignal_string(span_id),
sec,
nsec
);
span_ref = enif_make_resource(env, ptr);
enif_release_resource(ptr);
return make_ok_tuple(env, span_ref);
}
static ERL_NIF_TERM _set_span_name(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
span_ptr *ptr;
ErlNifBinary name;
if (argc != 2) {
return enif_make_badarg(env);
}
if(!enif_get_resource(env, argv[0], appsignal_span_type, (void**) &ptr)) {
return enif_make_badarg(env);
}
if(!enif_inspect_iolist_as_binary(env, argv[1], &name)) {
return enif_make_badarg(env);
}
appsignal_set_span_name(ptr->span, make_appsignal_string(name));
return enif_make_atom(env, "ok");
}
static ERL_NIF_TERM _set_span_attribute_string(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
span_ptr *ptr;
ErlNifBinary key;
ErlNifBinary value;
if (argc != 3) {
return enif_make_badarg(env);
}
if(!enif_get_resource(env, argv[0], appsignal_span_type, (void**) &ptr)) {
return enif_make_badarg(env);
}
if(!enif_inspect_iolist_as_binary(env, argv[1], &key)) {
return enif_make_badarg(env);
}
if(!enif_inspect_iolist_as_binary(env, argv[2], &value)) {
return enif_make_badarg(env);
}
appsignal_set_span_attribute_string(
ptr->span,
make_appsignal_string(key),
make_appsignal_string(value)
);
return enif_make_atom(env, "ok");
}
static ERL_NIF_TERM _set_span_attribute_int(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
span_ptr *ptr;
ErlNifBinary key;
long value;
if (argc != 3) {
return enif_make_badarg(env);
}
if(!enif_get_resource(env, argv[0], appsignal_span_type, (void**) &ptr)) {
return enif_make_badarg(env);
}
if(!enif_inspect_iolist_as_binary(env, argv[1], &key)) {
return enif_make_badarg(env);
}
if(!enif_get_long(env, argv[2], &value)) {
return enif_make_badarg(env);
}
appsignal_set_span_attribute_int(
ptr->span,
make_appsignal_string(key),
value
);
return enif_make_atom(env, "ok");
}
static ERL_NIF_TERM _set_span_attribute_bool(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
span_ptr *ptr;
ErlNifBinary key;
int value;
if (argc != 3) {
return enif_make_badarg(env);
}
if(!enif_get_resource(env, argv[0], appsignal_span_type, (void**) &ptr)) {
return enif_make_badarg(env);
}
if(!enif_inspect_iolist_as_binary(env, argv[1], &key)) {
return enif_make_badarg(env);
}
if(!enif_get_int(env, argv[2], &value)) {
return enif_make_badarg(env);
}
appsignal_set_span_attribute_bool(
ptr->span,
make_appsignal_string(key),
value
);
return enif_make_atom(env, "ok");
}
static ERL_NIF_TERM _set_span_attribute_double(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
span_ptr *ptr;
ErlNifBinary key;
double value;
if (argc != 3) {
return enif_make_badarg(env);
}
if(!enif_get_resource(env, argv[0], appsignal_span_type, (void**) &ptr)) {
return enif_make_badarg(env);
}
if(!enif_inspect_iolist_as_binary(env, argv[1], &key)) {
return enif_make_badarg(env);
}
if(!enif_get_double(env, argv[2], &value)) {
return enif_make_badarg(env);
}
appsignal_set_span_attribute_double(
ptr->span,
make_appsignal_string(key),
value
);
return enif_make_atom(env, "ok");
}
static ERL_NIF_TERM _set_span_attribute_sql_string(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
span_ptr *ptr;
ErlNifBinary key;
ErlNifBinary value;
if (argc != 3) {
return enif_make_badarg(env);
}
if(!enif_get_resource(env, argv[0], appsignal_span_type, (void**) &ptr)) {
return enif_make_badarg(env);
}
if(!enif_inspect_iolist_as_binary(env, argv[1], &key)) {
return enif_make_badarg(env);
}
if(!enif_inspect_iolist_as_binary(env, argv[2], &value)) {
return enif_make_badarg(env);
}
appsignal_set_span_attribute_sql_string(
ptr->span,
make_appsignal_string(key),
make_appsignal_string(value)
);
return enif_make_atom(env, "ok");
}
static ERL_NIF_TERM _set_span_sample_data(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
span_ptr *ptr;
ErlNifBinary key;
data_ptr *data_ptr;
if (argc != 3) {
return enif_make_badarg(env);
}
if(!enif_get_resource(env, argv[0], appsignal_span_type, (void**) &ptr)) {
return enif_make_badarg(env);
}
if(!enif_inspect_iolist_as_binary(env, argv[1], &key)) {
return enif_make_badarg(env);
}
if(!enif_get_resource(env, argv[2], appsignal_data_type, (void**) &data_ptr)) {
return enif_make_badarg(env);
}
appsignal_set_span_sample_data(
ptr->span,
make_appsignal_string(key),
data_ptr->data
);
return enif_make_atom(env, "ok");
}
static ERL_NIF_TERM _add_span_error(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {
span_ptr *ptr;
ErlNifBinary error, message;
data_ptr *data_ptr;
if (argc != 4) {
return enif_make_badarg(env);
}
if(!enif_get_resource(env, argv[0], appsignal_span_type, (void**) &ptr)) {
return enif_make_badarg(env);
}
if(!enif_inspect_iolist_as_binary(env, argv[1], &error)) {
return enif_make_badarg(env);
}
if(!enif_inspect_iolist_as_binary(env, argv[2], &message)) {
return enif_make_badarg(env);
}
if(!enif_get_resource(env, argv[3], appsignal_data_type, (void**) &data_ptr)) {
return enif_make_badarg(env);
}
appsignal_add_span_error(
ptr->span,
make_appsignal_string(error),
make_appsignal_string(message),
data_ptr->data
);
return enif_make_atom(env, "ok");
}
static ERL_NIF_TERM _close_span(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
span_ptr *ptr;
if (argc != 1) {
return enif_make_badarg(env);
}
if(!enif_get_resource(env, argv[0], appsignal_span_type, (void**) &ptr)) {
return enif_make_badarg(env);
}
appsignal_close_span(ptr->span);
return enif_make_atom(env, "ok");
}
static ERL_NIF_TERM _close_span_with_timestamp(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
span_ptr *ptr;
long sec;
long nsec;
if (argc != 3) {
return enif_make_badarg(env);
}
if(!enif_get_resource(env, argv[0], appsignal_span_type, (void**) &ptr)) {
return enif_make_badarg(env);
}
if(!enif_get_long(env, argv[1], &sec)) {
return enif_make_badarg(env);
}
if(!enif_get_long(env, argv[2], &nsec)) {
return enif_make_badarg(env);
}
appsignal_close_span_with_timestamp(ptr->span, sec, nsec);
return enif_make_atom(env, "ok");
}
static ERL_NIF_TERM _trace_id(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
span_ptr *ptr;
appsignal_string_t id;
if (argc != 1) {
return enif_make_badarg(env);
}
if (!enif_get_resource(env, argv[0], appsignal_span_type, (void**) &ptr)) {
return enif_make_badarg(env);
}
id = appsignal_trace_id(ptr->span);
return make_ok_tuple(env, make_elixir_string(env,id));
}
static ERL_NIF_TERM _span_id(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
span_ptr *ptr;
appsignal_string_t id;
if (argc != 1) {
return enif_make_badarg(env);
}
if (!enif_get_resource(env, argv[0], appsignal_span_type, (void**) &ptr)) {
return enif_make_badarg(env);
}
id = appsignal_span_id(ptr->span);
return make_ok_tuple(env, make_elixir_string(env,id));
}
static ERL_NIF_TERM _span_to_json(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {
span_ptr *ptr;
appsignal_string_t json;
if (argc != 1) {
return enif_make_badarg(env);
}
if (!enif_get_resource(env, argv[0], appsignal_span_type, (void**) &ptr)) {
return enif_make_badarg(env);
}
json = appsignal_span_to_json(ptr->span);
return make_ok_tuple(env, make_elixir_string(env, json));
}
static int on_load(ErlNifEnv* env, void** UNUSED(priv), ERL_NIF_TERM UNUSED(info))
{
ErlNifResourceType *transaction_resource_type;
ErlNifResourceType *data_resource_type;
ErlNifResourceType *span_resource_type;
transaction_resource_type = enif_open_resource_type(
env,
"appsignal_nif",
"appsignal_transaction_type",
destruct_appsignal_transaction,
ERL_NIF_RT_CREATE,
NULL
);
data_resource_type = enif_open_resource_type(
env,
"appsignal_nif",
"appsignal_data_type",
destruct_appsignal_data,
ERL_NIF_RT_CREATE,
NULL
);
span_resource_type = enif_open_resource_type(
env,
"appsignal_nif",
"appsignal_span_type",
destruct_appsignal_span,
ERL_NIF_RT_CREATE,
NULL
);
if (!transaction_resource_type || !data_resource_type) {
return -1;
}
appsignal_transaction_type = transaction_resource_type;
appsignal_data_type = data_resource_type;
appsignal_span_type = span_resource_type;
return 0;
}
static int on_reload(ErlNifEnv* UNUSED(env), void** UNUSED(priv_data), ERL_NIF_TERM UNUSED(load_info))
{
return 0;
}
static int on_upgrade(ErlNifEnv* UNUSED(env), void** UNUSED(priv), void** UNUSED(old_priv_data), ERL_NIF_TERM UNUSED(load_info))
{
return 0;
}
static ErlNifFunc nif_funcs[] =
{
{"_env_put", 2, _env_put, 0},
{"_env_get", 1, _env_get, 0},
{"_env_delete", 1, _env_delete, 0},
{"_env_clear", 0, _env_clear, 0},
{"_start", 0, _start, 0},
{"_stop", 0, _stop, 0},
{"_diagnose", 0, _diagnose, 0},
{"_start_transaction", 2, _start_transaction, 0},
{"_start_event", 1, _start_event, 0},
{"_finish_event", 5, _finish_event, 0},
{"_finish_event_data", 5, _finish_event_data, 0},
{"_record_event", 6, _record_event, 0},
{"_set_error", 4, _set_error, 0},
{"_set_sample_data", 3, _set_sample_data, 0},
{"_set_action", 2, _set_action, 0},
{"_set_namespace", 2, _set_namespace, 0},
{"_set_queue_start", 2, _set_queue_start, 0},
{"_set_meta_data", 3, _set_meta_data, 0},
{"_finish", 1, _finish, 0},
{"_complete", 1, _complete, 0},
{"_set_gauge", 3, _set_gauge, 0},
{"_increment_counter", 3, _increment_counter, 0},
{"_add_distribution_value", 3, _add_distribution_value, 0},
{"_data_map_new", 0, _data_map_new, 0},
{"_data_filtered_map_new", 0, _data_filtered_map_new, 0},
{"_data_set_string", 3, _data_set_string, 0},
{"_data_set_string", 2, _data_set_string, 0},
{"_data_set_integer", 3, _data_set_integer, 0},
{"_data_set_integer", 2, _data_set_integer, 0},
{"_data_set_float", 3, _data_set_float, 0},
{"_data_set_float", 2, _data_set_float, 0},
{"_data_set_boolean", 3, _data_set_boolean, 0},
{"_data_set_boolean", 2, _data_set_boolean, 0},
{"_data_set_nil", 2, _data_set_nil, 0},
{"_data_set_nil", 1, _data_set_nil, 0},
{"_data_set_data", 3, _data_set_data, 0},
{"_data_set_data", 2, _data_set_data, 0},
{"_data_list_new", 0, _data_list_new, 0},
{"_running_in_container", 0, _running_in_container, 0},
#ifdef TEST
{"_transaction_to_json", 1, _transaction_to_json, 0},
{"_data_to_json", 1, _data_to_json, 0},
#endif
{"_loaded", 0, _loaded, 0},
{"_create_root_span", 1, _create_root_span, 0},
{"_create_root_span_with_timestamp", 3, _create_root_span_with_timestamp, 0},
{"_create_child_span", 2, _create_child_span, 0},
{"_create_child_span_with_timestamp", 4, _create_child_span_with_timestamp, 0},
{"_set_span_name", 2, _set_span_name, 0},
{"_set_span_attribute_string", 3, _set_span_attribute_string, 0},
{"_set_span_attribute_int", 3, _set_span_attribute_int, 0},
{"_set_span_attribute_bool", 3, _set_span_attribute_bool, 0},
{"_set_span_attribute_double", 3, _set_span_attribute_double, 0},
{"_set_span_attribute_sql_string", 3, _set_span_attribute_string, 0},
{"_set_span_sample_data", 3, _set_span_sample_data, 0},
{"_add_span_error", 4, _add_span_error, 0},
{"_close_span", 1, _close_span, 0},
{"_close_span_with_timestamp", 3, _close_span_with_timestamp, 0},
{"_trace_id", 1, _trace_id, 0},
{"_span_id", 1, _span_id, 0},
{"_span_to_json", 1, _span_to_json, 0}
};
ERL_NIF_INIT(Elixir.Appsignal.Nif, nif_funcs, on_load, on_reload, on_upgrade, NULL)