open-telemetry / opentelemetry-go Goto Github PK
View Code? Open in Web Editor NEWOpenTelemetry Go API and SDK
Home Page: https://opentelemetry.io/
License: Apache License 2.0
OpenTelemetry Go API and SDK
Home Page: https://opentelemetry.io/
License: Apache License 2.0
Reference:
The API currently has two forms of event API, one supporting non-lazy usage (Event
) and one supporting lazy usage (AddEvent
). On the one hand, there is a desire to support lazy events. On the other hand, there is a desire not to force allocation of an object for all events.
This may rise to a specification level issue. We have open discussions around SpanData and Sampling and Laziness in general, and it is difficult to separate the event API from this larger discussion.
In OpenTracing, there was support for lazy events, via bulk delivery using an option to the span.Finish()
call. I believe the thinking was that sometimes you want to be lazy and limit the number of events that are buffered (assuming they are buffered). See https://github.com/opentracing/opentracing-go/blob/135aa78c6f95b4a199daf2f0470d231136cbbd0c/span.go#L154
At the same time, some OpenTracing libraries added support for lazy values, which are not the same as lazy events. In this case, I believe the thinking was that a programmer is only concerned with avoiding an expensive serialization when the SDK is not recording a span. See https://github.com/opentracing/opentracing-go/blob/135aa78c6f95b4a199daf2f0470d231136cbbd0c/log/field.go#L149
I will propose that we:
FinishOptions
as in OpenTracingValueType
for lazy serializationEspecially given that the GitHub org name may change, we should consider using an import path that isn't github.com/open-telemetry/opentelemetry-go.
Thoughts on, e.g., setting something up on opentelemetry.io or even opentelemetry.dev (which I think CNCF owns)?
Hi,
Many people in the Go community disagree with singletons: i.e. Package global state. A few people have spoken about them in the past, including this post by Dave Cheney and this post by Peter Bourgon, this talk at gophercon 2016, and this medium post about Aspects of a good Go library.
It is possible to implement the open-telemetry API without package global state. While singletons are clever ways to avoid explicit dependencies, they make the dependencies of an API less clear by hiding dependencies inside package private code rather than parameters. Clear is better than clever.
Singletons create API lock in by disallowing users from injecting their own solutions to dependent libraries if they decide to move away from open-telemetry in the future. More about this is talked about in the post What “accept interfaces, return structs” means in Go
Singletons are a viral API design choice. If a library I depend upon uses Singletons, then I'm forced into their singletons. On the other hand, if a library does not use Singletons and I want to make it Singletons I can. Viral APIs are generally discouraged as they limit the ability to refactor code in the long term.
Singletons make it difficult to piecemeal refactor code by pushing all dependent library code along a single code path. Incremental API change is important for large code bases and was the driving factor for Go's alias proposal.
It is possible to implement the open telemetry described API without singletons. I strongly hope this position can be reconsidered or discussed.
Thanks!
How should the repo/directory should be?
Single Repo
Directory for each module.
Separate repo for API, SDK., etc
Create http plugin for opentelemetry, similar to ochttp plugin for opencensus
As per the spec add tracestate to SpanContext.
The current prototype that was merged into this repository was unfinished work, in part because it was created while the OpenTelemetry specification was not finished.
The prototype included several concepts at the API level that were dedicated to streaming events to an asynchronous or out-of-process observer as part of the PoC. These types, in particular "ScopeID" are not needed for an in-process span and metrics exporter. To complete this work, the API should have a pure interface that an SDK can provide, for example:
The task is to create a SpanData exporter for exporting Zipkin
Implement tracestate propagation.
blocked on #74
Create an OpenCensus shim that bridges opencensus to opentelemetry.
This issue is opened to add unit-test to following packages..
Contributors : For each package open an issue and assign yourself before you work on it.
First will there be an official process to make appeals against the projects design decisions? I am worried that collectively open-telemetry is implementing the former projects designs under what I believe to be a false premise it can "always change things later". I feel such changes will be impossible once the library is in wide spread use.
I have a number of concerns with the actual implementation here but it will be a large effort for me to enumerate them. For now I would like to start with some higher level issues that would resolve many of my code related concerns.
If I could choose a single issue to focus on this would be it, as I feel it creates most of the design issues I have to begin with. This is an issue with the greater OpenTelemetry project as a hole. As far as "openness" OpenTelemetry is a step backwards from OpenTracing. It's placing OpenTelemetry as a gatekeeper of implementations, in fact it defines no formal specifications at all which I reported an issue about open-telemetry/opentelemetry-specification#20 and discuss in this gist. Instead of regurgitating these points in detail here I would ask anyone interested to please read this conversation, to summarize:
OpenTracing - Each SDK provides an interface in opentracing- which trace providers may implement in their own repositories to ship traces, for example
Python API defined in https://github.com/opentracing/opentracing-python and each trace provider must implement this:
Go API defined in https://github.com/opentracing/opentracing-go and each trace provider must implement this:
For tracing to be useful you must have participation from many teams across your organization. It's not uncommon for a request to span many languages (java, C#, Go, Python, Nodejs, ...) at a medium sized company. Thus if you want to provide a new tracer and integrate well with an existing ecosystem you must commit the dev cycles to implement all of these languages. There really is no reason to continue on this path with the "next generation" convergence efforts of "OpenTelemetry" that will leave a footprint on the ecosystem for years.
OpenTelemetry - Each SDK provides no interface as a "standard" design principle (not that I've seen anything resembling a standard design principle as I've echo'd here, in gitter, etc). This project seems to provide an ABI only, which is a step backwards from the API of OpenTracing. In addition it seems there is a drive to have the default OpenTelemetry SDK's all talk to a central "OpenTelemetry" agent which will be bundled with exporters further diminishing "openness". Push for an agent after your SDK's reduces the per-language burden we see above with OpenTracing but inserts OpenTelemetry as the gatekeeper of tracing implementations. At the very worst the "maintainers / governing body / process" could be captured by commerical interests to impede competition. At best it slowly grows to be a more arduous and painful process as layers of "exporters" increase bloat, complexity and reduce maintainability until it's no longer worth the efforts.
MyProposal - Stop writing code. Collectively define a structural specification that will slowly produce the initial version for a wire format for carrying trace events. Separate trace backends from the clients at the protocol level. Now you can resume writing code.
Trace vendors implement 1 server for every language
Open telemetry can provide reference implementations of clients that ship to these trace servers, which is what this repository would become. But this leaves room for those who want to implement their own clients because the chosen balance of ergonomics, performance, was not right for them. As it stands now you have a monumental effort beyond writing a client for a well defined wire-format. If the maintainers of this project disagree with my stance on plugins, great! I don't care. I can write my own client. As it stands I won't have that option without also implementing the glue for the tracer which defeats the purpose of investing resources in these convergence efforts. I really would like to urge the project owners to pump the brakes a little and consider the amount of effort that could spared by taking a different approach. Or at least provide some strong technical reasons to march on with this paradigm that expand beyond "this is what we had".
Unit tests are not just for testing results, they also lock in your public API. Using a large unit tests abstraction that accepts interfaces everywhere means that type changes are possible without breaking unit tests. It also imposes additional cognitive load for potential contributors who are unfamiliar with the chosen libraries. In short they only provide a tool to circumvent engineering rigor, relieving authors of both the responsibility to think about struct composition and the benefits of "testing" the said structures to begin with. I strongly believe the projects quality would suffer substantially by using them.
I am not sure the design considerations behind the scenes that led to requiring a plugin for tracing via "stdout" but I very strongly object. Plugins should be entirely out of the question as an API requirement.
I could continue on, but I feel this is a decent start for a technical debate. The most important argument against plugins is that they may still be provided for proprietary tracing solutions with careful design, you define the Tracer
interface and write a Tracer
which is backed by a plugin
. Knowing this, I think it's easy to prove there is no real reason to circumvent an API to provide an ABI.
First, I feel this project should depend on only the standard library, maybe a couple packages from golang.org/x if well justified. I strongly believe this should be a non-negotiable requirement because it will force a healthier design than what the current tracing libraries of today have. As it stands now this library depends on a massive (257) amount of packages go.sum and this project is just getting started. I understand that part of this is because there is a fundamental problem with the design of OpenTelemetry as a whole providing implementations rather than specifications, but there is still plenty of opportunity to improve here.
Create grpc plugin for opentelemetry, similar to ocgrpc for opencensus
As discussed briefly in the 7/9/2019 OpenTelemetry specification SIG meeting, the current specification does not say exactly how to initialize the SDK, particularly, the standard "global" tracer, meter, and recorder interfaces. It's not clear whether this requires a note in the cross-language specification, but I think we can state requirements for Go here. This is a proposal we might want to adopt:
Given these (proposed) requirements, here is an implementation for Go that works. It requires moving the global setter/getter methods into dedicated packages to avoid an import cycle--it is those global packages that trigger auto-loading the SDK.
We'll port the OpenCensus metricsdata exporter code into this repository.
The Map API is unsafe, as explained by @cstockton in #23 (comment)
Make it a concrete type.
while it's undesirable to call Finish()
more than once, we should probably be more informative than panicking when it happens...
https://gist.github.com/lizthegrey/30ca5c7def588a1bfd3c33041db67d27
The task is to create a SpanData exporter for exporting Jaeger. We think that OpenTelemetry's trace data format will not mature fast enough for users to begin testing the OTel APIs. Therefore, this task is to create a Jaeger span data exporter.
We need a shim to translate OpenTracing API calls into OpenTelemetry API calls.
Concretely, this is an OpenTracing implementation based on the OTel SDK.
This will require more issues to be filed as this task is broken down.
$ go get -u
github.com/open-telemetry/[email protected]: parsing go.mod: unexpected module path "go.opentelemetry.io"
is this a breaking change that I missed at some point, or is it a more structural problem?
I've been following the developing specification and work on the Java SDK. I felt that there were several considerations that applied uniquely in Go, particularly because of its builtin context.Context
, that deserved prototyping. I've just posted a new repository containing this prototype:
https://github.com/lightstep/opentelemetry-golang-prototype
This is not a complete implementation of the OpenTracing and OpenCensus API surface areas. I'm posting this here, now, to have as a point of reference for several of the issues in the specification repo. Some of the high-lights of the approach taken here:
context.Context
to propagate context tags and active scopeKeyValue
construct for span attributes, context tags, resource definitions, log fields, and metric fieldsplugin
package to load implementationsnet/http/httptrace
w/ @iredelmeier's tracecontext.go packageThe first bullet about associating current span context and stats/metrics events bridges the tracing data model with the metrics data model. The APIs here would make this association not an option, as the stats.Record
API takes a context, which passes through to the observer, which could choose to use the span-context association. The prototype includes a stderr exporter that writes a debugging log of events to the console. One of the critical features here, enabled by the low-level observer exporter, is that Span start events can be logged in chronological order, not as the span finishes.
as per this comment.
Exporter interface is currently part of SDK. Ideally it would be nice to have a separate interface that can be reused by other SDKS.
type ExporterType int32
const (
ExporterTypeSync = iota
ExporterTypeAsyncBatched,
// For streaming SDKs
ExporterTypeSyncEvents,
)
type SyncExporter interface {
// implementation cannot block.
ExportSpan(ctx context.Context, span SpanData)
}
type AsyncBatchedExporter interface {
ExportSpans(ctx context.Context, spans []SpanData)
}
type SyncEventsExporter interface {
// implementation cannot block.
ExportSpanEvent(ctx context.Context, event SpanEvent) // These are streaming SDK events.
}
func Register(t ExporterType, e interface{}) {
}
http://github.com/stretchr/testify is a nice library for Go code that helps write cleaner tests. It will be great to introduce this to our codebase.
Documentation is missing/insufficient in many apis. This issue is opened to add the documentation.
Contributors : For each package open an issue and assign yourself before you work on it.
I tried to run the http instance code,and use wireshark to capture network messages,why didn't i find traceID spanID in the http message?
See the specification: open-telemetry/opentelemetry-specification#205
This can be refactored out of the existing code in the sdk/trace
directory.
Add Batched Span Processor that collects all the spans and asynchronously process them.
Allow batch size and batch delay configuration.
Supporting this kind of method requires holding onto the span in memory and prevents streaming implementation. There is no such method in the Java API.
I've read the documentation at https://github.com/open-telemetry/community/blob/master/community-membership.md - I do not see the path to becoming a reviewer- only how to become an approver (by being a reviewer for at least 3 months) or how the current owners were selected. I would like to be involved in the initial design and implementation of this project in whatever ways I can, how do I do that?
My expectation when I started looking at the code base was that I would find mostly concrete implementations of the basic data types (Traces, Spans, SpanContexts, Logs, Measurements, Metrics, etc) with interfaces for vendors to hook into for enriching that data and exporting it either in batch or streaming forms.
Looking through the code base I'm sort of astonished by the number of interfaces that exist over concrete data types.
I realize that vendors want some control over various aspects of the implementation, but starting with making everything an interface seems like a poor design choice to me.
Can anyone explain this or point me to the docs that explain the motivation behind this?
see this comment
Event is currently an interface. It is desirable that this be converted to a concrete Event type with support for lazy loading.
Similar to Span Processor, add metric processor interface for processing metrics.
Provide two metric processor
Hi,
Tracing, logging, and metrics all help observability, but they are very different things. Companies that do one, may not do another. Systems that solve one well look very different from systems that solve another well. There is no clear reason to have them all in one repository, but very compelling reasons to separate them.
The API differences between metrics are tracing are very large. What little they share can be similarly solved with copying. A little copying is better than a little dependency.
People in the past have complained about the size of this repository's public API. It is much bigger than similar repositories that do any of those individually. This size carries a signal of bloat that is antithesis to Go's best practices around smaller libraries that focus and do one thing well. It sends a bad signal to people wanting to evaluate a library's focus.
The standard way to do semantic versioning in Go is modules. Modules work best with git tags to represent semantic versions. Because of the differences between metrics and tracing, it is very likely that a change in the metrics API may not require a change in the tracing API. By putting both in the same repository you potentially force metrics users to do a major version change when tracing updates.
Metrics and logging are very old observability patterns that have had time to mature into a somewhat consistent API. Tracing is much newer and the thoughts around what a good tracing API should look like are currently fragmented. It is possible that opentelemetry may land on a good solution for metric standardization while failing to make the best possible tracing API. Or the other way around, doing tracing very well while failing at some aspect of metrics. By separating these repositories people do not have to feel all in on both or neither.
A well written metrics abstraction should be able to interact with a well written tracing abstraction and a well written logging abstraction. Being separate, interchangeable, and working together is proof the API is flexibly designed.
Hi,
I tried writing a cloudwatch exporter for open census and the API there is not rich enough to do CloudWatch metrics well. I document some of the reasons on the README.md at https://github.com/cep21/cwopencensusexporter
I see open telemetry is based upon open census. Will it have the same problems, or will it work well with CloudWatch?
I've looked over a few metrics APIs and it seems like segment.io's handler is expressive enough for cloudwatch metrics because it lets me handle measures higher up the API stack at https://github.com/segmentio/stats/blob/master/handler.go#L15. Will open telemetry allow the same?
Thanks!
When calling Foreach()
on the tag.Map
, we gain access to every key and value in the map. We can also use Value()
to get access to a value for a specific key. The keys and values returned should essentially be copies of whatever is contained in the map, and usually they are. There are some troublesome members though. Some of them have the pointer-like semantics, so it is possible to mutate them in the Foreach
callback or just in the returned object from Value()
, and thus mutate the contents of the map itself.
Currently that happens for the keys in the map that contain the BYTES Value. So the map implementation should make a copy of the bytes when giving the access to it.
I'm also wondering if the Type
field in registry.Variable
should also be copied, because it is an interface, so it also could have some pointer-like semantics when doing shallow copy during Foreach
.
per issue #51, creating an issue for tracer and considering it assigned to me
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.