openzipkin / zipkin-ruby Goto Github PK
View Code? Open in Web Editor NEWzipkin-tracer ruby gem
License: Apache License 2.0
zipkin-tracer ruby gem
License: Apache License 2.0
We have constraints in routes which code depends on env passed from Rack.
Rails guide: http://edgeguides.rubyonrails.org/routing.html#advanced-constraints
Example code to reproduce problem but ours is much more complicated:
# config/routes.rb
resources :samples, :constraints => SampleConstraint.new
# lib/sample_constraint.rb
class SampleConstraint
def matches?(request)
request.host == 'myhost.com'
end
end
In that case when sampling you call Rails.application.routes.recognize_path
https://github.com/openzipkin/zipkin-ruby/blob/master/lib/zipkin-tracer/application.rb#L8
but
recogize_path will use Rack::Mock
https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/routing/route_set.rb#L734
Rack::Mock will return 'example.org' as host.
And we will never reach our endpoint in same trace.
recognize_path
is private rails method which shouldn't be used.
Related issues:
heartcombo/devise#3747 (comment)
rails/rails#21477 (comment)
I don't know how to solve it yet. Any help?
I've not isolated this yet, but I'm sure it's a timing issue
➜ zipkin-tracer git:(unreliable-specs) ✗ be rake spec
/home/tyler/.rvm/rubies/ruby-2.1.5/bin/ruby -I/home/tyler/.rvm/gems/ruby-2.1.5@rubygems/gems/rspec-core-3.0.4/lib:/home/tyler/.rvm/gems/ruby-2.1.5@rubygems/gems/rspec-support-3.0.4/lib -S /home/tyler/.rvm/gems/ruby-2.1.5@rubygems/gems/rspec-core-3.0.4/exe/rspec ./spec/rack_handler_spec.rb
........
Finished in 0.01552 seconds (files took 0.11713 seconds to load)
8 examples, 0 failures
Randomized with seed 46989
➜ zipkin-tracer git:(unreliable-specs) ✗ be rake spec
/home/tyler/.rvm/rubies/ruby-2.1.5/bin/ruby -I/home/tyler/.rvm/gems/ruby-2.1.5@rubygems/gems/rspec-core-3.0.4/lib:/home/tyler/.rvm/gems/ruby-2.1.5@rubygems/gems/rspec-support-3.0.4/lib -S /home/tyler/.rvm/gems/ruby-2.1.5@rubygems/gems/rspec-core-3.0.4/exe/rspec ./spec/rack_handler_spec.rb
....F...
Failures:
1) ZipkinTracer::RackHandler configured without plugins with sample rate set to 0 does not sample a request
Failure/Error: expect(trace_id.sampled?).to be_falsy
expected: falsey value
got: true
# ./spec/rack_handler_spec.rb:45:in `block (5 levels) in <top (required)>'
# ./lib/zipkin-tracer.rb:88:in `block in tracing_filter'
# ./lib/zipkin-tracer.rb:87:in `synchronize'
# ./lib/zipkin-tracer.rb:87:in `tracing_filter'
# ./lib/zipkin-tracer.rb:70:in `call'
# ./spec/rack_handler_spec.rb:47:in `block (4 levels) in <top (required)>'
Finished in 0.01555 seconds (files took 0.12222 seconds to load)
8 examples, 1 failure
Failed examples:
rspec ./spec/rack_handler_spec.rb:43 # ZipkinTracer::RackHandler configured without plugins with sample rate set to 0 does not sample a request
Randomized with seed 50368
/home/tyler/.rvm/rubies/ruby-2.1.5/bin/ruby -I/home/tyler/.rvm/gems/ruby-2.1.5@rubygems/gems/rspec-core-3.0.4/lib:/home/tyler/.rvm/gems/ruby-2.1.5@rubygems/gems/rspec-support-3.0.4/lib -S /home/tyler/.rvm/gems/ruby-2.1.5@rubygems/gems/rspec-core-3.0.4/exe/rspec ./spec/rack_handler_spec.rb failed
➜ zipkin-tracer git:(unreliable-specs) ✗
We currently support logging of only IPv4 addresses. Starting with Zipkin 1.4 endpoints can omit IPv4 (by setting Endpoint.ipv4 to 0), and optionally log Endpoint.ipv6 as the raw 16byte address.
https://github.com/openzipkin/zipkin-api/blob/master/thrift/zipkinCore.thrift#L276
In json, both are the string formatting http://zipkin.io/zipkin-api
ipv4:
string
The text representation of a IPv4 address associated with this endpoint. Ex. 192.168.99.100
ipv6:
string
The text representation of a IPv6 address associated with this endpoint. Ex. 2001:db8::c001
The rack zipkin tracer collects the local endpoint, which allows it to indicate the correct host when adding annotations.
::Trace.default_endpoint = ::Trace.default_endpoint.with_service_name(config.service_name).with_port(config.service_port)
--snip--
::Trace.record(::Trace::Annotation.new(::Trace::Annotation::SERVER_RECV, ::Trace.default_endpoint))
When making outbound calls, the faraday code uses the server address as the endpoint for all annotations, including http.uri, http.status, CLIENT_SEND, and CLIENT_RECV. This is incorrect as the actual log statements (annotations) are made from the client. For example, when instrumented, the server may record a different http.uri
for the same span, due to rewriting, and also the server may send a correct status back, which the client doesn't receive. It is important to log the local host within annotations, as otherwise debugging becomes misdirected.
The correction would be to change the faraday ZipkinTracer
to log its local visible IP (in docker, usually this is the container IP).
In order to indicate the recipient, when recording CLIENT_SEND and http.uri, also record SERVER_ADDR with the value of a single byte 1 (not ASCII '1', which is 49). I'm not sure the exact syntax, but here's what it might look like.
record(::Trace::BinaryAnnotation.new(::Trace::Annotation::SERVER_ADDR, [1], "BOOL", endpoint))
We don't need to rename any code inside, but renaming the repository to zipkin-ruby might make it more obvious to people that this is where to go for ruby frameworks.
wdyt?
I plan to to build a backend trace library, not only tracing the HTTP requests, that collects the span information of every method in the path and POST to zipkin server. Is it possible to do it?
I think it needs a wrapper before each method to collect time cost and send spans to another backend server. The backend server can analyze the spans, generate a trace and send to Zipkin server.
The hard part is how to keep an identical traceID through the path and make each span include its parent ID in the path. With a backend server, I can create a stack that keeps tracking the methods being called. Add to stack before calling the method and pop out when finishing the method. However, if two traces happen at the same time(asynchronous), the stack would be a messy.
Hi,
I have created a sample Rails application with CRUD for users.
I have added zipkin-tracer
Ruby gem to Gemfile and done configuration config.ru
But I don't see any traces available at my locally running Zipkin instance http://localhost:9411/zipkin/
Am I missing anything?
Thanks
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
/home/travis/.rvm/rubies/jruby-1.7.19-d19/bin/jruby -r ./siteconf20150705-2187-1vrg54k.rb extconf.rb
NotImplementedError: C extension support is not enabled. Pass -Xcext.enabled=true to JRuby or set JRUBY_OPTS.
(root) at /home/travis/.rvm/rubies/jruby-1.7.19-d19/lib/ruby/shared/mkmf.rb:8
require at org/jruby/RubyKernel.java:1071
(root) at /home/travis/.rvm/rubies/jruby-1.7.19-d19/lib/ruby/shared/rubygems/core_ext/kernel_require.rb:1
(root) at extconf.rb:1
extconf failed, uncaught signal 1
Trying to integrate with our rails application, but keep getting this uninitialized constant error. Config looks like
`require 'zipkin-tracer'
require_relative 'config/environment'
ZIPKIN_TRACER_CONFIG = {
service_name: 'test',
sample_rate: 1.0,
json_api_host: 'http://localhost:9411'
}.freeze
use ZipkinTracer::RackHandler, ZIPKIN_TRACER_CONFIG
run Rails.application`
Just curious if you have any insight as to why that might be popping up?
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;
}
I ran into this issue with Ruby 2.3.3:
NameError: uninitialized constant Trace::Endpoint::Socket
# .../gems/zipkin-tracer-0.21.0/lib/zipkin-tracer/trace.rb:137:in `local_endpoint'
# .../gems/zipkin-tracer-0.21.0/lib/zipkin-tracer/tracer_factory.rb:25:in `tracer'
# .../gems/zipkin-tracer-0.21.0/lib/zipkin-tracer/rack/zipkin-tracer.rb:14:in `initialize'
It seems like Socket is used in Zipkin, but it is not required explicitly with require 'socket'
.
Currently in the Application.rb
file the gem uses the recognize_path method. No second parameter is sent in. This means all paths are forced to be GET.
Of course that is not the case.
Wondering if I'm missing something, or if we need a PR to pass in a second parameter (a hash) with a :method
key?
There are services which throw error when an empty X-B3-ParentSpanId
header sent with the HTTP request.
From the openzipkin specification:
The
X-B3-ParentSpanId
header must be present on a child span and absent on the root span.
conn = Faraday.new() do |faraday|
faraday.use ZipkinTracer::FaradayHandler, 'service_name'
faraday.request :url_encoded
faraday.adapter Faraday.default_adapter
end
conn.get('http://logs-01.loggly.com/inputs/TOKEN/tag/http/')
Result is 400 Bad request
.
If we don't send tracing headers, the response is the expected 403 Invalid API key
:
conn = Faraday.new() do |faraday|
faraday.request :url_encoded
faraday.adapter Faraday.default_adapter
end
conn.get('http://logs-01.loggly.com/inputs/TOKEN/tag/http/')
The only workaround i found so far is to monkey patch FaradayHandler with unless trace_id.send(method).to_s.empty?
as below:
require 'zipkin-tracer/faraday/zipkin-tracer'
module ZipkinTracer
class FaradayHandler < ::Faraday::Middleware
def call(env)
trace_id = TraceGenerator.new.next_trace_id
TraceContainer.with_trace_id(trace_id) do
b3_headers.each do |method, header|
env[:request_headers][header] = trace_id.send(method).to_s unless trace_id.send(method).to_s.empty?
end
if Trace.tracer && trace_id.sampled?
trace!(env, trace_id)
else
@app.call(env)
end
end
end
end
end
By doing the same setting with rails/rails-html-sanitizer#26.
we have same error "undefined method `logger' for Rails:Module" since define?(Rails) is incorrect
https://github.com/openzipkin/zipkin-ruby/blob/master/lib/zipkin-tracer/application.rb#L16
This request is similar to openzipkin/brave#357. It would be nice to be able to configure the tracer to send certain tags by default.
It might be possible to override end_span
in ZipkinSenderBase
to do this? But it would be nice if it was supported natively as a config on the tracer.
We have the following config for a Sinatra App:
zipkin_config = { service_name:ENV[ '...' ],
service_port:settings.port,
sampled_as_boolean:false,
sample_rate: 1,
json_api_host: ENV[ '..' ]}
use ZipkinTracer::RackHandler, zipkin_config
The span is displayed as "post", which I guess comes from the request method. How can I set it to request method and request path?
From @pavolloffay on September 15, 2016 12:40
Env:
Zipkin master/head
openjdk version "1.8.0_102"
OpenJDK Runtime Environment (build 1.8.0_102-b14)
OpenJDK 64-Bit Server VM (build 25.102-b14, mixed mode)
Exception:
2016-09-15 14:19:49.649 WARN 18326 --- [nio-9411-exec-2] zipkin.server.ZipkinHttpCollector : Cannot decode spans due to IllegalArgumentException(For input string: "67e1383c1e7f" reading List<Span> from json: [{"name":"get","traceId":"ff6b08e210acd24b","id":"ff6b08e210acd24b","annotations":[{"value":"sr","timestamp":1473941989594730,"endpoint":{"ipv4":"67e1383c1e7f","port":9292,"serviceName":"roda"}},{"value":"ss","timestamp":1473941989594846,"endpoint":{"ipv4":"67e1383c1e7f","port":9292,"serviceName":"roda"}}],"binaryAnnotations":[{"key":"http.uri","value":"/roda/hello","endpoint":{"ipv4":"67e1383c1e7f","port":9292,"serviceName":"roda"}}],"timestamp":1473941989594695,"duration":158,"debug":false}])
java.lang.IllegalArgumentException: For input string: "67e1383c1e7f" reading List<Span> from json: [{"name":"get","traceId":"ff6b08e210acd24b","id":"ff6b08e210acd24b","annotations":[{"value":"sr","timestamp":1473941989594730,"endpoint":{"ipv4":"67e1383c1e7f","port":9292,"serviceName":"roda"}},{"value":"ss","timestamp":1473941989594846,"endpoint":{"ipv4":"67e1383c1e7f","port":9292,"serviceName":"roda"}}],"binaryAnnotations":[{"key":"http.uri","value":"/roda/hello","endpoint":{"ipv4":"67e1383c1e7f","port":9292,"serviceName":"roda"}}],"timestamp":1473941989594695,"duration":158,"debug":false}]
at zipkin.internal.JsonCodec.exceptionReading(JsonCodec.java:643) ~[zipkin-1.9.1-SNAPSHOT.jar!/:na]
at zipkin.internal.JsonCodec.readList(JsonCodec.java:597) ~[zipkin-1.9.1-SNAPSHOT.jar!/:na]
at zipkin.internal.JsonCodec.readSpans(JsonCodec.java:432) ~[zipkin-1.9.1-SNAPSHOT.jar!/:na]
at zipkin.collector.Collector.acceptSpans(Collector.java:93) ~[zipkin-1.9.1-SNAPSHOT.jar!/:na]
at zipkin.server.ZipkinHttpCollector.validateAndStoreSpans(ZipkinHttpCollector.java:89) [classes!/:na]
at zipkin.server.ZipkinHttpCollector.uploadSpansJson(ZipkinHttpCollector.java:63) [classes!/:na]
at sun.reflect.GeneratedMethodAccessor84.invoke(Unknown Source) ~[na:na]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_102]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_102]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221) [spring-web-4.3.2.RELEASE.jar!/:4.3.2.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136) [spring-web-4.3.2.RELEASE.jar!/:4.3.2.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:114) [spring-webmvc-4.3.2.RELEASE.jar!/:4.3.2.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827) [spring-webmvc-4.3.2.RELEASE.jar!/:4.3.2.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738) [spring-webmvc-4.3.2.RELEASE.jar!/:4.3.2.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) [spring-webmvc-4.3.2.RELEASE.jar!/:4.3.2.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963) [spring-webmvc-4.3.2.RELEASE.jar!/:4.3.2.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897) [spring-webmvc-4.3.2.RELEASE.jar!/:4.3.2.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) [spring-webmvc-4.3.2.RELEASE.jar!/:4.3.2.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872) [spring-webmvc-4.3.2.RELEASE.jar!/:4.3.2.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:648) [tomcat-embed-core-8.5.4.jar!/:8.5.4]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) [spring-webmvc-4.3.2.RELEASE.jar!/:4.3.2.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) [tomcat-embed-core-8.5.4.jar!/:8.5.4]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230) [tomcat-embed-core-8.5.4.jar!/:8.5.4]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) [tomcat-embed-core-8.5.4.jar!/:8.5.4]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) [tomcat-embed-websocket-8.5.4.jar!/:8.5.4]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) [tomcat-embed-core-8.5.4.jar!/:8.5.4]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) [tomcat-embed-core-8.5.4.jar!/:8.5.4]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) [spring-web-4.3.2.RELEASE.jar!/:4.3.2.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.2.RELEASE.jar!/:4.3.2.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) [tomcat-embed-core-8.5.4.jar!/:8.5.4]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) [tomcat-embed-core-8.5.4.jar!/:8.5.4]
at org.springframework.boot.web.filter.ApplicationContextHeaderFilter.doFilterInternal(ApplicationContextHeaderFilter.java:55) [spring-boot-1.4.0.RELEASE.jar!/:1.4.0.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.2.RELEASE.jar!/:4.3.2.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) [tomcat-embed-core-8.5.4.jar!/:8.5.4]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) [tomcat-embed-core-8.5.4.jar!/:8.5.4]
at org.springframework.boot.actuate.trace.WebRequestTraceFilter.doFilterInternal(WebRequestTraceFilter.java:105) [spring-boot-actuator-1.4.0.RELEASE.jar!/:1.4.0.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.2.RELEASE.jar!/:4.3.2.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) [tomcat-embed-core-8.5.4.jar!/:8.5.4]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) [tomcat-embed-core-8.5.4.jar!/:8.5.4]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) [spring-web-4.3.2.RELEASE.jar!/:4.3.2.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.2.RELEASE.jar!/:4.3.2.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) [tomcat-embed-core-8.5.4.jar!/:8.5.4]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) [tomcat-embed-core-8.5.4.jar!/:8.5.4]
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:87) [spring-web-4.3.2.RELEASE.jar!/:4.3.2.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.2.RELEASE.jar!/:4.3.2.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) [tomcat-embed-core-8.5.4.jar!/:8.5.4]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) [tomcat-embed-core-8.5.4.jar!/:8.5.4]
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77) [spring-web-4.3.2.RELEASE.jar!/:4.3.2.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.2.RELEASE.jar!/:4.3.2.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) [tomcat-embed-core-8.5.4.jar!/:8.5.4]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) [tomcat-embed-core-8.5.4.jar!/:8.5.4]
at org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.java:107) [spring-boot-actuator-1.4.0.RELEASE.jar!/:1.4.0.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.2.RELEASE.jar!/:4.3.2.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) [tomcat-embed-core-8.5.4.jar!/:8.5.4]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) [tomcat-embed-core-8.5.4.jar!/:8.5.4]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) [tomcat-embed-core-8.5.4.jar!/:8.5.4]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:108) [tomcat-embed-core-8.5.4.jar!/:8.5.4]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:522) [tomcat-embed-core-8.5.4.jar!/:8.5.4]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [tomcat-embed-core-8.5.4.jar!/:8.5.4]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) [tomcat-embed-core-8.5.4.jar!/:8.5.4]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.4.jar!/:8.5.4]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:349) [tomcat-embed-core-8.5.4.jar!/:8.5.4]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:1110) [tomcat-embed-core-8.5.4.jar!/:8.5.4]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.4.jar!/:8.5.4]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:785) [tomcat-embed-core-8.5.4.jar!/:8.5.4]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1425) [tomcat-embed-core-8.5.4.jar!/:8.5.4]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.4.jar!/:8.5.4]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_102]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_102]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.4.jar!/:8.5.4]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_102]
Caused by: java.lang.NumberFormatException: For input string: "67e1383c1e7f"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) ~[na:1.8.0_102]
at java.lang.Integer.parseInt(Integer.java:580) ~[na:1.8.0_102]
at java.lang.Integer.parseInt(Integer.java:615) ~[na:1.8.0_102]
at zipkin.internal.JsonCodec$1.fromJson(JsonCodec.java:76) ~[zipkin-1.9.1-SNAPSHOT.jar!/:na]
at zipkin.internal.JsonCodec$1.fromJson(JsonCodec.java:63) ~[zipkin-1.9.1-SNAPSHOT.jar!/:na]
at zipkin.internal.JsonCodec$2.fromJson(JsonCodec.java:145) ~[zipkin-1.9.1-SNAPSHOT.jar!/:na]
at zipkin.internal.JsonCodec$2.fromJson(JsonCodec.java:133) ~[zipkin-1.9.1-SNAPSHOT.jar!/:na]
at zipkin.internal.JsonCodec$4.fromJson(JsonCodec.java:331) ~[zipkin-1.9.1-SNAPSHOT.jar!/:na]
at zipkin.internal.JsonCodec$4.fromJson(JsonCodec.java:309) ~[zipkin-1.9.1-SNAPSHOT.jar!/:na]
at zipkin.internal.JsonCodec.readList(JsonCodec.java:592) ~[zipkin-1.9.1-SNAPSHOT.jar!/:na]
... 69 common frames omitted
Copied from original issue: openzipkin/zipkin#1301
This issue is just to track the progress of the various parties involved.
~> 0.7.0
so can't bundle
The cool thing with upgrading is we'd get rid of celluloid, which consumes a lot of memory.
The not so-cool thing is that ActionCable depends on celluloid so rails 5 users will end up with 2 concurrency libs ActionCable head doesn't pull celluloid anymore! 🎉
Release the gem after each commit to master.
I've created a related issue over on Sinatra here but though both projects may benefit from the collaboration. (sinatra/sinatra#1118)
Given a sinatra app.rb of
# -*- coding: utf-8 -*-
require 'sinatra'
require 'zipkin-tracer'
set :bind, '0.0.0.0'
use ZipkinTracer::RackHandler, {
:log_tracing => true,
:sample_rate => 1
}
get '/' do
"hello world"
end
Executing this at the shell via
bundle exec ruby app.rb
yields the expected behaviors. "hello world" is returned and zipkin trace statements are rendered to stdout.
However when executing the same code with same entry point in docker (via docker-compose) none of the zipkin statements are logged to the screen. Sinatra yields the correct payload and all looks ok, with the exception of the log_tracer behavior.
Any thoughts?
We are using the zipkin tracer rack middleware and it doesn't properly handle requests that have a trace ID, span ID and sampled flag but no parent span ID. According to the documentation, the parent span ID should be fully optional.
https://github.com/openzipkin/zipkin-ruby/blob/master/lib/zipkin-tracer/rack/zipkin-tracer.rb#L24 lists the X-B3-ParentSpanID
header as required, which will fail the called_with_zipkin_headers?
check. Moving it to the optional headers should fix it, but will break the order in trace_parameters
.
https://github.com/reiseburo/hermann has been dead for over 2 years and requires jruby
https://github.com/zendesk/ruby-kafka looks very active
Zipkin-tracer current interprets boolean on HTTP_X_B3_SAMPLED as 'true' or 'false'.
This is out of sync with the header specification and other zipkin tracing interpretations (spring-sleuth/ zipkin-js etc). Outside of the library implementations themselves the only specification I could find for the headers was here https://twitter.github.io/zipkin/Instrumenting.html#communicating-trace-information
The end effect is that so long as your micro-service ecosystem exclusively uses zipkin-tracer everything is ok but as soon as you start to work in a polyglot ecosystem traces get dropped due to inconsistent interpretation of this header on the inbound and incorrect setting on outbound calls.
Proposal
Besides traces are sampled and sent to collector, we wanna traces to be added to mdc, so that whenever there is a log line for a request the corresponding traceId would be present.
I know that zipkin brave supports it from here https://github.com/apache/incubator-zipkin-brave/tree/master/context/slf4j. ---- Looks like ruby doesn't ?
reproduce this memory leak by:
1000.times do
Thread.new do
Faraday.get 'http://google.com'
end
end
Because in this new thread there's no SERVER_SEND record annotation, so there's no chance to flush, there's memory leak on the spans.
I've created a PR for this. #109
You can reference the zipkin4net lib. https://github.com/criteo/zipkin4net#span-creation. It uses a timer to flush the spans. But I think it make more sense to fix in my way.
quotes from the zipkin4net lib.
Span creation
Zipkin is designed to handle complete spans. However, an incorrect usage of the library can lead to incomplete span creation. To create a complete span, you need a pair of matching annotations in the following list:
ServerRecv and ServerSend annotations
ClientSend and ClientRecv annotations
LocalComponentStart and LocalComponentStop annotations
Flush mechanism
We implemented a safety mechanism in the library in order to avoid any memory footprint explosion. Spans can remain in memory if the user doesn't record the matching annotation to complete the span, leading to a memory leak. To avoid it, we added a safety that removes these spans after 60 seconds.
I'd like to generate the span with V1 version for my application, is there any parameter used for this configuration?
Zipkin's RPC span is interesting because it is a shared model. For example, a client creates a span and then the next hop (a server) adds annotations to it. The authoritative owner of the span is the one that's supposed to set timestamp and duration. In the case where it is originated by a client, the client, not the server, should set timestamp and duration.
See openzipkin/openzipkin.github.io#49
If we special-case timestamp and duration reporting, a couple things happen:
I'm not sure if the current implementation is doing this fine or not, but it is probably useful to add tests to make sure it it. Usually, there's very little to do to special-case this, and it always is where B3 headers are read.
Here are tests that should smoke it out
client creates a span and propagates it to a server
server creates a new trace
server creates a new trace with externally supplied ids
Does this make sense? Can anyone help translate this into tests for us?
Hi!
I have a rails app that consumes a queue using shoryuken (https://github.com/phstc/shoryuken), instead of receiving http requests. I've been trying to find a workaround so I can use zipkin to trace these, with no success. How can this be implemented?
So we can bundle using ~> 0.4.0
for instance.
As of now only 0.2.0
is tagged.
0.2.1
, 0.3.1
& 0.4.0
are missing.
Unable to post spans to zipkin-server using current zipkin trace version.
zipkin-tracer: 0.18.1
zipkin-server: 1.1.4
Zipkin server responds with a 400 code and message body
"Cannot decode spans due to IllegalArgumentException(Expected a string but was NULL at path $[0].parentId reading List<Span> from json: [{\"name\":\"get\",\"traceId\":\"9c88dbcdd6a4c1e6\",\"id\":\"9c88dbcdd6a4c1e6\",\"parentId\":null,\"annotations\":[{\"value\":\"sr\",\"timestamp\":1465341141243210,\"endpoint\":{\"ipv4\":\"127.0.1.1\",\"port\":4567,\"serviceName\":\"quote-server\"}},{\"value\":\"ss\",\"timestamp\":1465341141247275,\"endpoint\":{\"ipv4\":\"127.0.1.1\",\"port\":4567,\"serviceName\":\"quote-server\"}}],\"binaryAnnotations\":[{\"key\":\"http.uri\",\"value\":\"/\",\"endpoint\":{\"ipv4\":\"127.0.1.1\",\"port\":4567,\"serviceName\":\"quote-server\"}}],\"timestamp\":1465341141243187,\"duration\":4095,\"debug\":false}])\n",
Removing 'parentId' when nil resolved the issue for me in AsyncJsonApiClient class (zipkin_json_tracer.rb). Will make a pull request when I have run through benchmarks/tests etc.
I try to use the "annotate_plugin" method to add the status code as a binary annotation.
I created a new rails application, added the "zipkin-tracer" gem to gemfile then copied the annotate_plugin setup from the readme:
module TestZipkinRuby
class Application < Rails::Application
# Settings in config/environments/* take precedence over those specified here.
# Application configuration should go into files in config/initializers
# -- all .rb files in that directory are automatically loaded.
require 'zipkin-tracer'
zipkin_config = {
service_name: 'example-app',
service_port: 443,
sample_rate: 1,
json_api_host: 'http://localhost:9411',
annotate_plugin: lambda do |env, status, response_headers, response_body|
ep = ::Trace.default_endpoint
# string annotation
::Trace.record(::Trace::BinaryAnnotation.new('http.referrer', env['HTTP_REFERRER'], 'STRING', ep)) # this is line 23
# integer annotation
::Trace.record(::Trace::BinaryAnnotation.new('http.content_size', [env['CONTENT_SIZE']].pack('N'), 'I32', ep))
::Trace.record(::Trace::BinaryAnnotation.new('http.status', [status.to_i].pack('n'), 'I16', ep))
end
}
middleware.use ZipkinTracer::RackHandler, zipkin_config
end
end
This throws not implemented
error at runtime with this backtrace:
finagle-thrift (1.4.2) lib/finagle-thrift/tracer.rb:4:in `record'
finagle-thrift (1.4.2) lib/finagle-thrift/trace.rb:43:in `record'
config/application.rb:23:in `block in <class:Application>'
zipkin-tracer (0.21.1) lib/zipkin-tracer/rack/zipkin-tracer.rb:38:in `annotate_plugin'
zipkin-tracer (0.21.1) lib/zipkin-tracer/rack/zipkin-tracer.rb:48:in `trace!'
zipkin-tracer (0.21.1) lib/zipkin-tracer/rack/zipkin-tracer.rb:25:in `block (2 levels) in call'
zipkin-tracer (0.21.1) lib/zipkin-tracer/zipkin_tracer_base.rb:19:in `with_new_span'
zipkin-tracer (0.21.1) lib/zipkin-tracer/rack/zipkin-tracer.rb:24:in `block in call'
zipkin-tracer (0.21.1) lib/zipkin-tracer/trace_container.rb:8:in `with_trace_id'
zipkin-tracer (0.21.1) lib/zipkin-tracer/rack/zipkin-tracer.rb:20:in `call'
Is the readme out of date? Do i have to configure something else?
Ruby 2.3.3, Rails 4.28 or 5.0.2, zipkin-tracer 0.21.1
Hi,
This gem helps to trace incoming requests, however in case of API made with popular API framework Grape it fails to help. The reason for that is Grape having it's own storage for routes.
Before release 0.29.0
of zipkin-ruby it was possible to patch routable_request?
method adding:
return true if Grape::API.recognize_path(path_info)
But with the new version get_route
also needs to be patched to get rid of extra slash in the beginning of request.path
(env[SCRIPT_NAME] becomes updated because of this line
Other tracer implementations include a setting to force client and server spans to have different spanId's. In Go the setting is WithSharedSpans(false)
and in Java it's supportsJoin(false)
.
There should be something similar in ruby.
This is important because zipkin traces may be reported to non-zipkin backends that might not support the concept of joining spans.
When an error bubbles up from this line the trace spans are never flushed
https://github.com/openzipkin/zipkin-ruby/blob/master/lib/zipkin-tracer/sidekiq/middleware.rb#L31
This results in spans missing from the trace context in a Zipkin UI.
Was this behavior intentional?
here are my code,
use ZipkinTracer::RackHandler, {
:service_name => 'demo',
:service_port => '80',
:sample_rate => 1,
:log_tracing => true,
:json_api_host => "http://localhost:9411/"
}
def get_repositories(_request, _call)
project_id, query = _request.project_id, _request.q
ZipkinTracer::TraceClient.local_component_span('local relay') do |ztc|
ztc.record "relay.get_repositories"
ztc.record_tag 'project_id', project_id
ztc.record_tag 'query', query
p ztc.inspect
"result"
end
end
but, got a NullSpan
"#<ZipkinTracer::NullSpan:0x007f8eeb928750>"
How to solve it?
Besides traces are sampled and sent to collector, we wanna traces to be added to mdc, so that whenever there is a log line for a request the corresponding traceId would be present.
I know that zipkin java supports it from here https://github.com/apache/incubator-zipkin-brave/tree/master/context/slf4j. ---- Does ruby support it ?
Also based on the README description(https://github.com/openzipkin/zipkin-ruby):
:log_tracing - Set to true to log all traces. Only used if traces are not sent to the API or Kafka.
--- What is :log_tracing for? Can we utilize it for logging ?
In the data model, port is not required. Is there a reason why we bother people about this? or is it just a historical effect?
Most zipkin repositories are moving to circle CI. Would be nice if zipkin-ruby
moves in that direction too.
Besides traces are sampled and sent to collector, we wanna traces to be added to mdc, so that whenever there is a log line for a request the corresponding traceId would be present.
I know that zipkin java supports it from here https://github.com/apache/incubator-zipkin-brave/tree/master/context/slf4j. ---- Does ruby support it ?
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.