C++ opentracing zipkin

Useful page : https://github.com/openzipkin/b3-propagation & other official websites

Steps to run attached scripts

  1. Download opentracing: https://github.com/opentracing/opentracing-cpp
  1. Download and install OpenTracing implementation for Zipkin  : https://github.com/rnburn/zipkin-cpp-opentracing
  2. Download ZipKin backend server :curl -sSL https://zipkin.io/quickstart.sh | bash -s
  3. Run opentracingtest/build.sh
  4. Start zipkin backend: java -jar zipkin.jar
  5. Start ./server
  6. Start ./client
  7. Go to http://localhsot:9411
// text_map_carrier.h, copy from example folder#ifndef LIGHTSTEP_TEXT_MAP_CARRIER#define LIGHTSTEP_TEXT_MAP_CARRIER#include <opentracing/propagation.h>#include <string>#include <unordered_map>using opentracing::TextMapReader;using opentracing::TextMapWriter;using opentracing::expected;using opentracing::string_view;// class textMapCarrierclass TextMapCarrier : public TextMapReader, public TextMapWriter {public:  TextMapCarrier(std::unordered_map<std::string, std::string> &text_map)      : text_map_(text_map) {}  expected<void> Set(string_view key, string_view value) const override {    text_map_[key] = value;    return {};  }  expected<void> ForeachKey(      std::function<expected<void>(string_view key, string_view value)> f)      const override {    for (const auto &key_value : text_map_) {      auto result = f(key_value.first, key_value.second);      if (!result)        return result;    }    return {};  }  std::unordered_map<std::string, std::string> &text_map_;};// span context reader/writer helperstd::string read_span_context(std::unordered_map<std::string, std::string> m){    std::string output = "";    for (auto it = m.cbegin(); it != m.cend(); it++)    {        output += (it->first) + ":" + it->second + ",";    }    return output.substr(0, output.size() - 1);}void write_span_context(std::unordered_map<std::string, std::string> &m, char *context){   char * keypair = strtok(context, ",");   while(keypair != NULL)   {       std::string s(keypair);       std::string::size_type found = s.find_first_of(':');       m.insert(std::pair<std::string, std::string>(s.substr(0,found),s.substr(found+1)));       keypair =strtok(NULL, ",");   }}#endif // LIGHTSTEP_TEXT_MAP_CARRIER
// client.cpp, copy from example folder#include "text_map_carrier.h"#include <unistd.h>#include <sys/types.h>       /* basic system data types */#include <sys/socket.h>      /* basic socket definitions */#include <netinet/in.h>      /* sockaddr_in{} and other Internet defns */#include <arpa/inet.h>       /* inet(3) functions */#include <netdb.h>           /* gethostbyname function */#include <stdlib.h>#include <errno.h>#include <stdio.h>#include <string.h>#include <cassert>#include <iostream>#include <unordered_map>#include <zipkin/opentracing.h>using namespace zipkin;using namespace opentracing;#define MAXLINE 1024int main(){    int socket_fd;    char buf[MAXLINE];    char buf2[MAXLINE];    struct sockaddr_in serv_addr ;    socket_fd = socket(PF_INET, SOCK_STREAM, 0);    bzero( &serv_addr, sizeof(serv_addr) );    serv_addr.sin_family = AF_INET ;       serv_addr.sin_port = htons(39152);        inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr);    ZipkinOtTracerOptions options;    options.service_name = "client_app";    auto tracer = makeZipkinOtTracer(options);    assert(tracer);    auto parent_span = tracer->StartSpan("startMain");    {        auto child_span =            tracer->StartSpan("Step1", {ChildOf(&parent_span->context())});        assert(child_span);        // Set a simple tag.        child_span->SetTag("simple tag", 123);        // Set a complex tag.        child_span->SetTag("complex tag",                Values{123, Dictionary{{"abc", 123}, {"xyz", 4.0}}});        // Log simple values.        child_span->Log({{"event", "simple log"}, {"abc", 123}});        // Log complex values.        child_span->Log({{"event", "complex log"},                {"data", Dictionary{{"a", 1}, {"b", Values{1, 2}}}}});        sleep(1);        child_span->Finish();    }    // Create a follows from span.    {        auto child_span =            tracer->StartSpan("Step1_1", {FollowsFrom(&parent_span->context())});        sleep(1);        // child_span's destructor will finish the span if not done so explicitly.    }    // Use custom timestamps.    {        auto t1 = SystemClock::now();        sleep(1);        auto t2 = SteadyClock::now();        auto span = tracer->StartSpan(                "Step3",                {ChildOf(&parent_span->context()), StartTimestamp(t1)});        assert(span);        span->Finish({FinishTimestamp(t2)});    }    if(connect(socket_fd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) == 0)    {        printf("client starts ...\n");        while(1)        {            static int n = 0;            if( n>=6) break;            char span_name[24];            sprintf(span_name, "request_%d", n++);            auto child_span = tracer->StartSpan(span_name, {ChildOf(&parent_span->context())});            std::unordered_map<std::string, std::string> text_map;            TextMapCarrier carrier(text_map);            auto err = tracer->Inject(child_span->context(), carrier);            std::string contxt = read_span_context(text_map);            // for testing            if(n == 2) sleep(2);                        printf("send message : %d\n", n);            sprintf(buf, "%s\r\n%d",contxt.c_str(), n);            if(write(socket_fd, buf, MAXLINE) == -1)                printf("write error\n");            sleep(1);            // wait for response            while(read(socket_fd, buf2, MAXLINE) == -1) { sleep(1);}            printf("get message from server: %s\n", buf2);            child_span->Finish();        }    }    parent_span->Finish();    tracer->Close();    return 0;}
// server.cpp#include "text_map_carrier.h"#include <unistd.h>#include <sys/types.h>       /* basic system data types */#include <sys/socket.h>      /* basic socket definitions */#include <netinet/in.h>      /* sockaddr_in{} and other Internet defns */#include <arpa/inet.h>       /* inet(3) functions */#include <netdb.h>           /* gethostbyname function */#include <stdlib.h>#include <errno.h>#include <stdio.h>#include <string.h>#include <cassert>#include <iostream>#include <unordered_map>#include <zipkin/opentracing.h>using namespace zipkin;using namespace opentracing;#define MAXLINE 1024#define LISTENQ 1024int main(int argc, char **argv){    int listen_fd, connect_fd;    char buf[MAXLINE];    char buf2[MAXLINE];    socklen_t len;    struct sockaddr_in serv_addr, client_addr;    ZipkinOtTracerOptions options;    options.service_name = "server_app";    auto tracer = makeZipkinOtTracer(options);    listen_fd = socket(PF_INET, SOCK_STREAM, 0);    bzero(&serv_addr, sizeof(serv_addr));    serv_addr.sin_family = AF_INET;              serv_addr.sin_port = htons(39152);    inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) ;    bind(listen_fd, (struct sockaddr*)&serv_addr, sizeof(struct sockaddr_in));     printf("start listening ..\n");    listen(listen_fd, LISTENQ);     for( ; ; )     {        connect_fd = accept(listen_fd, (struct sockaddr*)&client_addr, &len);        if(connect_fd < 0) continue;        printf("accept from %s : %d \n", inet_ntoa(client_addr.sin_addr), client_addr.sin_port);        while(1)        {            if (read(connect_fd, buf, MAXLINE) > -1)            {                char contxt[MAXLINE];                int data;                sscanf(buf,"%s\r\n%d",contxt,&data);                std::unordered_map<std::string, std::string> text_map;                write_span_context(std::ref(text_map),&contxt[0]);                TextMapCarrier carrier(text_map);                auto span_context_maybe = tracer->Extract(carrier);                if(!span_context_maybe)                     printf("error context............\n");                auto span = tracer->StartSpan("receive", {ChildOf(span_context_maybe->get())});                printf("receive message : %d\n", data);                                // for testing                if (data == 4) sleep(2);                sprintf(buf2, "back %d", data);                sleep(1);                if(write(connect_fd, buf2, MAXLINE) == -1)                    printf("write error");                span->Finish();            }            sleep(1);        }        close(connect_fd);        sleep(2);    }    tracer->Close();}
# build.shg++ -g -O0 client.cpp -o client -lcurl -lopentracing -lzipkin -lzipkin_opentracing -pthread -std=c++11g++ -g -O0 server.cpp -o server -lcurl -lopentracing -lzipkin -lzipkin_opentracing -pthread -std=c++11
(0)

相关推荐

  • 全网首发!!C 20新特性全在这一张图里了

    前面我写了C++11.C++14.C++17新特性系列文章,大家可以移步到这里 ↓↓↓ <C++11新特性,所有知识点都在这了!> <C++14新特性的所有知识点全在这儿啦!> ...

  • 分析Zipkin/Brave中的B3

    对 http://www.iocoder.cn/categories/Zipkin/ 的一些补充,分析基于Brave#release-5.11.2分支,可能未来会有所变化 开头先打个广告,我们团队目前 ...

  • zipkin简介

    文章翻译自英文原文:Distributed Tracing: Design and Architecture 先前的博客公告中讨论过为什么Knewton需要一个分布式追踪系统,并且数值可以被添加到一个 ...

  • (4条消息) zipkin

    概述 zipkin为分布式链路调用监控系统,聚合各业务系统调用延迟数据,达到链路调用监控跟踪. 在复杂的调用链路中假设存在一条调用链路响应缓慢,如何定位其中延迟高的服务呢? 日志: 通过分析调用链路上 ...

  • (4条消息) ZipKin原理学习

    ZipKin入门介绍 Zipkin是一款开源的分布式实时数据追踪系统(Distributed Tracking System),基于 Google Dapper的论文设计而来,由 Twitter 公司 ...

  • 调用链选型之Zipkin,Pinpoint,SkyWalking,CAT

    简介Zipkin是Twitter开源的调用链分析工具,目前基于springcloud sleuth得到了广泛的使用,特点是轻量,使用部署简单.Pinpoint是韩国人开源的基于字节码注入的调用链分析, ...