instana 0.15.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Troubleshooting.md +32 -0
- data/lib/instana/agent.rb +1 -1
- data/lib/instana/instrumentation/excon.rb +3 -2
- data/lib/instana/instrumentation/net-http.rb +3 -2
- data/lib/instana/instrumentation/rack.rb +4 -4
- data/lib/instana/logger.rb +10 -4
- data/lib/instana/opentracing/carrier.rb +4 -0
- data/lib/instana/opentracing/tracer.rb +18 -0
- data/lib/instana/setup.rb +3 -0
- data/lib/instana/tracer.rb +107 -68
- data/lib/instana/tracing/processor.rb +5 -6
- data/lib/instana/tracing/span.rb +322 -2
- data/lib/instana/tracing/span_context.rb +31 -0
- data/lib/instana/tracing/trace.rb +51 -190
- data/lib/instana/util.rb +77 -0
- data/lib/instana/version.rb +1 -1
- data/lib/opentracing.rb +6 -0
- metadata +8 -3
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: cbc400b87081fe4c927cb2f437faf8597ac217bf
         | 
| 4 | 
            +
              data.tar.gz: 247eb9b4db84239ebbf7ec934c5427f94a5b1771
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 9299e4b9ed9aaeabd40dd6c5df7f21b8a76e849b083a152e133b9d8f10e2e8c2787bc711cf5cae75ee9d9f4f2f624a8418bac1b38cf275ab1c1ad46045ccb42a
         | 
| 7 | 
            +
              data.tar.gz: 38ea273e84533d1a9be4e3373a0962a44fa3bf8b96c8aa4937f466b77062995b168630bf146d79d8c21f0680beb26ead6ff0ae90b06c235f3f3f19cb6789e27c
         | 
    
        data/Troubleshooting.md
    ADDED
    
    | @@ -0,0 +1,32 @@ | |
| 1 | 
            +
            # Troubleshooting
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            The Instana gem has been designed to be fully automatic in process metric reporting and trace reporting.  But if something
         | 
| 4 | 
            +
            goes wrong, you can use the following steps and tips to potentially diagnose any issues that may exist.
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            # Supported Components
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            Make sure that the component that you want to get visibility into has been added to the support matrix.  A list of all
         | 
| 9 | 
            +
            supported components can be found in the [documentation](https://instana.atlassian.net/wiki/display/DOCS/Ruby).
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            # Logging & Environment Variables
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            By default, the gem will log informational messages on boot that will indicate if any problems were encountered.  If you
         | 
| 14 | 
            +
            set the `INSTANA_GEM_DEV` environment variable, it will increase the amount of logging output.
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            In the example above, you can see that the host agent isn't available.  Once the host agent is available, the Instana
         | 
| 19 | 
            +
            gem will automatically re-connect without any intervention.
         | 
| 20 | 
            +
             | 
| 21 | 
            +
            There are even more methods to control logging output.  See the [Configuration](https://github.com/instana/ruby-sensor/blob/master/Configuration.md#logging)
         | 
| 22 | 
            +
            document for details.
         | 
| 23 | 
            +
             | 
| 24 | 
            +
            # Testing in your Application
         | 
| 25 | 
            +
             | 
| 26 | 
            +
            To diagnose the Instana gem from your application, often simply opening an application console with verbose logging can be
         | 
| 27 | 
            +
            enough to identify any potential issues:
         | 
| 28 | 
            +
             | 
| 29 | 
            +
            
         | 
| 30 | 
            +
             | 
| 31 | 
            +
            In the example above, you can see the Instana Ruby gem initialize, instrument some components and a success notification: `Host agent available. We're
         | 
| 32 | 
            +
            in business`.
         | 
    
        data/lib/instana/agent.rb
    CHANGED
    
    | @@ -215,7 +215,7 @@ module Instana | |
| 215 215 | 
             
                  response = make_host_agent_request(req)
         | 
| 216 216 |  | 
| 217 217 | 
             
                  if response
         | 
| 218 | 
            -
                    if response.body.length > 2
         | 
| 218 | 
            +
                    if response.body && response.body.length > 2
         | 
| 219 219 | 
             
                      # The host agent returned something indicating that is has a request for us that we
         | 
| 220 220 | 
             
                      # need to process.
         | 
| 221 221 | 
             
                      handle_response(response.body)
         | 
| @@ -19,8 +19,9 @@ if defined?(::Excon) && ::Instana.config[:excon][:enabled] | |
| 19 19 | 
             
                      end
         | 
| 20 20 |  | 
| 21 21 | 
             
                      # Set request headers; encode IDs as hexadecimal strings
         | 
| 22 | 
            -
                       | 
| 23 | 
            -
                      datum[:headers]['X-Instana- | 
| 22 | 
            +
                      t_context = ::Instana.tracer.context
         | 
| 23 | 
            +
                      datum[:headers]['X-Instana-T'] = t_context.trace_id_header
         | 
| 24 | 
            +
                      datum[:headers]['X-Instana-S'] = t_context.span_id_header
         | 
| 24 25 |  | 
| 25 26 | 
             
                      @stack.request_call(datum)
         | 
| 26 27 | 
             
                    end
         | 
| @@ -13,8 +13,9 @@ Net::HTTP.class_eval { | |
| 13 13 | 
             
                request = args[0]
         | 
| 14 14 |  | 
| 15 15 | 
             
                # Set request headers; encode IDs as hexadecimal strings
         | 
| 16 | 
            -
                 | 
| 17 | 
            -
                request['X-Instana- | 
| 16 | 
            +
                t_context = ::Instana.tracer.context
         | 
| 17 | 
            +
                request['X-Instana-T'] = t_context.trace_id_header
         | 
| 18 | 
            +
                request['X-Instana-S'] = t_context.span_id_header
         | 
| 18 19 |  | 
| 19 20 | 
             
                # Collect up KV info now in case any exception is raised
         | 
| 20 21 | 
             
                kv_payload = { :http => {} }
         | 
| @@ -18,8 +18,8 @@ module Instana | |
| 18 18 | 
             
                  # Check incoming context
         | 
| 19 19 | 
             
                  incoming_context = {}
         | 
| 20 20 | 
             
                  if env.key?('HTTP_X_INSTANA_T')
         | 
| 21 | 
            -
                    incoming_context[:trace_id]  = ::Instana. | 
| 22 | 
            -
                    incoming_context[:span_id]   = ::Instana. | 
| 21 | 
            +
                    incoming_context[:trace_id]  = ::Instana::Util.header_to_id(env['HTTP_X_INSTANA_T'])
         | 
| 22 | 
            +
                    incoming_context[:span_id]   = ::Instana::Util.header_to_id(env['HTTP_X_INSTANA_S']) if env.key?('HTTP_X_INSTANA_S')
         | 
| 23 23 | 
             
                    incoming_context[:level]     = env['HTTP_X_INSTANA_L'] if env.key?('HTTP_X_INSTANA_L')
         | 
| 24 24 | 
             
                  end
         | 
| 25 25 |  | 
| @@ -49,8 +49,8 @@ module Instana | |
| 49 49 | 
             
                ensure
         | 
| 50 50 | 
             
                  if headers && ::Instana.tracer.tracing?
         | 
| 51 51 | 
             
                    # Set reponse headers; encode as hex string
         | 
| 52 | 
            -
                    headers['X-Instana-T'] = ::Instana. | 
| 53 | 
            -
                    headers['X-Instana-S'] = ::Instana. | 
| 52 | 
            +
                    headers['X-Instana-T'] = ::Instana::Util.id_to_header(trace_id)
         | 
| 53 | 
            +
                    headers['X-Instana-S'] = ::Instana::Util.id_to_header(span_id)
         | 
| 54 54 | 
             
                  end
         | 
| 55 55 | 
             
                  ::Instana.tracer.log_end(:rack, kvs)
         | 
| 56 56 | 
             
                end
         | 
    
        data/lib/instana/logger.rb
    CHANGED
    
    | @@ -2,7 +2,7 @@ require "logger" | |
| 2 2 |  | 
| 3 3 | 
             
            module Instana
         | 
| 4 4 | 
             
              class XLogger < Logger
         | 
| 5 | 
            -
                LEVELS = [:agent, :agent_comm, :trace, :agent_response].freeze
         | 
| 5 | 
            +
                LEVELS = [:agent, :agent_comm, :trace, :agent_response, :tracing].freeze
         | 
| 6 6 | 
             
                STAMP = "Instana: ".freeze
         | 
| 7 7 |  | 
| 8 8 | 
             
                def initialize(*args)
         | 
| @@ -22,8 +22,9 @@ module Instana | |
| 22 22 | 
             
                #
         | 
| 23 23 | 
             
                # :agent          - All agent related messages such as state & announcements
         | 
| 24 24 | 
             
                # :agent_comm     - Output all payload comm sent between this Ruby gem and the host agent
         | 
| 25 | 
            -
                # :trace          - Output all traces reported to the host agent
         | 
| 26 25 | 
             
                # :agent_response - Outputs messages related to handling requests received by the host agent
         | 
| 26 | 
            +
                # :trace          - Output all traces reported to the host agent
         | 
| 27 | 
            +
                # :tracing        - Output messages related to tracing components, spans and management
         | 
| 27 28 | 
             
                #
         | 
| 28 29 | 
             
                # To use:
         | 
| 29 30 | 
             
                # ::Instana.logger.debug_level = [:agent_comm, :trace]
         | 
| @@ -52,13 +53,18 @@ module Instana | |
| 52 53 | 
             
                  self.debug(msg)
         | 
| 53 54 | 
             
                end
         | 
| 54 55 |  | 
| 56 | 
            +
                def agent_response(msg)
         | 
| 57 | 
            +
                  return unless @level_agent_response
         | 
| 58 | 
            +
                  self.debug(msg)
         | 
| 59 | 
            +
                end
         | 
| 60 | 
            +
             | 
| 55 61 | 
             
                def trace(msg)
         | 
| 56 62 | 
             
                  return unless @level_trace
         | 
| 57 63 | 
             
                  self.debug(msg)
         | 
| 58 64 | 
             
                end
         | 
| 59 65 |  | 
| 60 | 
            -
                def  | 
| 61 | 
            -
                  return unless @ | 
| 66 | 
            +
                def tracing(msg)
         | 
| 67 | 
            +
                  return unless @level_tracing
         | 
| 62 68 | 
             
                  self.debug(msg)
         | 
| 63 69 | 
             
                end
         | 
| 64 70 |  | 
| @@ -0,0 +1,18 @@ | |
| 1 | 
            +
            module OpenTracing
         | 
| 2 | 
            +
              class << self
         | 
| 3 | 
            +
                # Text format for #inject and #extract
         | 
| 4 | 
            +
                FORMAT_TEXT_MAP = 1
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                # Binary format for #inject and #extract
         | 
| 7 | 
            +
                FORMAT_BINARY = 2
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                # Ruby Specific format to handle how Rack changes environment variables.
         | 
| 10 | 
            +
                FORMAT_RACK = 3
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                attr_accessor :global_tracer
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                def method_missing(method_name, *args, &block)
         | 
| 15 | 
            +
                  @global_tracer.send(method_name, *args, &block)
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
              end
         | 
| 18 | 
            +
            end
         | 
    
        data/lib/instana/setup.rb
    CHANGED
    
    | @@ -11,6 +11,9 @@ require "instana/instrumentation" | |
| 11 11 |  | 
| 12 12 | 
             
            ::Instana.agent.setup
         | 
| 13 13 |  | 
| 14 | 
            +
            # Require supported OpenTracing interfaces
         | 
| 15 | 
            +
            require "opentracing"
         | 
| 16 | 
            +
             | 
| 14 17 | 
             
            # The Instana agent is now setup.  The only remaining
         | 
| 15 18 | 
             
            # task for a complete boot is to call
         | 
| 16 19 | 
             
            # `Instana.agent.start` in the thread of your choice.
         | 
    
        data/lib/instana/tracer.rb
    CHANGED
    
    | @@ -1,6 +1,7 @@ | |
| 1 1 | 
             
            require "instana/thread_local"
         | 
| 2 2 | 
             
            require "instana/tracing/trace"
         | 
| 3 3 | 
             
            require "instana/tracing/span"
         | 
| 4 | 
            +
            require "instana/tracing/span_context"
         | 
| 4 5 |  | 
| 5 6 | 
             
            module Instana
         | 
| 6 7 | 
             
              class Tracer
         | 
| @@ -126,10 +127,10 @@ module Instana | |
| 126 127 | 
             
                # @param name [String] the name of the span to end
         | 
| 127 128 | 
             
                # @param kvs [Hash] list of key values to be reported in the span
         | 
| 128 129 | 
             
                #
         | 
| 129 | 
            -
                def log_end(name, kvs = {})
         | 
| 130 | 
            +
                def log_end(name, kvs = {}, end_time = Time.now)
         | 
| 130 131 | 
             
                  return unless tracing?
         | 
| 131 132 |  | 
| 132 | 
            -
                  self.current_trace.finish(kvs)
         | 
| 133 | 
            +
                  self.current_trace.finish(kvs, end_time)
         | 
| 133 134 |  | 
| 134 135 | 
             
                  if !self.current_trace.has_async? ||
         | 
| 135 136 | 
             
                      (self.current_trace.has_async? && self.current_trace.complete?)
         | 
| @@ -156,7 +157,7 @@ module Instana | |
| 156 157 | 
             
                #   :trace_id => 12345
         | 
| 157 158 | 
             
                #   :span_id => 12345
         | 
| 158 159 | 
             
                #
         | 
| 159 | 
            -
                def log_async_entry(name, kvs | 
| 160 | 
            +
                def log_async_entry(name, kvs)
         | 
| 160 161 | 
             
                  return unless tracing?
         | 
| 161 162 | 
             
                  self.current_trace.new_async_span(name, kvs)
         | 
| 162 163 | 
             
                end
         | 
| @@ -164,41 +165,38 @@ module Instana | |
| 164 165 | 
             
                # Add info to an asynchronous span
         | 
| 165 166 | 
             
                #
         | 
| 166 167 | 
             
                # @param kvs [Hash] list of key values to be reported in the span
         | 
| 167 | 
            -
                # @param  | 
| 168 | 
            -
                #    | 
| 169 | 
            -
                #   :span_id => 12345
         | 
| 170 | 
            -
                #   This can be retrieved by using ::Instana.tracer.context
         | 
| 168 | 
            +
                # @param span [Span] the span for this Async op (previously returned
         | 
| 169 | 
            +
                #   from `log_async_entry`)
         | 
| 171 170 | 
             
                #
         | 
| 172 | 
            -
                def log_async_info(kvs,  | 
| 171 | 
            +
                def log_async_info(kvs, span)
         | 
| 173 172 | 
             
                  # Asynchronous spans can persist longer than the parent
         | 
| 174 173 | 
             
                  # trace.  With the trace ID, we check the current trace
         | 
| 175 174 | 
             
                  # but otherwise, we search staged traces.
         | 
| 176 175 |  | 
| 177 | 
            -
                  if tracing? && self.current_trace.id ==  | 
| 178 | 
            -
                    self.current_trace.add_async_info(kvs,  | 
| 176 | 
            +
                  if tracing? && self.current_trace.id == span.context.trace_id
         | 
| 177 | 
            +
                    self.current_trace.add_async_info(kvs, span)
         | 
| 179 178 | 
             
                  else
         | 
| 180 | 
            -
                    trace = ::Instana.processor.staged_trace( | 
| 181 | 
            -
                    trace.add_async_info(kvs,  | 
| 179 | 
            +
                    trace = ::Instana.processor.staged_trace(span.context.trace_id)
         | 
| 180 | 
            +
                    trace.add_async_info(kvs, span)
         | 
| 182 181 | 
             
                  end
         | 
| 183 182 | 
             
                end
         | 
| 184 183 |  | 
| 185 184 | 
             
                # Add an error to an asynchronous span
         | 
| 186 185 | 
             
                #
         | 
| 187 186 | 
             
                # @param e [Exception] Add exception to the current span
         | 
| 188 | 
            -
                # @param  | 
| 189 | 
            -
                #    | 
| 190 | 
            -
                #   :span_id => 12345
         | 
| 187 | 
            +
                # @param span [Span] the span for this Async op (previously returned
         | 
| 188 | 
            +
                #   from `log_async_entry`)
         | 
| 191 189 | 
             
                #
         | 
| 192 | 
            -
                def log_async_error(e,  | 
| 190 | 
            +
                def log_async_error(e, span)
         | 
| 193 191 | 
             
                  # Asynchronous spans can persist longer than the parent
         | 
| 194 192 | 
             
                  # trace.  With the trace ID, we check the current trace
         | 
| 195 193 | 
             
                  # but otherwise, we search staged traces.
         | 
| 196 194 |  | 
| 197 | 
            -
                  if tracing? && self.current_trace.id ==  | 
| 198 | 
            -
                    self.current_trace.add_async_error(e,  | 
| 195 | 
            +
                  if tracing? && self.current_trace.id == span.context.trace_id
         | 
| 196 | 
            +
                    self.current_trace.add_async_error(e, span)
         | 
| 199 197 | 
             
                  else
         | 
| 200 | 
            -
                    trace = ::Instana.processor.staged_trace( | 
| 201 | 
            -
                    trace.add_async_error(e,  | 
| 198 | 
            +
                    trace = ::Instana.processor.staged_trace(span.context.trace_id)
         | 
| 199 | 
            +
                    trace.add_async_error(e, span)
         | 
| 202 200 | 
             
                  end
         | 
| 203 201 | 
             
                end
         | 
| 204 202 |  | 
| @@ -206,29 +204,92 @@ module Instana | |
| 206 204 | 
             
                #
         | 
| 207 205 | 
             
                # @param name [String] the name of the async span to exit (close out)
         | 
| 208 206 | 
             
                # @param kvs [Hash] list of key values to be reported in the span
         | 
| 209 | 
            -
                # @param  | 
| 210 | 
            -
                #    | 
| 211 | 
            -
                #   :span_id => 12345
         | 
| 207 | 
            +
                # @param span [Span] the span for this Async op (previously returned
         | 
| 208 | 
            +
                #   from `log_async_entry`)
         | 
| 212 209 | 
             
                #
         | 
| 213 | 
            -
                def log_async_exit(name, kvs,  | 
| 210 | 
            +
                def log_async_exit(name, kvs, span)
         | 
| 214 211 | 
             
                  # An asynchronous span can end after the current trace has
         | 
| 215 212 | 
             
                  # already completed so we make sure that we end the span
         | 
| 216 213 | 
             
                  # on the right trace.
         | 
| 217 214 |  | 
| 218 | 
            -
                  if tracing? &&  | 
| 219 | 
            -
                    self.current_trace.end_async_span(kvs,  | 
| 215 | 
            +
                  if tracing? && self.current_trace.id == span.context.trace_id
         | 
| 216 | 
            +
                    self.current_trace.end_async_span(kvs, span)
         | 
| 220 217 | 
             
                  else
         | 
| 221 218 | 
             
                    # Different trace from current so find the staged trace
         | 
| 222 219 | 
             
                    # and close out the span on it.
         | 
| 223 | 
            -
                    trace = ::Instana.processor.staged_trace( | 
| 220 | 
            +
                    trace = ::Instana.processor.staged_trace(span.context.trace_id)
         | 
| 224 221 | 
             
                    if trace
         | 
| 225 | 
            -
                      trace.end_async_span(kvs,  | 
| 222 | 
            +
                      trace.end_async_span(kvs, span)
         | 
| 226 223 | 
             
                    else
         | 
| 227 | 
            -
                      ::Instana.logger.debug "log_async_exit: Couldn't find staged trace. #{ | 
| 224 | 
            +
                      ::Instana.logger.debug "log_async_exit: Couldn't find staged trace. #{span.inspect}"
         | 
| 228 225 | 
             
                    end
         | 
| 229 226 | 
             
                  end
         | 
| 230 227 | 
             
                end
         | 
| 231 228 |  | 
| 229 | 
            +
                ###########################################################################
         | 
| 230 | 
            +
                # OpenTracing Support
         | 
| 231 | 
            +
                ###########################################################################
         | 
| 232 | 
            +
             | 
| 233 | 
            +
                # Start a new span
         | 
| 234 | 
            +
                #
         | 
| 235 | 
            +
                # @param operation_name [String] The name of the operation represented by the span
         | 
| 236 | 
            +
                # @param child_of [Span] A span to be used as the ChildOf reference
         | 
| 237 | 
            +
                # @param start_time [Time] the start time of the span
         | 
| 238 | 
            +
                # @param tags [Hash] Starting tags for the span
         | 
| 239 | 
            +
                #
         | 
| 240 | 
            +
                # @return [Span]
         | 
| 241 | 
            +
                #
         | 
| 242 | 
            +
                def start_span(operation_name, child_of: nil, start_time: Time.now, tags: nil)
         | 
| 243 | 
            +
                  return unless ::Instana.agent.ready?
         | 
| 244 | 
            +
             | 
| 245 | 
            +
                  if tracing?
         | 
| 246 | 
            +
                    span = self.current_trace.new_span(operation_name, tags, start_time, child_of)
         | 
| 247 | 
            +
                  else
         | 
| 248 | 
            +
                    self.current_trace = ::Instana::Trace.new(operation_name, tags, nil, start_time)
         | 
| 249 | 
            +
                    span = self.current_trace.current_span
         | 
| 250 | 
            +
                  end
         | 
| 251 | 
            +
                  span.set_tags(tags)
         | 
| 252 | 
            +
                  span
         | 
| 253 | 
            +
                end
         | 
| 254 | 
            +
             | 
| 255 | 
            +
                # Inject a span into the given carrier
         | 
| 256 | 
            +
                #
         | 
| 257 | 
            +
                # @param span_context [SpanContext]
         | 
| 258 | 
            +
                # @param format [OpenTracing::FORMAT_TEXT_MAP, OpenTracing::FORMAT_BINARY, OpenTracing::FORMAT_RACK]
         | 
| 259 | 
            +
                # @param carrier [Carrier]
         | 
| 260 | 
            +
                #
         | 
| 261 | 
            +
                def inject(span_context, format, carrier)
         | 
| 262 | 
            +
                  case format
         | 
| 263 | 
            +
                  when OpenTracing::FORMAT_TEXT_MAP, OpenTracing::FORMAT_BINARY
         | 
| 264 | 
            +
                    ::Instana.logger.debug 'Unsupported inject format'
         | 
| 265 | 
            +
                  when OpenTracing::FORMAT_RACK
         | 
| 266 | 
            +
                    carrier['X-Instana-T'] = ::Instana::Util.id_to_header(span_context.trace_id)
         | 
| 267 | 
            +
                    carrier['X-Instana-S'] = ::Instana::Util.id_to_header(span_context.span_id)
         | 
| 268 | 
            +
                  else
         | 
| 269 | 
            +
                    ::Instana.logger.debug 'Unknown inject format'
         | 
| 270 | 
            +
                  end
         | 
| 271 | 
            +
                end
         | 
| 272 | 
            +
             | 
| 273 | 
            +
                # Extract a span from a carrier
         | 
| 274 | 
            +
                #
         | 
| 275 | 
            +
                # @param format [OpenTracing::FORMAT_TEXT_MAP, OpenTracing::FORMAT_BINARY, OpenTracing::FORMAT_RACK]
         | 
| 276 | 
            +
                # @param carrier [Carrier]
         | 
| 277 | 
            +
                #
         | 
| 278 | 
            +
                # @return [SpanContext]
         | 
| 279 | 
            +
                #
         | 
| 280 | 
            +
                def extract(format, carrier)
         | 
| 281 | 
            +
                  case format
         | 
| 282 | 
            +
                  when OpenTracing::FORMAT_TEXT_MAP, OpenTracing::FORMAT_BINARY
         | 
| 283 | 
            +
                    ::Instana.logger.debug 'Unsupported extract format'
         | 
| 284 | 
            +
                  when OpenTracing::FORMAT_RACK
         | 
| 285 | 
            +
                    ::Instana::SpanContext.new(::Instana::Util.header_to_id(carrier['HTTP_X_INSTANA_T']),
         | 
| 286 | 
            +
                                                 ::Instana::Util.header_to_id(carrier['HTTP_X_INSTANA_S']))
         | 
| 287 | 
            +
                  else
         | 
| 288 | 
            +
                    ::Instana.logger.debug 'Unknown inject format'
         | 
| 289 | 
            +
                    nil
         | 
| 290 | 
            +
                  end
         | 
| 291 | 
            +
                end
         | 
| 292 | 
            +
             | 
| 232 293 | 
             
                ###########################################################################
         | 
| 233 294 | 
             
                # Helper methods
         | 
| 234 295 | 
             
                ###########################################################################
         | 
| @@ -248,11 +309,11 @@ module Instana | |
| 248 309 |  | 
| 249 310 | 
             
                # Retrieve the current context of the tracer.
         | 
| 250 311 | 
             
                #
         | 
| 312 | 
            +
                # @return [SpanContext] or nil if not tracing
         | 
| 313 | 
            +
                #
         | 
| 251 314 | 
             
                def context
         | 
| 252 315 | 
             
                  return nil unless tracing?
         | 
| 253 | 
            -
             | 
| 254 | 
            -
                  { :trace_id => self.current_trace.id,
         | 
| 255 | 
            -
                    :span_id => self.current_trace.current_span_id }
         | 
| 316 | 
            +
                  self.current_trace.current_span.context
         | 
| 256 317 | 
             
                end
         | 
| 257 318 |  | 
| 258 319 | 
             
                # Take the current trace_id and convert it to a header compatible
         | 
| @@ -261,7 +322,7 @@ module Instana | |
| 261 322 | 
             
                # @return [String] a hexadecimal representation of the current trace ID
         | 
| 262 323 | 
             
                #
         | 
| 263 324 | 
             
                def trace_id_header
         | 
| 264 | 
            -
                  id_to_header(trace_id)
         | 
| 325 | 
            +
                  ::Instana::Util.id_to_header(trace_id)
         | 
| 265 326 | 
             
                end
         | 
| 266 327 |  | 
| 267 328 | 
             
                # Take the current span_id and convert it to a header compatible
         | 
| @@ -270,41 +331,7 @@ module Instana | |
| 270 331 | 
             
                # @return [String] a hexadecimal representation of the current span ID
         | 
| 271 332 | 
             
                #
         | 
| 272 333 | 
             
                def span_id_header
         | 
| 273 | 
            -
                  id_to_header(span_id)
         | 
| 274 | 
            -
                end
         | 
| 275 | 
            -
             | 
| 276 | 
            -
                # Convert an ID to a value appropriate to pass in a header.
         | 
| 277 | 
            -
                #
         | 
| 278 | 
            -
                # @param id [Integer] the id to be converted
         | 
| 279 | 
            -
                #
         | 
| 280 | 
            -
                # @return [String]
         | 
| 281 | 
            -
                #
         | 
| 282 | 
            -
                def id_to_header(id)
         | 
| 283 | 
            -
                  unless id.is_a?(Integer) || id.is_a?(String)
         | 
| 284 | 
            -
                    Instana.logger.debug "id_to_header received a #{id.class}: returning empty string"
         | 
| 285 | 
            -
                    return String.new
         | 
| 286 | 
            -
                  end
         | 
| 287 | 
            -
                  [id.to_i].pack('q>').unpack('H*')[0]
         | 
| 288 | 
            -
                rescue => e
         | 
| 289 | 
            -
                  Instana.logger.error "#{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}"
         | 
| 290 | 
            -
                  Instana.logger.debug e.backtrace.join("\r\n")
         | 
| 291 | 
            -
                end
         | 
| 292 | 
            -
             | 
| 293 | 
            -
                # Convert a received header value into a valid ID
         | 
| 294 | 
            -
                #
         | 
| 295 | 
            -
                # @param header_id [String] the header value to be converted
         | 
| 296 | 
            -
                #
         | 
| 297 | 
            -
                # @return [Integer]
         | 
| 298 | 
            -
                #
         | 
| 299 | 
            -
                def header_to_id(header_id)
         | 
| 300 | 
            -
                  if !header_id.is_a?(String)
         | 
| 301 | 
            -
                    Instana.logger.debug "header_to_id received a #{header_id.class}: returning 0"
         | 
| 302 | 
            -
                    return 0
         | 
| 303 | 
            -
                  end
         | 
| 304 | 
            -
                  [header_id].pack("H*").unpack("q>")[0]
         | 
| 305 | 
            -
                rescue => e
         | 
| 306 | 
            -
                  Instana.logger.error "#{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}"
         | 
| 307 | 
            -
                  Instana.logger.debug e.backtrace.join("\r\n")
         | 
| 334 | 
            +
                  ::Instana::Util.id_to_header(span_id)
         | 
| 308 335 | 
             
                end
         | 
| 309 336 |  | 
| 310 337 | 
             
                # Returns the trace ID for the active trace (if there is one),
         | 
| @@ -320,5 +347,17 @@ module Instana | |
| 320 347 | 
             
                def span_id
         | 
| 321 348 | 
             
                  self.current_trace  ? current_trace.current_span_id : nil
         | 
| 322 349 | 
             
                end
         | 
| 350 | 
            +
             | 
| 351 | 
            +
                # Helper method to retrieve the currently active span for the active trace.
         | 
| 352 | 
            +
                #
         | 
| 353 | 
            +
                def current_span
         | 
| 354 | 
            +
                  self.current_trace ? self.current_trace.current_span : nil
         | 
| 355 | 
            +
                end
         | 
| 356 | 
            +
             | 
| 357 | 
            +
                # Used in the test suite, this resets the tracer to non-tracing state.
         | 
| 358 | 
            +
                #
         | 
| 359 | 
            +
                def clear!
         | 
| 360 | 
            +
                  self.current_trace = nil
         | 
| 361 | 
            +
                end
         | 
| 323 362 | 
             
              end
         | 
| 324 363 | 
             
            end
         |