def zipkin_tween(handler, registry):
    """
    Factory for pyramid tween to handle zipkin server logging. Note that even
    if the request isn't sampled, Zipkin attributes are generated and pushed
    into threadlocal storage, so `create_http_headers_for_new_span` and
    `zipkin_span` will have access to the proper Zipkin state.

    Consumes custom create_zipkin_attr function if one is set in the pyramid
    registry.

    :param handler: pyramid request handler
    :param registry: pyramid app registry

    :returns: pyramid tween
    """
    def tween(request):
        zipkin_settings = _get_settings_from_request(request)
        tracer = get_default_tracer()

        tween_kwargs = dict(
            service_name=zipkin_settings.service_name,
            span_name=zipkin_settings.span_name,
            zipkin_attrs=zipkin_settings.zipkin_attrs,
            transport_handler=zipkin_settings.transport_handler,
            host=zipkin_settings.host,
            port=zipkin_settings.port,
            add_logging_annotation=zipkin_settings.add_logging_annotation,
            report_root_timestamp=zipkin_settings.report_root_timestamp,
            context_stack=zipkin_settings.context_stack,
            max_span_batch_size=zipkin_settings.max_span_batch_size,
            encoding=zipkin_settings.encoding,
            kind=Kind.SERVER,
        )

        if zipkin_settings.firehose_handler is not None:
            tween_kwargs['firehose_handler'] = zipkin_settings.firehose_handler

        with tracer.zipkin_span(**tween_kwargs) as zipkin_context:
            response = handler(request)
            if zipkin_settings.use_pattern_as_span_name and request.matched_route:
                zipkin_context.override_span_name('{} {}'.format(
                    request.method,
                    request.matched_route.pattern,
                ))
            zipkin_context.update_binary_annotations(
                get_binary_annotations(request, response),
            )

            if zipkin_settings.post_handler_hook:
                zipkin_settings.post_handler_hook(request, response)

            return response

    return tween
Factory for pyramid tween to handle zipkin server logging. Note that even
    if the request isn't sampled, Zipkin attributes are generated and pushed
    into threadlocal storage, so `create_http_headers_for_new_span` and
    `zipkin_span` will have access to the proper Zipkin state.

    Consumes custom create_zipkin_attr function if one is set in the pyramid
    registry.

    :param handler: pyramid request handler
    :param registry: pyramid app registry

    :returns: pyramid tween