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

Observers cannot access native zipkin span instance #156

Open
iamtakingiteasy opened this issue Jun 27, 2020 · 2 comments · May be fixed by #157
Open

Observers cannot access native zipkin span instance #156

iamtakingiteasy opened this issue Jun 27, 2020 · 2 comments · May be fixed by #157

Comments

@iamtakingiteasy
Copy link

iamtakingiteasy commented Jun 27, 2020

Because opentracing observers are passed private spanImpl wrapper, there is no way for observer to extract native zipkin span instance.

As such, it is impossible to implement e.g. centralized unfinished spans flushing using current state of the library.

Also SpanObserver interface does not provide methods for log/annotation changes.

To address both issues, I suggest introducing new interfaces

// ZipkinStartSpanOptions allows ZipkinObserver.OnStartSpan() to inspect
// options used during zipkin.Span creation
type ZipkinStartSpanOptions struct {
	// Parent span context reference, if any
	Parent *model.SpanContext

	// Span's start time
	StartTime time.Time

	// Kind clarifies context of timestamp, duration and remoteEndpoint in a span.
	Kind model.Kind

	// Tags used during span creation
	Tags map[string]string

	// RemoteEndpoint used during span creation
	RemoteEndpoint *model.Endpoint
}

// ZipkinObserver may be registered with a Tracer to receive notifications about new Spans
type ZipkinObserver interface {
	// OnStartSpan is called when new Span is created. Creates and returns span observer.
	// If the observer is not interested in the given span, it must return nil.
	OnStartSpan(sp zipkin.Span, operationName string, options ZipkinStartSpanOptions) ZipkinSpanObserver
}

// ZipkinSpanObserver is created by the ZipkinObserver and receives notifications about
// other Span events.
type ZipkinSpanObserver interface {
	// Callback called from zipkin.Span.SetName()
	OnSetName(operationName string)

	// Callback called from zipkin.Span.SetTag()
	OnSetTag(key, value string)

	// Callback called from zipkin.Span.SetRemoteEndpoint()
	OnSetRemoteEndpoint(remote *model.Endpoint)

	// Callback called from zipkin.Span.Annotate()
	OnAnnotate(t time.Time, annotation string)

	// Callback called from zipkin.Span.Finish()
	OnFinish()

	// Callback called from zipkin.Span.FinishedWithDuration()
	OnFinishedWithDuration(dur time.Duration)
}

And new tracer option

WithZipkinObserver(zipkinObserver ZipkinObserver) TracerOption
iamtakingiteasy added a commit to iamtakingiteasy/zipkin-go-opentracing that referenced this issue Jun 27, 2020
@iamtakingiteasy iamtakingiteasy linked a pull request Jun 27, 2020 that will close this issue
iamtakingiteasy added a commit to iamtakingiteasy/zipkin-go-opentracing that referenced this issue Jun 27, 2020
iamtakingiteasy added a commit to iamtakingiteasy/zipkin-go-opentracing that referenced this issue Jun 27, 2020
iamtakingiteasy added a commit to iamtakingiteasy/zipkin-go-opentracing that referenced this issue Jun 27, 2020
iamtakingiteasy added a commit to iamtakingiteasy/zipkin-go-opentracing that referenced this issue Jun 27, 2020
iamtakingiteasy added a commit to iamtakingiteasy/zipkin-go-opentracing that referenced this issue Jun 27, 2020
iamtakingiteasy added a commit to iamtakingiteasy/zipkin-go-opentracing that referenced this issue Jun 27, 2020
iamtakingiteasy added a commit to iamtakingiteasy/zipkin-go-opentracing that referenced this issue Jun 28, 2020
iamtakingiteasy added a commit to iamtakingiteasy/zipkin-go-opentracing that referenced this issue Jun 28, 2020
iamtakingiteasy added a commit to iamtakingiteasy/zipkin-go-opentracing that referenced this issue Jun 28, 2020
iamtakingiteasy added a commit to iamtakingiteasy/zipkin-go-opentracing that referenced this issue Jun 28, 2020
@jcchavezs
Copy link
Contributor

jcchavezs commented Jun 30, 2020

Interesting, so your use case is to access the list of unfinished spans, any particular reason?. While I think about it I will friendly ping @adriancole to see if there is such use cases somewhere else.

For now I can mention that in libraries like zipkin-js after some due time we flush unfinished spans to the server with a annotation called zipkin-js.flush which was actually inspired in brave.flush so I guess brave has this feature. Also this very library has the ability to not to flush spans by default, transferring that responsibility to the user.

@iamtakingiteasy
Copy link
Author

Yes, I have use-case of flushing unfinished spans, when span is covering long-running operation, such as incoming bidirectional GRPC stream with events going both ways and each possibly causing child spans of execution.

In this case, stream may very well last for many hours or even days, so any sampling information may easily get lost unless span is regularly flushed. In my target use-case I intend flushing on every child span finish and with configurable rates/intervals.

While library itself might benefit from global flush timeout specifically, I still think it would be best to allow for implementation of custom flushing policies using observers as well.

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 a pull request may close this issue.

2 participants