Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added batch spans sending #52

Conversation

dmitry-prokopchenkov
Copy link
Contributor

@dmitry-prokopchenkov dmitry-prokopchenkov commented Jul 18, 2017

This is a pr for #6

Guys, I have a question. I didn't provide a backward compatibility in this pull request. After my changes in thrift encoding code this example from the docs won't work:

import requests

def http_transport(encoded_span):
    # The collector expects a thrift-encoded list of spans. Instead of
    # decoding and re-encoding the already thrift-encoded message, we can just
    # add header bytes that specify that what follows is a list of length 1.
    body = '\x0c\x00\x00\x00\x01' + encoded_span
    requests.post(
        'http://localhost:9411/api/v1/spans',
        data=body,
        headers={'Content-Type': 'application/x-thrift'},
    )

I think here we breach encapsulation of thrift encoding logic by adding '\x0c\x00\x00\x00\x01'. In the pull request the count of thrift objects is defined automatically and can be hided from client. So the modified version of this example would be:

import requests

def http_transport(encoded_span):
    requests.post(
        'http://localhost:9411/api/v1/spans',
        data=encoded_span,
        headers={'Content-Type': 'application/x-thrift'},
    )

I can provide a backward compatibility by adding a 'batch' flag to zipkin_span constructor, but I prefer not to do it without your feedback. Please advise.

@coveralls
Copy link

coveralls commented Jul 18, 2017

Coverage Status

Coverage remained the same at 100.0% when pulling 6b2e7c2 on dmitry-prokopchenkov:dprokopchenkov-send-batches-of-spans into 4f53165 on Yelp:master.

@coveralls
Copy link

coveralls commented Jul 18, 2017

Coverage Status

Coverage remained the same at 100.0% when pulling 85a9ebf on dmitry-prokopchenkov:dprokopchenkov-send-batches-of-spans into 4f53165 on Yelp:master.

Copy link
Contributor

@bplotnick bplotnick left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks so much for submitting this. You're right about the leaky abstraction of the encoding of the span!

This mostly looks good, but I'm concerned that if a client doesn't call flush, then you could potentially get queued spans that are never emitted. I believe zipkin-reporter-java handles this by using a sending thread with a timeout so that the max sending delay is bounded. I wonder if we can do the same here?

@kaisen We will need to adjust a few internal tools before using this anywhere to check for the type of the thrift message: https://github.com/openzipkin/zipkin/blob/release-1.28.1/zipkin-collector/kafka/src/main/java/zipkin/collector/kafka/KafkaStreamProcessor.java#L62

@@ -4,7 +4,8 @@
import struct

import thriftpy
from thriftpy.protocol.binary import TBinaryProtocol
from thriftpy.protocol.binary import TBinaryProtocol, write_list_begin
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We split imports into one per line. If you run pre-commit, it should fix this. I believe pre-commit should be run as part of tox.

span = create_span(
class ZipkinBatchSender(object):

MAX_PORTION_SIZE = 100
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you make this configurable?

@kaisen
Copy link
Member

kaisen commented Jul 22, 2017

@bplotnick if I'm reading the code right, it looks like we won't have to worry about spans not being sent because flush() is always called with the logging context manager exits. Unless you're thinking about another corner case?

Still reviewing this PR.

@bplotnick
Copy link
Contributor

@kaisen My concern was not with log_spans, but rather if someone uses ZipkinBatchSender separately. Perhaps we can call flush in the ZipkinBatchSender destructor?

@coveralls
Copy link

coveralls commented Jul 24, 2017

Coverage Status

Coverage remained the same at 100.0% when pulling bd6a025 on dmitry-prokopchenkov:dprokopchenkov-send-batches-of-spans into 4f53165 on Yelp:master.

@dmitry-prokopchenkov
Copy link
Contributor Author

@bplotnick re: flush(). I don't think zipkin-reporter-java with its timeouts is suitable for our case, because here we encode all spans together in zipkin_span.stop(). But we can use ZipkinBatchSender as a context manager and do flush() at __exit__().

@dmitry-prokopchenkov
Copy link
Contributor Author

Guys, looking forward to your feedback about the latest changes

Copy link
Member

@kaisen kaisen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looking good!

@@ -142,13 +142,9 @@ your Zipkin collector is running at localhost:9411.
import requests

def http_transport(encoded_span):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A comment describing what type/format encoded_span is expected to be would be useful.

timestamp_s,
duration_s,
)
self._add_span_to_queue(thrift_span)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'm thinking we don't need a separate function just to add it to the queue. i'm ok with _add_span_to_queue's logic be inside add_span

message = thrift_obj_in_bytes(span)
transport_handler(message)
):
if not self.transport_handler:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i believe this check is unnecessary. a logging context is only created if perform_logging is True, which is only True if (self.zipkin_attrs or self.sampling_rate is not None) which requires a check for self.transport_handler.

@@ -126,6 +127,9 @@ def __init__(
:param transport_handler: Callback function that takes a message parameter
and handles logging it
:type transport_handler: function
:param max_span_portion_size: Spans in a trace are sent in batches,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doesn't matter too much but i would prefer 'max_span_batch_size'. @bplotnick thoughts?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I like the idea of having "batch" somewhere in the name, considering the batch sender class is called ZipkinBatchSender

@@ -1,5 +1,5 @@
import pytest
from thriftpy.protocol.binary import TBinaryProtocol
from thriftpy.protocol.binary import TBinaryProtocol, read_list_begin
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 separate import lines for this

@dmitry-prokopchenkov
Copy link
Contributor Author

@kaisen, @bplotnick Please verify my latest commit. I took into account all your comments.

@coveralls
Copy link

coveralls commented Jul 26, 2017

Coverage Status

Coverage remained the same at 100.0% when pulling bdef103 on dmitry-prokopchenkov:dprokopchenkov-send-batches-of-spans into 4f53165 on Yelp:master.

1 similar comment
@coveralls
Copy link

Coverage Status

Coverage remained the same at 100.0% when pulling bdef103 on dmitry-prokopchenkov:dprokopchenkov-send-batches-of-spans into 4f53165 on Yelp:master.

@dmitry-prokopchenkov
Copy link
Contributor Author

Guys?

@kaisen
Copy link
Member

kaisen commented Jul 31, 2017

Sorry for the delay @dmitry-prokopchenkov. This looks good to me. @bplotnick ?

@bplotnick
Copy link
Contributor

:shipit:

@bplotnick bplotnick merged commit 275789a into Yelp:master Jul 31, 2017
@bplotnick
Copy link
Contributor

Merged. I'll release a 0.9.0 in a bit with these changes. Thanks so much for this work @dmitry-prokopchenkov!!

@dmitry-prokopchenkov
Copy link
Contributor Author

@bplotnick thanks! I really need this version in pip to complete my current task) When are you going to release this?

@bplotnick
Copy link
Contributor

@kaisen I released 0.9.0 yesterday, but it didn't get uploaded to the public pypi (for some reason, i thought we had this automated). Can you do this so @dmitry-prokopchenkov can use the release?

@bplotnick
Copy link
Contributor

@dmitry-prokopchenkov v0.9.0 is now on pypi

@dmitry-prokopchenkov
Copy link
Contributor Author

@bplotnick , @kaisen Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants