summaryrefslogtreecommitdiffstats
path: root/src/blkin/blkin-lib/zipkin_c.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/blkin/blkin-lib/zipkin_c.c356
1 files changed, 356 insertions, 0 deletions
diff --git a/src/blkin/blkin-lib/zipkin_c.c b/src/blkin/blkin-lib/zipkin_c.c
new file mode 100644
index 000000000..a68182b55
--- /dev/null
+++ b/src/blkin/blkin-lib/zipkin_c.c
@@ -0,0 +1,356 @@
+/*
+ * Copyright 2014 Marios Kogias <marioskogias@gmail.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "zipkin_c.h"
+#include <pthread.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#define TRACEPOINT_DEFINE
+#include <zipkin_trace.h>
+
+const char *default_ip = "NaN";
+const char *default_name = "NoName";
+
+const char* const CLIENT_SEND = "cs";
+const char* const CLIENT_RECV = "cr";
+const char* const SERVER_SEND = "ss";
+const char* const SERVER_RECV = "sr";
+const char* const WIRE_SEND = "ws";
+const char* const WIRE_RECV = "wr";
+const char* const CLIENT_SEND_FRAGMENT = "csf";
+const char* const CLIENT_RECV_FRAGMENT = "crf";
+const char* const SERVER_SEND_FRAGMENT = "ssf";
+const char* const SERVER_RECV_FRAGMENT = "srf";
+
+static int64_t random_big()
+{
+ int64_t a;
+ a = rand();
+ a = a << 32;
+ int b = rand();
+ a = a + b;
+ if (a<0)
+ a = !a;
+ return a;
+}
+
+int blkin_init()
+{
+ static pthread_mutex_t blkin_init_mutex = PTHREAD_MUTEX_INITIALIZER;
+ static int initialized = 0;
+
+ /*
+ * Initialize srand with sth appropriete
+ * time is not good for archipelago: several deamons -> same timstamp
+ */
+ pthread_mutex_lock(&blkin_init_mutex);
+ if (!initialized) {
+ int inf, seed;
+ inf = open("/dev/urandom", O_RDONLY); //file descriptor 1
+ read(inf, &seed, sizeof(int));
+ close(inf);
+ srand(seed);
+ initialized = 1;
+ }
+ pthread_mutex_unlock(&blkin_init_mutex);
+ return 0;
+}
+
+int blkin_init_new_trace(struct blkin_trace *new_trace, const char *service,
+ const struct blkin_endpoint *endpoint)
+{
+ int res;
+ if (!new_trace) {
+ res = -EINVAL;
+ goto OUT;
+ }
+ new_trace->name = service;
+ blkin_init_trace_info(&(new_trace->info));
+ new_trace->endpoint = endpoint;
+ res = 0;
+
+OUT:
+ return res;
+}
+
+void blkin_init_trace_info(struct blkin_trace_info *trace_info)
+{
+ trace_info->span_id = trace_info->trace_id = random_big();
+ trace_info->parent_span_id = 0;
+}
+
+int blkin_init_child_info(struct blkin_trace *child,
+ const struct blkin_trace_info *parent_info,
+ const struct blkin_endpoint *endpoint,
+ const char *child_name)
+{
+ int res;
+ if ((!child) || (!parent_info) || (!endpoint)){
+ res = -EINVAL;
+ goto OUT;
+ }
+ child->info.trace_id = parent_info->trace_id;
+ child->info.span_id = random_big();
+ child->info.parent_span_id = parent_info->span_id;
+ child->name = child_name;
+ child->endpoint = endpoint;
+ res = 0;
+
+OUT:
+ return res;
+}
+
+int blkin_init_child(struct blkin_trace *child,
+ const struct blkin_trace *parent,
+ const struct blkin_endpoint *endpoint,
+ const char *child_name)
+{
+ int res;
+ if (!parent) {
+ res = -EINVAL;
+ goto OUT;
+ }
+ if (!endpoint)
+ endpoint = parent->endpoint;
+ if (blkin_init_child_info(child, &parent->info, endpoint, child_name) != 0){
+ res = -EINVAL;
+ goto OUT;
+ }
+ res = 0;
+
+OUT:
+ return res;
+}
+
+int blkin_init_endpoint(struct blkin_endpoint *endp, const char *ip,
+ int16_t port, const char *name)
+{
+ int res;
+ if (!endp){
+ res = -EINVAL;
+ goto OUT;
+ }
+ if (!ip)
+ ip = default_ip;
+
+ endp->ip = ip;
+ endp->port = port;
+ endp->name = name;
+ res = 0;
+
+OUT:
+ return res;
+}
+
+int blkin_init_string_annotation(struct blkin_annotation *annotation,
+ const char *key, const char *val, const struct blkin_endpoint *endpoint)
+{
+ int res;
+ if ((!annotation) || (!key) || (!val)){
+ res = -EINVAL;
+ goto OUT;
+ }
+ annotation->type = ANNOT_STRING;
+ annotation->key = key;
+ annotation->val_str = val;
+ annotation->endpoint = endpoint;
+ res = 0;
+
+OUT:
+ return res;
+}
+
+int blkin_init_integer_annotation(struct blkin_annotation *annotation,
+ const char *key, int64_t val, const struct blkin_endpoint *endpoint)
+{
+ int res;
+ if ((!annotation) || (!key)) {
+ res = -EINVAL;
+ goto OUT;
+ }
+ annotation->type = ANNOT_INTEGER;
+ annotation->key = key;
+ annotation->val_int = val;
+ annotation->endpoint = endpoint;
+ res = 0;
+
+OUT:
+ return res;
+}
+
+int blkin_init_timestamp_annotation(struct blkin_annotation *annotation,
+ const char *event, const struct blkin_endpoint *endpoint)
+{
+ int res;
+ if ((!annotation) || (!event)){
+ res = -EINVAL;
+ goto OUT;
+ }
+ annotation->type = ANNOT_TIMESTAMP;
+ annotation->val_str = event;
+ annotation->endpoint = endpoint;
+ res = 0;
+
+OUT:
+ return res;
+}
+
+int blkin_record(const struct blkin_trace *trace,
+ const struct blkin_annotation *annotation)
+{
+ int res;
+ if (!annotation || !trace || !trace->name) {
+ res = -EINVAL;
+ goto OUT;
+ }
+
+ const struct blkin_endpoint *endpoint =
+ annotation->endpoint ? : trace->endpoint;
+ if (!endpoint || !endpoint->ip || !endpoint->name) {
+ res = -EINVAL;
+ goto OUT;
+ }
+
+ if (annotation->type == ANNOT_STRING) {
+ if ((!annotation->key) || (!annotation->val_str)) {
+ res = -EINVAL;
+ goto OUT;
+ }
+ tracepoint(zipkin, keyval_string, trace->name,
+ endpoint->name, endpoint->port, endpoint->ip,
+ trace->info.trace_id, trace->info.span_id,
+ trace->info.parent_span_id,
+ annotation->key, annotation->val_str);
+ }
+ else if (annotation->type == ANNOT_INTEGER) {
+ if (!annotation->key) {
+ res = -EINVAL;
+ goto OUT;
+ }
+ tracepoint(zipkin, keyval_integer, trace->name,
+ endpoint->name, endpoint->port, endpoint->ip,
+ trace->info.trace_id, trace->info.span_id,
+ trace->info.parent_span_id,
+ annotation->key, annotation->val_int);
+ }
+ else {
+ if (!annotation->val_str) {
+ res = -EINVAL;
+ goto OUT;
+ }
+ tracepoint(zipkin, timestamp , trace->name,
+ endpoint->name, endpoint->port, endpoint->ip,
+ trace->info.trace_id, trace->info.span_id,
+ trace->info.parent_span_id,
+ annotation->val_str);
+ }
+ res = 0;
+OUT:
+ return res;
+}
+
+int blkin_get_trace_info(const struct blkin_trace *trace,
+ struct blkin_trace_info *info)
+{
+ int res;
+ if ((!trace) || (!info)){
+ res = -EINVAL;
+ goto OUT;
+ }
+
+ res = 0;
+ *info = trace->info;
+OUT:
+ return res;
+}
+
+int blkin_set_trace_info(struct blkin_trace *trace,
+ const struct blkin_trace_info *info)
+{
+ int res;
+ if ((!trace) || (!info)){
+ res = -EINVAL;
+ goto OUT;
+ }
+
+ res = 0;
+ trace->info = *info;
+OUT:
+ return res;
+}
+
+int blkin_set_trace_properties(struct blkin_trace *trace,
+ const struct blkin_trace_info *info,
+ const char *name,
+ const struct blkin_endpoint *endpoint)
+{
+ int res;
+ if ((!trace) || (!info) || (!endpoint) || (!name)){
+ res = -EINVAL;
+ goto OUT;
+ }
+
+ res = 0;
+ trace->info = *info;
+ trace->name = name;
+ trace->endpoint = endpoint;
+
+OUT:
+ return res;
+}
+
+int blkin_pack_trace_info(const struct blkin_trace_info *info,
+ struct blkin_trace_info_packed *pinfo)
+{
+ if (!info || !pinfo) {
+ return -EINVAL;
+ }
+
+ pinfo->trace_id = __cpu_to_be64(info->trace_id);
+ pinfo->span_id = __cpu_to_be64(info->span_id);
+ pinfo->parent_span_id = __cpu_to_be64(info->parent_span_id);
+
+ return 0;
+}
+
+int blkin_unpack_trace_info(const struct blkin_trace_info_packed *pinfo,
+ struct blkin_trace_info *info)
+{
+ if (!info || !pinfo) {
+ return -EINVAL;
+ }
+
+ info->trace_id = __be64_to_cpu(pinfo->trace_id);
+ info->span_id = __be64_to_cpu(pinfo->span_id);
+ info->parent_span_id = __be64_to_cpu(pinfo->parent_span_id);
+
+ return 0;
+}