Zipkin is a distributed tracing system. It is an open source system that is developed by Twitter to trace real-time data. Zipkin gathers real-time monitoring data from various heterogeneous systems. You can use Zipkin to submit the trace data of a Go application to the Tracing Analysis console.

Prerequisites

To obtain an endpoint of Jaeger or Zipkin, perform the following steps:
  1. Log on to the Tracing Analysis console.
  2. In the left-side navigation pane, click Cluster Configurations. Then, click the Access point information tab.
  3. In the top navigation bar, select a region. In the Cluster Information section, turn on Show Token.
  4. In the Client section, click Jaeger or Zipkin.

    Obtain an endpoint of Jaeger or Zipkin in the Related Information column of the table in the lower part.

    Endpoint of Jaeger or Zipkin
    Note If your application is deployed in an Alibaba Cloud production environment, use an access point of Alibaba Cloud VPC. Otherwise, use a public endpoint. Generally, use the endpoint of v2 for Zipkin. Use the endpoint of v1 only if you know Zipkin well.

Background information

The following figure shows how to report data by using Zipkin.Use Zipkin to report data

Instrument the application

Before you use Zipkin to submit the trace data of a Go application to the Tracing Analysis console, you must instrument the application.

  1. Add dependencies:
    [[constraint]]
      name = "github.com/openzipkin/zipkin-go"
      version = "0.1.1"
    
    [[constraint]]
      name = "github.com/gorilla/mux"
      version = "1.6.2"
  2. Create a tracer. You can use tracers to create spans that record the time of distributed operations. Tracers contain information such as the endpoint from which data is submitted, the IP address of the on-premises machine, and the sampling rate. You can adjust the sampling rate to reduce the cost of submitting data:
    func getTracer(serviceName string, ip string) *zipkin.Tracer {
      // create a reporter to be used by the tracer
      reporter := httpreporter.NewReporter("http://tracing-analysis-dc-hz.aliyuncs.com/adapt_aokcdqnxyz@123456ff_abcdef123@abcdef123/api/v2/spans")
      // set-up the local endpoint for our service
      endpoint, _ := zipkin.NewEndpoint(serviceName, ip)
      // set-up our sampling strategy
      sampler := zipkin.NewModuloSampler(1)
      // initialize the tracer
      tracer, _ := zipkin.NewTracer(
        reporter,
        zipkin.WithLocalEndpoint(endpoint),
        zipkin.WithSampler(sampler),
      )
      return tracer;
    }
  3. Record the request data:
    // tracer can now be used to create spans.
    span := tracer.StartSpan("some_operation")
    // ... do some work ...
    span.Finish()
    // Output:
    Note

    You can run the preceding code to create a root span that records the root operation of a request. If you need to record the previous and next operations of a request, inject a context. Example:

    childSpan := tracer.StartSpan("some_operation2", zipkin.Parent(span.Context()))
        // ... do some work ...
    childSpan.Finish()
  4. Optional:You can add custom tags to a span to troubleshoot errors. For example, you can check whether an error occurs, record the return value of a request, or configure the error message.

    Add a custom tag:

    childSpan.Tag("http.status_code", statusCode)

    Create a custom error message:

    childSpan := tracer.StartSpan("some_operation2", zipkin.Parent(span.Context()))
    // ... do some work ...
    var events = make(map[string]string)
    events["event"] = "error"
    events["stack"] = "Runtime Exception: unable to find userid"
    jsonStr, err := json.Marshal(events)
    if err == nil {
       childSpan.Annotate(time.Now(), string(jsonStr))
    }
    childSpan.Finish()
  5. In a distributed system, remote procedure call (RPC) requests are sent together with the trace data. The trace data includes the values of the TraceId, ParentSpanId, SpanId, and Sampled parameters. You can call the Extract or Inject method to specify data in HTTP request headers. The following example shows how to call the Extract or Inject method to specify data in HTTP request headers:
       Client Span                                                Server Span
    ┌──────────────────┐                                       ┌──────────────────┐
    │                  │                                       │                  │
    │   TraceContext   │           HTTP Request Headers        │   TraceContext   │
    │ ┌──────────────┐ │          ┌───────────────────┐        │ ┌──────────────┐ │
    │ │ TraceId      │ │          │ X-B3-TraceId      │        │ │ TraceId      │ │
    │ │              │ │          │                   │        │ │              │ │
    │ │ ParentSpanId │ │ Inject   │ X-B3-ParentSpanId │Extract │ │ ParentSpanId │ │
    │ │              ├─┼─────────>│                   ├────────┼>│              │ │
    │ │ SpanId       │ │          │ X-B3-SpanId       │        │ │ SpanId       │ │
    │ │              │ │          │                   │        │ │              │ │
    │ │ Sampled      │ │          │ X-B3-Sampled      │        │ │ Sampled      │ │
    │ └──────────────┘ │          └───────────────────┘        │ └──────────────┘ │
    │                  │                                       │                  │
    └──────────────────┘                                       └──────────────────┘
    Note Zipkin allows you to pass context information by using the HTTP protocol or gRPC framework.
    1. Call the Inject method on the client to specify the context information:
      req, _ := http.NewRequest("GET", "/", nil)
      // configure a function that injects a trace context into a reques
      injector := b3.InjectHTTP(req)
      injector(sp.Context())
    2. Call the Extract method on the server to extract the context information:
      req, _ := http.NewRequest("GET", "/", nil)
              b3.InjectHTTP(req)(sp.Context())
      
              b.ResetTimer()
              _ = b3.ExtractHTTP(copyRequest(req))

Getting started with Data Encryption Service

The following example shows how to use Zipkin to submit the trace data of a Go application.

  1. Download the Demo file.
  2. Change the endpoint from which data is submitted in the utils.go file.
    Important Replace <endpoint> with the endpoint of the region where the client resides. You can obtain the endppoint on the Overview page in the Tracing Analysis console. For more information, see the Prerequisites topic.
  3. Install the following dependency:
    dep ensure
  4. Run the test program:
    go run main.go

    On the Applications page in the Tracing Analysis console, click the name of the application. On the page that appears, view the trace data.

FAQ

Why is no data submitted?

You can check the error message that is returned when the program is running and check whether the endpoint_url parameter is valid. For example, if the failed the request with status code 403 message is returned, the username or password is invalid.