Coder Social home page Coder Social logo

zipkin-ruby's People

Contributors

abesto avatar adriancole avatar alunyou avatar ayrat555 avatar ismith avatar jamescway avatar jcarres-mdsol avatar jfeltesse-mdsol avatar jmhon08 avatar jordipolo avatar jvans1 avatar keithmgould avatar pje avatar sonny8988 avatar sprsquish avatar ssteeg-mdsol avatar tbalthazar avatar trevrosen avatar turnon avatar yellowred avatar ykitamura-mdsol avatar ys avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

zipkin-ruby's Issues

Does not work with constraints in routes

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?

Intermittent RSpec failure with rack handler specs

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) ✗ 

IPv6 support

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

log the "sa" annotation when making outbound calls

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))

rename repo to zipkin-ruby?

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?

Build a backend trace ruby library

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.

`bundle install` fails on JRuby due to Thin requiring native extensions

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

Keep Getting Uninitialized Constant AsyncHttpApiClient::ZipkinHttpSender

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?

implement "b3 single" header format

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;
}

Socket is used but there's no "require"

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'.

Forcing all paths to get GET causes problems

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?

Should omit ParentSpanId header for root spans

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.

How to reproduce

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/')

Workaround

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

Default tracer tags

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.

How to set component_span with Rack middleware?

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?

Cannot decode spans due to endpoint ipv4 value `67e1383c1e7f`

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

use sucker_punch 2.0.0

This issue is just to track the progress of the various parties involved.

  • sucker_punch 2.0.0 uses concurrent-ruby 1.0.0
  • hermann depends on ~> 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! 🎉

Sinatra + Docker issues

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?

Parent span ID header should be optional

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.

Boolean representation for HTTP_X_B3_SAMPLED incorrect resulting in broken traces

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

  • Change the interpretation of 'HTTP_X_B3_SAMPLED' to be '0'/'1' inline with specification and other implementations.

Memory leak when doing http requests in a new thread

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.

How to set the span version

I'd like to generate the span with V1 version for my application, is there any parameter used for this configuration?

Don't report span.timestamp or duration when you didn't create the span

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

Why bother?

If we special-case timestamp and duration reporting, a couple things happen:

  • zipkin duration queries will be accurate because the critical path duration will be the only duration queried for the span
  • Those externally controlling ids will be able to use the duration query
  • Those converting zipkin RPC spans into single-host spans, like Google StackDriver, will have a heuristic to tell if a span is dual host or not.

Do we need to do anything?

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

    • client propagates b3 headers for trace id, span id, and sampled=1
    • server neither reports span.timestamp nor duration
    • client reports span.timestamp and duration
  • server creates a new trace

    • no b3 headers are detected
    • server reports span.timestamp and duration
  • server creates a new trace with externally supplied ids

    • caller propagates b3 headers for trace id, span id, but no sampled header
    • server reports span.timestamp and duration

Does this make sense? Can anyone help translate this into tests for us?

See openzipkin/brave#277 (comment)

SQS integration

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?

Unable to POST spans to zipkin-server 1.1.4

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.

::Trace.record throws "not implemented"

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

Feature request: Grape compatibility

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

req = Rack::Request.new(env)
). It seems either Grape is included in the roadmap or it will become incompatible with zipkin.

got a NullSpan?

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?

Is trace logging supported? (like add to MDC)

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 ?

why is :service_port REQUIRED?

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?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.