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

Monitoring platform events with zipkin-go and opentracing #50

Merged
merged 5 commits into from
Jun 22, 2017

Conversation

hkshaw1990
Copy link
Contributor

Perf events can provide additional insights into the performance of a
span or a sequence of spans in a trace. This patch includes the use of
a library called
"perfevents" (https://github.com/opentracing-contrib/perfevents) which
can be simply imported and used. This library is an abstraction of the
platform side of counters and operations. Right now, only the generic
perf events are supported. With this patch, one should be able to find
out the cpu-cycles, instructions, cache-references, cache-misses,
branch-instructions, branch-misses and bus cycles for a span.

The required event(s) should be supplied in the form of a string(comma
separated list if there are multiple events to be monitored) to the
StartSpan call and then, the opentracing-go library and the
zipkin-go-opentracing library should take over from there. As soon as
the span is closed, the perf event(s) count is logged with span.Log().

An example to use this with a span :
// start a span with perfevents
sp = tracer.StartSpan("read_file",
opentracing.PerfString("cache-misses,cpu-cycles"))

Upon closing the span, the events stop monitoring and are destroyed afer
the data is sent for logging.

Perf events can provide additional insights into the performance of a
span or a sequence of spans in a trace. This patch includes the use of
a library called
"perfevents" (https://github.com/opentracing-contrib/perfevents) which
can be simply imported and used. This library is an abstraction of the
platform side of counters and operations. Right now, only the generic
perf events are supported. With this patch, one should be able to find
out the cpu-cycles, instructions, cache-references, cache-misses,
branch-instructions, branch-misses and bus cycles for a span.

The required event(s) should be supplied in the form of a string(comma
separated list if there are multiple events to be monitored) to the
StartSpan call and then, the opentracing-go library and the
zipkin-go-opentracing library should take over from there. As soon as
the span is closed, the perf event(s) count is logged with span.Log().

An example to use this with a span :
// start a span with perfevents
sp = tracer.StartSpan("read_file",
opentracing.PerfString("cache-misses,cpu-cycles"))

Upon closing the span, the events stop monitoring and are destroyed afer
the data are sent for logging.

Signed-off-by: Hemant Kumar <hemant@linux.vnet.ibm.com>
@hkshaw1990
Copy link
Contributor Author

opentracing/spec Issue in refernce : opentracing/specification#36
PR to opentracing-go : opentracing/opentracing-go#135

Also, the travis error mentioned above is because the perfevents package is not yet upstream :
PR to perfevents : opentracing-contrib/perfevents#1

Use PerfEvent tag to check if perfevents needs to be initialized, if
yes, initialize them.

Signed-off-by: Hemant Kumar <hemant@linux.vnet.ibm.com>
@hkshaw1990
Copy link
Contributor Author

Added one more commit to this PR to use tags instead of span options to start the perfevents.

@basvanbeek
Copy link
Member

I like the idea of being able to have these metrics inside spans, but not in the proposed current implementation where it breaks cross platform compatibility. I think most will depend on the outcome of: opentracing/opentracing-go#136

@hkshaw1990
Copy link
Contributor Author

Hi @basvanbeek
I am currently looking into the approach of an observer interface (as in the issue you referenced and this PR from Yuri : jaegertracing/jaeger-client-go#94)
Thanks!

@hkshaw1990
Copy link
Contributor Author

hkshaw1990 commented Mar 15, 2017

Hi,
Regarding the discussion which is going on here opentracing/opentracing-go#135 (comment) for an Observer interface, would love to hear some thoughts on having an Observer interface and an implementation in zipkin.

@basvanbeek
Copy link
Member

@hkshaw1990 unfortunately I have too much on my plate at the moment to look at an Observer interface more closely but I definitely don't dismiss the idea of one existing.

In the mean time you could investigate a POC and adjust the PR to include this logic through an Observer interface and make it easier for all of us to look at the implications for the project as a whole. Since I consider the platform events logic as something for consumers to opt-in on, I would like the implementation of the Observer interface be neither obtrusive nor performance impeding.

Metrics are useful to gain insights in a distributed application. But
there can be a lot of metrics in different domains. Adding such metrics
from one domain (metrics exporter pkg) into zipkin is not good for
cross platform compatibility.
This commit adds a new observer and span observer API which defines a
standard interface to add such metrics. To expose the metrics, one would
have to implement the observer interface in the metrics
exporter. zipkin will need to implement this interface and install
callbacks for methods such as StartSpan, SetOperationName, SetTag and
Finish. The registered callbacks would then be called on the span events
if an observer is created.

This is based on the work done by Yuri here :
jaegertracing/jaeger-client-go#94

Signed-off-by: Yuri Shkuro <yurishkuro@users.noreply.github.com>
Signed-off-by: Hemant Kumar <hemant@linux.vnet.ibm.com>
@hkshaw1990
Copy link
Contributor Author

@basvanbeek I have added a commit as a POC to add an API for the Observer interface and its implementation.

Copy link
Member

@basvanbeek basvanbeek left a comment

Choose a reason for hiding this comment

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

A few items to take care of and then LGTM

observer.go Outdated
// observer := myobserver.NewObserver()
// tracer := zipkin.NewTracer(..., zipkin.WithObserver(observer))
//
type Observer interface {
Copy link
Member

Choose a reason for hiding this comment

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

Please remove the Observer interface here and use the one you created in https://github.com/opentracing-contrib/go-observer. You can pull PR opentracing-contrib/go-observer#2 to fix the missing dependencies to opentracing-go

Copy link
Contributor Author

Choose a reason for hiding this comment

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

WIll do and thanks for the PR!

observer.go Outdated
// other Span events.
// zipkin should define these functions for each of the span operations
// which should call the registered (observer) callbacks.
type SpanObserver interface {
Copy link
Member

Choose a reason for hiding this comment

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

Same as Observer. This one can be removed

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yup.

observer.go Outdated

// noopSpanObserver is used when there are no observers registered on the
// Tracer or none of them returns span observers
var noopSpanObserver = spanObserver{}
Copy link
Member

@basvanbeek basvanbeek Jun 18, 2017

Choose a reason for hiding this comment

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

I added a NoopSpanObserver implementation to opentracing-contrib/go-observer.

If you use that one we don't try to range over SpanObservers when calling one of the SpanObserver methods

EDIT: Yuri told me it is fine to return nil, isn't that a much better idea?

Copy link
Contributor Author

@hkshaw1990 hkshaw1990 Jun 20, 2017

Choose a reason for hiding this comment

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

Yeah, makes sense to return a nil.

span.go Outdated
@@ -29,6 +29,7 @@ type Span interface {
type spanImpl struct {
tracer *tracerImpl
event func(SpanEvent)
Observer SpanObserver
Copy link
Member

Choose a reason for hiding this comment

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

do not export the SpanObserver variable as it is not needed and direct external access to it is undesirable.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, will change this.

@hkshaw1990
Copy link
Contributor Author

@basvanbeek added the changes which uses the go-observer interfaces and addresses the review comments.

@basvanbeek
Copy link
Member

Thanks @hkshaw1990 for your patience with this.

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.

2 participants