weixin_39918248
weixin_39918248
2020-12-08 23:35

Zipkin exporter drops some spans that are accepted if sent directly to Zipkin

Zipkin allow any of the properties of LocalEndpoint and RemoteEndpoint to be absent (see https://zipkin.io/zipkin-api/#/). However, Zipkin exporter used by agent and service drops such spans if they do not have an ip address.

The issue was initially noted with the following setup, but any Zipkin emitter that causes openzipkin.NewEndpoint(serviceName, endpointURI) to return a non-nil error will cause the same:

  1. Start the Zipkin docker image with default settings: docker run --rm -d -p 9411:9411 openzipkin/zipkin.

First, try without agent/collector to see that the spans reach the Zipkin in the container:

  1. Run the python script below
shell
test $ python ./test.py 9411
  1. Verify the Zipkin received the spans

Now introduce the Zipkin receiver and exporter (here using the collector):

  1. Create the following configuration file:
yaml
receivers:
  zipkin:
    port: 9410

exporters:
  zipkin: {}
  1. Launch the collector, using the config file above:
shell
$ go run ./cmd/occollector/main.go --config ./config.yaml
  1. Run the python script below, but, notice the use of port 9410 here so it goes via the collector.
shell
test $ python ./test.py 9410

Result: no spans sent via port 9410 are received by Zipkin, they are being dropped by the exporter.

Expected: spans sent via port 9410 sent to Zipkin since they are the same spans accepted by Zipkin when sent directly to it (via port 9411).

test.py:

python
import sys
import time

from opencensus.trace import execution_context
from opencensus.trace.exporters import zipkin_exporter
from opencensus.trace.tracer import Tracer
from opencensus.trace.samplers import always_on
from opencensus.trace.exporters.transports.background_thread import BackgroundThreadTransport

def function_to_trace():
    time.sleep(1)


def main():
    sampler = always_on.AlwaysOnSampler()
    exporter = zipkin_exporter.ZipkinExporter(service_name="dst-port:" + sys.argv[1], host_name='localhost', port=int(sys.argv[1]), transport=BackgroundThreadTransport)
    tracer = Tracer(sampler=sampler, exporter=exporter)

    with tracer.span(name='root') as root_span:
        tracer.add_attribute_to_current_span(attribute_key='example key',
                                             attribute_value='example value')
        function_to_trace()
        with tracer.span(name='child') as child_span:
            function_to_trace()

    # Get the current tracer
    tracer = execution_context.get_opencensus_tracer()

    # Explicitly create spans
    tracer.start_span()

    # Get current span
    cur_span = execution_context.get_current_span()

    # Explicitly end span
    tracer.end_span()


if __name__ == '__main__':
    main()

该提问来源于开源项目:census-instrumentation/opencensus-service

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

4条回答

  • weixin_39918248 weixin_39918248 5月前

    Fix in PR #229

    点赞 评论 复制链接分享
  • weixin_40003478 weixin_40003478 5月前

    thanks for filing this issue!

    So a) OpenCensus Python ALWAYS fills in a default localEndpoint if one isn't set: * https://github.com/census-instrumentation/opencensus-python/blob/da40cb19b4cce302aeb22177c4102f8f36c4e75e/opencensus/trace/exporters/zipkin_exporter.py#L80 where service_name by default is "my_service" as per https://github.com/census-instrumentation/opencensus-python/blob/da40cb19b4cce302aeb22177c4102f8f36c4e75e/opencensus/trace/exporters/zipkin_exporter.py#L72 * https://github.com/census-instrumentation/opencensus-python/blob/da40cb19b4cce302aeb22177c4102f8f36c4e75e/opencensus/trace/exporters/zipkin_exporter.py#L136-L139 * https://github.com/census-instrumentation/opencensus-python/blob/da40cb19b4cce302aeb22177c4102f8f36c4e75e/opencensus/trace/exporters/zipkin_exporter.py#L161

    So currently the comparison with Python is not apples to oranges as OpenCensus Python ALWAYS sends localEndpoint regardless of if set or not but also the receiver just proxies content.

    The Zipkin v2 API definitely shows that those fields are optional as you've noted so the issue to tackle here is to allow proxying of nodes without endpoints.

    点赞 评论 复制链接分享
  • weixin_39918248 weixin_39918248 5月前

    A small clarification to not cause confusion for someone reading this in the future: the OpenCensus Python sets service name and port, the issue was exposed because there was no valid ip (either v4 or v6) for the localEndpoint.

    点赞 评论 复制链接分享
  • weixin_39918248 weixin_39918248 5月前

    Fixed by #231

    点赞 评论 复制链接分享

相关推荐