openzipkin / zipkin-go Goto Github PK
View Code? Open in Web Editor NEWZipkin distributed tracing library for go.
License: Apache License 2.0
Zipkin distributed tracing library for go.
License: Apache License 2.0
I see https://zipkin.io/pages/quickstart.html
run docker run -p 9411:9411 openzipkin/zipkin
, then see https://github.com/openzipkin/zipkin-go#usage-and-examples
and created a http server by modifying https://github.com/openzipkin/zipkin-go/blob/70244c9703277c13566aac289c530a1143b14cf5/example_httpserver_test.go
package main
import (
"log"
"net/http"
"os"
"time"
"github.com/gorilla/mux"
zipkin "github.com/openzipkin/zipkin-go"
zipkinhttp "github.com/openzipkin/zipkin-go/middleware/http"
logreporter "github.com/openzipkin/zipkin-go/reporter/log"
)
func main() {
// set up a span reporter
reporter := logreporter.NewReporter(log.New(os.Stderr, "", log.LstdFlags))
defer reporter.Close()
// create our local service endpoint
endpoint, err := zipkin.NewEndpoint("myService", "localhost:9411")
if err != nil {
log.Fatalf("unable to create local endpoint: %+v\n", err)
}
// initialize our tracer
tracer, err := zipkin.NewTracer(reporter, zipkin.WithLocalEndpoint(endpoint))
if err != nil {
log.Fatalf("unable to create tracer: %+v\n", err)
}
// create global zipkin http server middleware
// serverMiddleware := zipkinhttp.NewServerMiddleware(
// tracer, zipkinhttp.TagResponseSize(true),
// )
// create global zipkin traced http client
client, err := zipkinhttp.NewClient(tracer, zipkinhttp.ClientTrace(true))
if err != nil {
log.Fatalf("unable to create client: %+v\n", err)
}
// initialize router
router := mux.NewRouter()
// // start web service with zipkin http server middleware
// ts := httptest.NewServer(serverMiddleware(router))
// defer ts.Close()
// set-up handlers
// router.Methods("GET").Path("/some_function").HandlerFunc(someFunc(client, ts.URL))
router.Methods("GET").Path("/").HandlerFunc(otherFunc(client))
log.Fatal(http.ListenAndServe("localhost:8080", router))
// // initiate a call to some_func
// req, err := http.NewRequest("GET", ts.URL+"/some_function", nil)
// if err != nil {
// log.Fatalf("unable to create http request: %+v\n", err)
// }
// res, err := client.DoWithAppSpan(req, "some_function")
// if err != nil {
// log.Fatalf("unable to do http request: %+v\n", err)
// }
// res.Body.Close()
// Output:
}
// func someFunc(client *zipkinhttp.Client, url string) http.HandlerFunc {
// return func(w http.ResponseWriter, r *http.Request) {
// log.Printf("some_function called with method: %s\n", r.Method)
// // retrieve span from context (created by server middleware)
// span := zipkin.SpanFromContext(r.Context())
// span.Tag("custom_key", "some value")
// // doing some expensive calculations....
// time.Sleep(25 * time.Millisecond)
// span.Annotate(time.Now(), "expensive_calc_done")
// newRequest, err := http.NewRequest("POST", url+"/other_function", nil)
// if err != nil {
// log.Printf("unable to create client: %+v\n", err)
// http.Error(w, err.Error(), 500)
// return
// }
// ctx := zipkin.NewContext(newRequest.Context(), span)
// newRequest = newRequest.WithContext(ctx)
// res, err := client.DoWithAppSpan(newRequest, "other_function")
// if err != nil {
// log.Printf("call to other_function returned error: %+v\n", err)
// http.Error(w, err.Error(), 500)
// return
// }
// res.Body.Close()
// }
// }
func otherFunc(client *zipkinhttp.Client) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
log.Printf("other_function called with method: %s\n", r.Method)
time.Sleep(50 * time.Millisecond)
}
}
Start the app
go run main.go
Made a request curl http://localhost:8080/
However, no trace to be seen in http://localhost:9411/.
I don't understand nothing, but without knowing almost nothing but it just work may help newbies like me.
Please give me a complete source code of woking http server that can work with local zipkin server if you please.
Thanks.
@anuraaga care to do the honors of updating the README, now that we have gRPC middleware?
Lately I saw many traces including the http.request.size=0
in some server spans and I am thinking this is just adding buzz when it comes to GET
requests or when the value is zero
. What do you think?
Currently there if using NewEndpoint("name", ":1993")
does not provide the same effect as &Endpoint{ServiceName: "name", Port: 1993}
, should they have the same behavour?
ping @basvanbeek
Currently when writing a test that has a tracer as dependency, there is no easy way to create a noop
tracer.
Required code for a noop tracer is:
noopSampler := NewBoundarySampler(0, 123)
tr := &Tracer{
reporter: reporter.NewNoopReporter(),
noop: 1,
sampler: noopSampler
}
Having a function would be nice.
Ping @basvanbeek @adriancole
There are some use cases where a 4xx server response does not mean an error at all. For example, an auth service would have a 403 as a response and marking it an error would be meaningless as there is nothing wrong here, it just the coupling inherited from the REST spec.
I would say this is more specific for server instrumentation as for the client a 403 is still an error (does not have to know the internals of the server returning the 403). I envision this as an option for the server middleware.
Ping @openzipkin/core
Can we export noopSpan type or let me know how else I could check whether a given span is a noopSpan?
Thank you again for all your work on this repository and for answering my questions.
I just encountered an issue whereby I am intercepting Zipkin spans from arbitrary sources, parsing them using this library and then processing them and then on the exit users can choose to export them back to Zipkin. For this I need to have a verification test that the intercepted spans' serialization matches almost exactly.
However, when I do
endpoint, err := openzipkin.NewEndpoint("foo", "[7::80:807f]:0")
I get back
&model.Endpoint{ServiceName:"frontend", IPv4:net.IP{0x0, 0x0, 0x0, 0x0}, IPv6:net.IP{0x0, 0x7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, 0x80, 0x7f}, Port:0x0}
when then reflects in my roundtrip tests as
[{"timestamp":1472470996199000,"duration":207000,"traceId":"4d1e00c0db9010db86154a4ba6e91385","id":"4d1e00c0db9010db","parentId":"86154a4ba6e91385","name":"get","kind":"CLIENT","localEndpoint":{"serviceName":"frontend","ipv4":"0.0.0.0","ipv6":"7::80:807f"},"remoteEndpoint":{"serviceName":"backend","ipv4":"192.168.99.101","port":9000},"annotations":[{"timestamp":1472470996238000,"value":"foo"},{"timestamp":1472470996403000,"value":"bar"}],"tags":{"clnt/finagle.version":"6.45.0","http.path":"/api"}},{"timestamp":1472470996199000,"duration":207000,"traceId":"4d1e00c0db9010db86154a4ba6e91385","id":"4d1e00c0db9010db","parentId":"86154a4ba6e91386","name":"put","kind":"SERVER","localEndpoint":{"serviceName":"frontend","ipv4":"0.0.0.0","ipv6":"7::80:807f"},"remoteEndpoint":{"serviceName":"frontend","ipv4":"192.168.99.101","port":9000},"annotations":[{"timestamp":1472470996238000,"value":"foo"},{"timestamp":1472470996403000,"value":"bar"}],"tags":{"clnt/finagle.version":"6.45.0","http.path":"/api"}}]
I noticed that there is an intentional fluffing of the IPv4 field if blank
Lines 65 to 71 in 70244c9
but I don't see a reason documented why this should be.
Here's a use case:
The Tracing.Builder API in Brave supports this feature so I would love to see a similar feature in Go.
As discussed on openzipkin/b3-propagation#21 and first implemented here: https://github.com/openzipkin/brave/blob/master/brave/src/main/java/brave/propagation/B3SingleFormat.java https://github.com/openzipkin/brave/blob/master/brave/src/test/java/brave/propagation/B3SingleFormatTest.java
Let's support at least reading "b3" header from a single string, most commonly traceid-spanid-1
It would also be nice to support optionally writing this, especially in message providers or others with constrained environments.
Brave currently has a property like this, but its name could change with feedback:
/**
* When true, only writes a single {@link B3SingleFormat b3 header} for outbound propagation.
*
* <p>Use this to reduce overhead. Note: normal {@link Tracing#propagation()} is used to parse
* incoming headers. The implementation must be able to read "b3" headers.
*/
public Builder b3SingleFormat(boolean b3SingleFormat) {
this.b3SingleFormat = b3SingleFormat;
return this;
}
In order to embrace the usage of zipkin-go we should provide some standard library instrumented. http.Client
, http.Handler
and sqlx.DB
would be the first candidates.
Creating a repo in openzipkin
or openzipkin-contrib
under the name zipkin-go-instrumentation
or go-instrumentation
would be enough (similar to https://github.com/opentracing-contrib/go-stdlib).
I build myself one library for sqlx
that I could happily move there.
Ping @basvanbeek @adriancole
For more serious set-ups we should also have a Kafka reporter available
Is there a MDC machenism in this client?
For example,Spring Cloud Sleuth outputs logs like this:
If we outputting logs (probably using MDC) with the trace-id and span-id and parsing those when inserting into elasticsearch, it’s pretty easy to search elasticsearch for a given trace ID, and the Zipkin UI already has an integration that I can setup a link to your kibana with the search for the trace ID from the trace view
Hi, in my case, I use TraceID.UnmarshalJSON() to retrieve the origin traceid, but it doesn't work.
For example:
var ss = "490f450433569020"
t := new(zmodel.TraceID)
t.UnmarshalJSON([]byte(ss))
fmt.Println(t.String())
The result is: 0090f45043356902
.
I check UnmarshalJSON source code, found tID, err := TraceIDFromHex(string(traceID[1 : len(traceID)-1]))
I don't know why need cut out the origin traceid? But if I add 0 like this var ss = "0490f4504335690200"
(add 0 in the begin and back).
I got the expect result.
var ss = "0490f4504335690200"
t := new(zmodel.TraceID)
t.UnmarshalJSON([]byte(ss))
fmt.Println(t.String())
the result : 490f450433569020
Is it a bug? If not, can you please tell me the right usage?
When reporter is offline or down, timeout is not working. Rentry goes infinite as below.
failed to send the request: Post http://localhost:9411/api/v2/spans: dial tcp 12
7.0.0.1:9411: connectex: No connection could be made because the target machine actively refused it.
failed to send the request: Post http://localhost:9411/api/v2/spans: dial tcp 12
7.0.0.1:9411: connectex: No connection could be made because the target machine actively refused it.
failed to send the request: Post http://localhost:9411/api/v2/spans: dial tcp 12
7.0.0.1:9411: connectex: No connection could be made because the target machine actively refused it.
As i can see default timeout is 5 seconds ie. defaultTimeout = time.Second * 5
And also i tried to override the timeout, which is not working
reporterTimeoutOption := zipkinHttpReporter.Timeout(time.Duration(5 * time.Second))
reporter := zipkinHttpReporter.NewReporter(os.Getenv("ZIPKIN_REPORTER"), reporterTimeoutOption)
Currently it is quite hard to do simple prototyping with sample as one can not directly access to alwaysSample
and neverSample
making the initial usage of the library kind of tricky (going through NewModuloSampler(1)
is counter intuitive).
IMHO this won't have a big impact at all.
WDYT @basvanbeek
I would like to add additional fixed tags per GRPC ClientHandler to spans like "component = grpc".
A way to implement it could be to introduce an additional ClientOption to the grpc package to pass tags when calling NewClientHandler()
.
Similiar to https://github.com/openzipkin/zipkin-go/blob/master/middleware/http/client.go#L60
How do I specify a http proxy in the client with zipkin-go’s client? Using the http package, I would specify it in the following way.
client = http.Client{
Transport: &http.Transport{
Proxy: http.ProxyURL(proxyURL),
},
}
When I update vendors I have error:
go: github.com/gogo/[email protected]: unknown revision 000000000000
go get: error loading module requirements
How to reproduce:
docker run -ti golang:1.12.7-alpine3.10 ash
apk add git
git clone -b v0.2.0 https://github.com/openzipkin/zipkin-go.git && cd zipkin-go
go get -u
At the moment, tracer is creating a noop span only if the tracer is set as noop. Otherwise, it is creating a real span (even if the context has sampled=false
). This goes against the assumption that sampling reduces overhead as it creates noop
objects.
Thoughts @basvanbeek @adriancole
Hello there, thank you all for the great work on this package!
I just encountered a bug while writing a Zipkin interceptor, whereby I am using sample JSON, translating it to some intermediate representation then sending it over the wire. However, for my test source which has IPv6 addresses https://gist.github.com/adriancole/e8823c19dfed64e2eb71
NewEndpoint fails with "too many colons in address"
that is
le, err := openzipkin.NewEndpoint("frontend", "7::0.128.128.127")
if err != nil {
log.Fatalf("Failed to create endpoint: %v", err)
}
but Go's net.ParseIP can successfully parse it https://play.golang.org/p/-OB548A8qpK
package main
import (
"fmt"
"net"
)
func main() {
fmt.Println(net.ParseIP("7::0.128.128.127"))
}
This is a test to make sure that Gitter accepts messages from repos other than the one that sent the first notification with a given token.
We use a goroutine to accept the request,and creating a span 。but we use a annother goroutine to handle the response。so if we need to finsh the span ,we need to save the span while accepted the request ,but the performance of this way is unacceptable。 Like the case of async ,Hope the feature can be support in zipkin-Go。
Zipkin Kafka Collector expects an array of SpanModels per message instead of single SpanModel objects.
@jcchavezs can you fix?
Currently RequestSampler
is only being invoked in the lack of sampling decision, tho I see a lot of potential on reverting sampling decision for interesting operations that are only in the knowledge of the endpoint itself and not in the upstream knowledge.
Does it make sense for the request sampler to act even when sampling decision is to not sample from upstream?
Ping @basvanbeek @adriancole
Following suit with census-instrumentation/opencensus-service#154 I've implemented logic for proto unmarshalling to a *model.SpanModel.
I can make a PR to this repository to add that code. Thank you.
Currently error handler supports a transport error and a status code:
type ErrHandler func(sp zipkin.Span, err error, statusCode int)
There are well known cases where the api returns meaningful errors in the response payload and those errors would be much better in traces e.g.:
{"error": "INVALID_TYPE"}
I think the error handler is the piece where we can pass the resp.Body, the only challenge here is that we might need to mutate it after the read (to be able to read it again). This sounds to me safe as long as we only do that on http error code (which we do already) as when in error status code, the payload of the response is usually the error description (and it is mostly short payload). A proposed interface would be:
type ErrHandler func(sp zipkin.Span, err error, statusCode int, resBody io.ReadCloser)
A related implementation can be found in https://github.com/elastic/go-elasticsearch/blob/master/estransport/estransport.go#L115
hi, it's my first time to run test case, then it occurs:
go: google.golang.org/[email protected]: unrecognized import path "google.golang.org/genproto" (https fetch: Get https://google.golang.org/genproto?go-get=1: dial tcp 216.239.37.1:443: i/o timeout) go: google.golang.org/[email protected]: unrecognized import path "google.golang.org/appengine" (https fetch: Get https://google.golang.org/appengine?go-get=1: dial tcp 216.239.37.1:443: i/o timeout) go: google.golang.org/[email protected]: unrecognized import path "google.golang.org/grpc" (https fetch: Get https://google.golang.org/grpc?go-get=1: dial tcp 216.239.37.1:443: i/o timeout) go: golang.org/x/[email protected]: unrecognized import path "golang.org/x/lint" (https fetch: Get https://golang.org/x/lint?go-get=1: dial tcp 216.239.37.1:443: i/o timeout) go: golang.org/x/[email protected]: unrecognized import path "golang.org/x/net" (https fetch: Get https://golang.org/x/net?go-get=1: dial tcp 216.239.37.1:443: i/o timeout) go: golang.org/x/[email protected]: unrecognized import path "golang.org/x/oauth2" (https fetch: Get https://golang.org/x/oauth2?go-get=1: dial tcp 216.239.37.1:443: i/o timeout) go: golang.org/x/[email protected]: unrecognized import path "golang.org/x/sys" (https fetch: Get https://golang.org/x/sys?go-get=1: dial tcp 216.239.37.1:443: i/o timeout) go: golang.org/x/[email protected]: unrecognized import path "golang.org/x/sync" (https fetch: Get https://golang.org/x/sync?go-get=1: dial tcp 216.239.37.1:443: i/o timeout) go: golang.org/x/[email protected]: unrecognized import path "golang.org/x/sync" (https fetch: Get https://golang.org/x/sync?go-get=1: dial tcp 216.239.37.1:443: i/o timeout) go: golang.org/x/[email protected]: unrecognized import path "golang.org/x/tools" (https fetch: Get https://golang.org/x/tools?go-get=1: dial tcp 216.239.37.1:443: i/o timeout) go: golang.org/x/[email protected]: unrecognized import path "golang.org/x/sys" (https fetch: Get https://golang.org/x/sys?go-get=1: dial tcp 216.239.37.1:443: i/o timeout) go: golang.org/x/[email protected]: unrecognized import path "golang.org/x/net" (https fetch: Get https://golang.org/x/net?go-get=1: dial tcp 216.239.37.1:443: i/o timeout) go: golang.org/x/[email protected]: unrecognized import path "golang.org/x/text" (https fetch: Get https://golang.org/x/text?go-get=1: dial tcp 216.239.37.1:443: i/o timeout) go: error loading module requirements
are the modules missing?
is it normal? or what can i do?
Zipkin is not critical component to work. If the kafka producer channel buffer is full messages should be just logged instead of waiting for space in buffer. There should be option when creating kafkaReporter to specify if you want to be non-blocking and time for timeout. This allows current request not to wait for space in channel buffer if there is none.
Current implementation lacks sufficient unit tests as we've been ironing out the way the API surface and overall project structure needs to look. Now that this is becoming clearer we should add unit tests before further refactoring and enhancements.
Help is very welcome!
while propagating,it support fields like TraceId、SpanId、ParentSpanId 、Debug And Sample。But No extra fields to propagate other user-defined fields 。The feature has been supported In zipkin-Java
ExtraFieldPropagation TraceContext
Hope the feature can also be supported In zipkin-Go
We received PR #72 which shows consumer desire not to work with raw numbers. Unfortunately wrapping these out for the actual HTTP constants makes the code less clear.
We should comment the locations where we test for status code ranges.
Ex. the test for <200 || >299
could be commented as "test for status code to be outside of the successful 2xx range"
Currently we don't have any example in this library that we for example have in https://github.com/openzipkin-contrib/zipkin-go-opentracing/tree/master/examples (which was a first implementation of zipkin). We could either port those examples in here or create new ones.
Ping @basvanbeek @adriancole
Often it is useful to add remoteEndpoint to the client spans. Specifically http requests.
Currently nor the client or the transport support this functionality. The most logical options that comes to my mind is that we add an option for both.
Ping @basvanbeek @adriancole
The current latest version of the github.com/openzipkin/zipkin-go
module is v0.1.5. Its go.mod file requires the module google.golang.org/grpc
at version v1.16.0
:
https://github.com/openzipkin/zipkin-go/blob/v0.1.5/go.mod#L27
That version is old, and has an issue where it requires the module golang.org/x/lint
twice:
https://github.com/grpc/grpc-go/blob/v1.16.0/go.mod#L7
https://github.com/grpc/grpc-go/blob/v1.16.0/go.mod#L11
The first time it's being required via the module path github.com/golang/lint
, which is not compatible with the module path specified in the latest master commit of that repository:
https://github.com/golang/lint/blob/5b3e6a55c961c61f4836ae6868c17b070744c590/go.mod#L1
As a result, when in module mode, doing go get -u github.com/openzipkin/zipkin-go
fails:
$ cd $(mktemp -d)
$ export GO111MODULE=on
$ go get -u github.com/openzipkin/zipkin-go
go: finding github.com/golang/snappy v0.0.1
go: finding github.com/Shopify/sarama v1.21.0
go: github.com/golang/[email protected]: parsing go.mod: unexpected module path "golang.org/x/lint"
go get: error loading module requirements
Because this affects the latest version of this module, which is being required by other modules, it indirectly causes the issue golang/lint#436.
To fix this problem, you need to update go.mod to require a newer version of the grpc module and issue a new version. I can send a PR for the go.mod file change.
@abesto what's in your opinion the best tool considering various things you may have run into. Seems codecov vs coveralls? or maybe something else
cc @openzipkin/devops-tooling
Referring to:
zipkin-go/propagation/b3/spancontext.go
Line 38 in e260ab9
zipkin4net least treats X-B3-Flags
as a bitfield; py_zipkin doesn't currently care what the flags are set to, as it doesn't use them yet. Even brave implements this as a boolean but doesn't refuse to proceed if the flag is not a 0|1
value (it'll just be false).
When calling a Go backend from a C# client and passing a trace, zipkin-go barfs on parsing the headers because the value of the X-B3-Flags
header is not always 1
or 0
A snippet of the headers and result logs look like:
gobackend_1 | 2018/04/17 06:21:21 Could not extract span from headers: invalid B3 Flags header found
gobackend_1 | 2018/04/17 06:21:21 Request: http.Header map[X-B3-Parentspanid:[8222d44275b111ae] X-B3-Flags:[6] X-B3-Sampled:[1] Accept:[*/*] X-B3-Traceid:[c5ff9f62dff84719] X-B3-Spanid:[2e005b9bb979c1c2]]
This breaks tracing spans which propagate between language implementations.
Would it be possible to make this a warning case, instead of an error case?
We should provide a standard structured logger interface which consumers can inject with an implementation. zipkin-go-opentracing
uses an interface compatible with the Go kit
logger interface which seems the best candidate.
type Logger interface {
Log(keyvals ...interface{}) error
}
This will allow people to easily fetch the K/V pairs coming from errors and exceptions within the library and merge them with their application logging infrastructure.
For people not liking structured logging we should provide an adapter for the standard Go log.
This is a continuation of issue #114.
It has been resolved via PR #115, which has been merged. However, a new tag hasn't been created yet, which means v0.1.5 is still the latest version of zipkin-go, and now that golang.org/x/lint
has a go.mod file again, the latest version of zipkin-go is running into the same issue as described in #114.
It can be reproduced with Go 1.12 as follows:
$ cd $(mktemp -d)
$ go mod init m
go: creating new go.mod: module m
$ go get -u github.com/openzipkin/zipkin-go
go: finding github.com/golang/lint latest
go: finding github.com/eapache/go-xerial-snappy latest
go: github.com/golang/[email protected]: parsing go.mod: unexpected module path "golang.org/x/lint"
go: finding honnef.co/go/tools latest
go: finding google.golang.org/genproto latest
go: finding github.com/golang/glog latest
go: finding golang.org/x/sync latest
go: finding golang.org/x/lint latest
go get: error loading module requirements
$ echo $?
1
Please consider making a new tag that includes the fix from PR #115 in order to fix the latest version of zipkin-go. Thanks!
The span and its annotations are shown, but with empty services name and no tags.
This should be my misusage, I think, so please help to provide the right code, Thanks!!
This is my code for create tracer:
func InitTrace(zipkinHTTPEndpoint string, debug bool, hostPort, serviceName string) (*zipkin.Tracer, error) {
reporter := httpreporter.NewReporter(zipkinHTTPEndpoint)
ip, err := GetInternalIP()
if err != nil {
return nil, err
}
// ip is 0.0.0.0 format, and hostPort is ":80"
endpoint, err := zipkin.NewEndpoint(serviceName, fmt.Sprintf("%s%s", ip, hostPort))
if err != nil {
return nil, err
}
tracer, err := zipkin.NewTracer(reporter, zipkin.WithLocalEndpoint(endpoint))
if err != nil {
return nil, err
}
return tracer, nil
}
Send span
....
var parentContext model.SpanContext
if span := zipkin.SpanFromContext(ctx); span != nil {
parentContext = span.Context()
}
remoteEndpoint, _ := zipkin.NewEndpoint(s.module, c.Request.RemoteAddr)
appSpan := s.Tracer.StartSpan("proxy",
zipkin.Kind(model.Client),
zipkin.Parent(parentContext),
zipkin.RemoteEndpoint(remoteEndpoint),
)
defer func() {
appSpan.Finish()
}()
...
Let's discuss how, who and when we will add support for "firehose" mode.
The http.Logger() interface expects a log.Logger
type as parameter.
Instead of expecting log.Logger
, define a simple logger interface with the Printf()
method and change the parameter to that interface.
That will allow to use other loggers then log.Logger
of the stdlib as reporter logger.
Brave http client instrumentation allow users to inject a sampler at client level and it would be great to include something similar here. Currently we only have RequestSampler
for server middleware but the same interface could perfectly work for the client middleware.
The use case is a request that is not sampled by default (maybe internal endpoint) but you might want to trace a specific request to other service. My use case is that I do sampling 33% but I want to trace 100% requests to a payment endpoint and right now I don't have means to make the payment endpoint to be traced 100% as my sampling policy is global (and it is a monolith with LOTS of endpoints).
Ping @adriancole @basvanbeek
Error log messages for reporting are meaningless https://github.com/openzipkin/zipkin-go/blob/master/reporter/http/http.go#L139 end up in
2018/11/07 13:28:24 failed the request with status code 503
in logs which might not be useful. I was thinking on
2018/11/07 13:28:24 failed the request to zipkin collector with status code 503
Any suggestion @adriancole @basvanbeek ?
I was optimistically hoping #96 would get in before another tagged release but unfortunately 0.1.4 doesn't have it. #96 made this backwards incompatible change (removal of WithRPCHandler
since we found it to be overkill).
https://github.com/openzipkin/zipkin-go/pull/96/files#diff-e9d00f5e4c269bd123203c5aff2f336eL34
Does it make sense to release 0.1.5 quickly and consider 0.1.4 a skipped release? Sorry for the trouble.
In the current zipkin-go project, there are various SpanOptions functions (for example, func Kind(kind model.Kind) SpanOption)) to adjust a span that is being created. However, there is no API to adjust a span that is already created (please let me know if I missed it).
In brave API, you can update Span after it is created, for example:
Span kind(Span.Kind var1) which sets the kind of an existing span
Span name(String var1) which sets the name of an existing span
Can we add this functionality to zipkin-go as well?
Is there an equivalent API in zipkin-go for brave Tracer API:
Span joinSpan(TraceContext context)
or a combination of the existing zipkin-go APIs that could achieve the same thing?
Having the ability of abandoming a Span is convenient for those cases where an output makes the span meaningless.
APIs like brave and zipkin-php include such a thing.
Ping @adriancole @basvanbeek
There are some cases where one might need to enable/disable tracing for certain children spans. For example, if I will write a bunch of files in a zip stream, I want to trace the call to S3 to list the files but not every single call to S3 to retrieve the content of the file. In such case I want to make a decision on what to record and what not based on rules in the spans.
For implementation reference we could have a look at brave: https://github.com/openzipkin/brave/blob/master/brave/src/main/java/brave/handler/FinishedSpanHandler.java
Ping @basvanbeek @adriancole
I've noticed that func (s *spanImpl) FinishedWithDuration(d time.Duration) was added to support duration when finish.
How about adding this api into the Span interface.
It's helpful under the case which who want to report the span with some rate control.
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.