Sha256: 7ba2e72db077fa12f12e20371b928e4b98181962e50b7097f59e837143714119

Contents?: true

Size: 1.69 KB

Versions: 2

Compression:

Stored size: 1.69 KB

Contents

# frozen_string_literal: true

require 'elastic_apm/stacktrace/frame'

module ElasticAPM
  # @api private
  class Stacktrace
    def initialize(backtrace)
      @backtrace = backtrace
    end

    attr_reader :frames

    def self.build(builder, backtrace)
      return nil unless backtrace

      stack = new(backtrace)
      stack.build_frames(builder)
      stack
    end

    def build_frames(builder)
      @frames = @backtrace.reverse.map do |line|
        build_frame(builder, line)
      end
    end

    def length
      frames.length
    end

    def to_a
      frames.map(&:to_h)
    end

    private

    JAVA_FORMAT = /^(.+)\.([^\.]+)\(([^\:]+)\:(\d+)\)$/
    RUBY_FORMAT = /^(.+?):(\d+)(?::in `(.+?)')?$/

    def parse_line(line)
      ruby_match = line.match(RUBY_FORMAT)

      if ruby_match
        _, file, number, method = ruby_match.to_a
        file.sub!(/\.class$/, '.rb')
        module_name = nil
      else
        java_match = line.match(JAVA_FORMAT)
        _, module_name, method, file, number = java_match.to_a
      end

      [file, number, method, module_name]
    end

    def build_frame(_builder, line)
      abs_path, lineno, function, _module_name = parse_line(line)

      frame = Frame.new
      frame.abs_path = abs_path
      frame.filename = strip_load_path(abs_path)
      frame.function = function
      frame.lineno = lineno.to_i
      frame.build_context 3

      frame
    end

    def strip_load_path(path)
      return nil unless path

      prefix =
        $LOAD_PATH
        .map(&:to_s)
        .select { |s| path.start_with?(s) }
        .sort_by(&:length)
        .last

      return path unless prefix

      path[prefix.chomp(File::SEPARATOR).length + 1..-1]
    end
  end
end

Version data entries

2 entries across 2 versions & 1 rubygems

Version Path
elastic-apm-0.2.0 lib/elastic_apm/stacktrace.rb
elastic-apm-0.1.0 lib/elastic_apm/stacktrace.rb