class Atatus::Builder

Attributes

config[R]

Public Class Methods

new(config) click to toggle source
# File lib/atatus/collector/builder.rb, line 7
def initialize(config)
  @config = config
  @metadata = Metadata::SystemInfo.new(config)
  @container_id = nil
  if
    !@metadata.container.nil? &&
    @metadata.container.key?(:id)
  then
    @container_id = @metadata.container[:id]
  end

  @real_hostname = Socket.gethostname
end

Public Instance Methods

common() click to toggle source
# File lib/atatus/collector/builder.rb, line 23
def common()
  common = {
    appName: @config.app_name,
    licenseKey: @config.license_key,
    agent: {
      name: AGENT_NAME,
      version: VERSION
    },
    hostname: @metadata.hostname,
    hostId: @metadata.hwinfo.hostid
  }
  if !@container_id.nil?
    common[:containerId] = @container_id
  end
  common
end
error_metrics(start_time, end_time, metrics_data, requests_data) click to toggle source
# File lib/atatus/collector/builder.rb, line 71
def error_metrics(start_time, end_time, metrics_data, requests_data)
  payload = common()
  payload[:startTime] = start_time
  payload[:endTime] = end_time
  payload[:errorMetrics] = build_error_metrics_obj(metrics_data)
  payload[:errorRequests] = build_error_requests_obj(requests_data)
  payload
end
errors(start_time, end_time, error_data) click to toggle source
# File lib/atatus/collector/builder.rb, line 80
def errors(start_time, end_time, error_data)
  payload = common()
  payload[:errors] = build_errors_obj(error_data)
  payload
end
hostinfo(start_time) click to toggle source
# File lib/atatus/collector/builder.rb, line 40
def hostinfo(start_time)
  payload = common()
  payload[:timestamp] = start_time
  payload[:environment] = build_hostinfo_obj()
  payload
end
metrics(start_time, end_time, metric_data) click to toggle source
# File lib/atatus/collector/builder.rb, line 86
def metrics(start_time, end_time, metric_data)
  payload = common()
  payload[:startTime] = start_time
  payload[:endTime] = end_time
  payload[:ruby] = metric_data
  payload
end
traces(start_time, end_time, data) click to toggle source
# File lib/atatus/collector/builder.rb, line 63
def traces(start_time, end_time, data)
  payload = common()
  payload[:startTime] = start_time
  payload[:endTime] = end_time
  payload[:traces] = build_traces_obj(data)
  payload
end
txn_hist(start_time, end_time, data) click to toggle source
# File lib/atatus/collector/builder.rb, line 55
def txn_hist(start_time, end_time, data)
  payload = common()
  payload[:startTime] = start_time
  payload[:endTime] = end_time
  payload[:transactions] = build_txn_hist_obj(data)
  payload
end
txns(start_time, end_time, data) click to toggle source
# File lib/atatus/collector/builder.rb, line 47
def txns(start_time, end_time, data)
  payload = common()
  payload[:startTime] = start_time
  payload[:endTime] = end_time
  payload[:transactions] = build_txns_obj(data)
  payload
end

Private Instance Methods

build_error_metrics_obj(metrics_data) click to toggle source
# File lib/atatus/collector/builder.rb, line 328
def build_error_metrics_obj(metrics_data)
  error_metrics = []
  metrics_data.each do |t, v|
    error_metric = {}
    error_metric[:name] = t
    error_metric[:type] = @config.framework_name || AGENT_NAME
    error_metric[:kind] = AGENT_NAME
    error_metric[:statusCodes] = v
    error_metrics << error_metric
  end
  error_metrics
end
build_error_requests_obj(requests_data) click to toggle source
# File lib/atatus/collector/builder.rb, line 341
def build_error_requests_obj(requests_data)
  error_requests = []
  requests_data.each do |v|
    if
      !v.key?('name') ||
      !v.key?('context')
    then
      next
    end
    error_request = {}
    error_request[:name] = v['name']
    error_request[:type] = @config.framework_name || AGENT_NAME
    error_request[:kind] = AGENT_NAME
    error_request[:request] = build_request(v['context'])
    error_requests << error_request
  end
  error_requests
end
build_errors_obj(data) click to toggle source
# File lib/atatus/collector/builder.rb, line 360
def build_errors_obj(data)
  errors = []
  data.each do |v|
    if
      v.timestamp.nil? ||
      v.exception.nil?
    then
      next
    end

    if
      v.exception.type.nil? ||
      v.exception.message.nil?
    then
      next
    end

    error = {}
    error[:timestamp] = v.timestamp

    if
      !v.transaction.nil? &&
      v.transaction.key?(:name)
    then
      error[:transaction] = v.transaction[:name]
    end

    if !v.context.nil?
      error[:request] = build_request(v.context)
    end
    error[:exceptions] = []
    exception = {}
    exception[:class] = v.exception.type
    exception[:message] = v.exception.message
    exception[:stacktrace] = []
    if
      !v.exception.stacktrace.nil? &&
      !v.exception.stacktrace.frames.nil?
    then
      v.exception.stacktrace.frames.each do |f|
        if
          f.filename.nil? ||
          f.function.nil? ||
          f.lineno.nil? ||
          f.library_frame.nil?
        then
          next
        end

        frame = {}
        frame[:f] = f.filename
        frame[:m] = f.function
        frame[:ln] = f.lineno.to_i
        if f.library_frame == false
          frame[:inp] = true
        end
        if !f.context_line.nil?
          frame[:code] = []

          if f.library_frame == false && !f.pre_context.nil?
            psize = f.pre_context.size
            lineno = 0
            if f.lineno - psize >= 0
              lineno = f.lineno - psize
            end
            f.pre_context.each do |c|
              frame[:code].push([lineno.to_s, c])
              lineno += 1
            end
          end

          frame[:code].push([f.lineno.to_s, f.context_line])

          if f.library_frame == false && !f.post_context.nil?
            psize = f.post_context.size
            lineno = f.lineno + 1
            f.post_context.each do |c|
              frame[:code].push([lineno.to_s, c])
              lineno += 1
            end
          end
        end
        exception[:stacktrace] << frame
      end
    end
    error[:exceptions] << exception
    errors << error
  end
  errors
end
build_hist_metric(name, value) click to toggle source
# File lib/atatus/collector/builder.rb, line 159
def build_hist_metric(name, value)
  return unless name
  return unless value

  m = {
      name: name,
      type: value.type,
      kind: value.kind,
      histogram: value.hist,
    }

  m
end
build_hostinfo_env_host() click to toggle source
# File lib/atatus/collector/builder.rb, line 108
def build_hostinfo_env_host()
  host_info = {
    cpu: [@metadata.hwinfo.cpuinfo],
    ram: @metadata.hwinfo.meminfo,
    hostname: @real_hostname,
    bootId: @metadata.hwinfo.hostid,
    hostId: @metadata.hwinfo.hostid,
    os: @metadata.osinfo.os,
    kernel: @metadata.osinfo.kernel
  }
  if !@container_id.nil?
    host_info[:containerId] = @container_id
  end
  host_info
end
build_hostinfo_env_settings() click to toggle source
# File lib/atatus/collector/builder.rb, line 124
def build_hostinfo_env_settings()
  {
    agentVersion: VERSION,
    appName: @config.app_name,
    framework: @config.framework_name,
    frameworkVersion: @config.framework_version,
    logLevel: @config.log_level,
    ruby: RUBY_VERSION
  }
end
build_hostinfo_gems() click to toggle source
# File lib/atatus/collector/builder.rb, line 135
def build_hostinfo_gems()
  Bundler.rubygems.all_specs.map {|spec| [spec.name, spec.version.to_s]}.sort.to_h
rescue => e
  {}
end
build_hostinfo_obj() click to toggle source
# File lib/atatus/collector/builder.rb, line 100
def build_hostinfo_obj()
  environment = {}
  environment[:gems] = build_hostinfo_gems()
  environment[:host] = build_hostinfo_env_host()
  environment[:settings] = build_hostinfo_env_settings()
  environment
end
build_metric(name, value, background: false) click to toggle source
# File lib/atatus/collector/builder.rb, line 141
def build_metric(name, value, background: false)
  return unless name
  return unless value

  m = {
      name: name,
      type: value.type,
      kind: value.kind,
      durations: [value.count, Util.ms(value.total), Util.ms(value.min), Util.ms(value.max)],
    }

  if background == true
    m[:background] = background
  end

  m
end
build_request(context) click to toggle source
# File lib/atatus/collector/builder.rb, line 173
def build_request(context)
  request = {}
  return request unless context

  if !context.request.nil?
    r = context.request
    request[:method] = r.method if !r.method.nil?
    if !r.headers.nil?
      h = r.headers
      request[:accept] = h['Accept'] if h.key?('Accept')
      request[:'accept-encoding'] = h['Accept-Encoding'] if h.key?('Accept-Encoding')
      request[:'accept-language'] = h['Accept-Language'] if h.key?('Accept-Language')
      request[:'userAgent'] = h['User-Agent'] if h.key?('User-Agent')
    end

    if !r.url.nil?
      u = r.url
      request[:host] = u.hostname if !u.hostname.nil?
      request[:port] = (u.port).to_i if !u.port.nil?
      request[:path] = u.pathname if !u.pathname.nil?
    end
  end

  if !context.response.nil?
    if !context.response.status_code.nil?
      request[:statusCode] = context.response.status_code.to_i
    end
  end

  request
end
build_traces_obj(data) click to toggle source
# File lib/atatus/collector/builder.rb, line 230
def build_traces_obj(data)
  traces = []
  data.each do |txn|
    if
      txn.name.nil? ||
      txn.timestamp.nil? ||
      txn.duration.nil?
    then
      next
    end

    trace = {}
    trace[:name] = txn.name
    trace[:type] = @config.framework_name || AGENT_NAME
    trace[:kind] = AGENT_NAME
    trace[:start] = txn.timestamp
    trace[:duration] = Util.ms(txn.duration)
    if !txn.context.nil?
      trace[:request] = build_request(txn.context)
    end
    trace[:entries] = []
    trace[:funcs] = []
    i = 0

    if
      !txn.spans.nil? &&
      !txn.spans.empty?
    then
      txn.spans.each do |span|
        entry = {}
        entry[:lv] = 1
        if span.timestamp >= txn.timestamp
          entry[:so] = Util.ms(span.timestamp - txn.timestamp)
        else
          entry[:so] = 0
        end
        entry[:du] = Util.ms(span.duration)
        entry[:ly] = {}
        entry[:ly][:name] = span.name
        entry[:ly][:type] = Atatus::Collector::Layer.span_type(span.subtype)
        entry[:ly][:kind] = Atatus::Collector::Layer.span_kind(span.type)
        if
          !span.context.nil? &&
          !span.context.db.nil? &&
          defined?(span.context.db.statement) &&
          !span.context.db.statement.nil?
        then
          entry[:dt] = {}
          entry[:dt][:query] = span.context.db.statement
        end
        if
          !span.context.nil? &&
          !span.context.http.nil? &&
          defined?(span.context.http.url) &&
          !span.context.http.url.nil?
        then
          entry[:dt] = {}
          entry[:dt][:url] = span.context.http.url
          entry[:dt][:method] = span.context.http.method if defined?(span.context.http.method) && !span.context.http.method.nil?
          entry[:dt][:status_code] = span.context.http.status_code.to_s if defined?(span.context.http.status_code) && !span.context.http.status_code.nil?
        end
        trace[:entries] << entry
        func_index = trace[:funcs].index(span.name)
        if func_index.nil?
          trace[:funcs] << span.name
          func_index = i
          i = i + 1
        end
        entry[:i] = func_index
      end
    end

    if
      !txn.ruby_time.nil?
    then
      entry = {}
      entry[:lv] = 1
      entry[:so] = 0
      entry[:du] = Util.ms(txn.ruby_time)
      entry[:ly] = {}
      entry[:ly][:name] = AGENT_NAME
      entry[:ly][:type] = AGENT_NAME
      entry[:ly][:kind] = AGENT_NAME
      trace[:entries] << entry
      func_index = trace[:funcs].index(AGENT_NAME)
      if func_index.nil?
        trace[:funcs] << AGENT_NAME
        func_index = i
        i = i + 1
      end
      entry[:i] = func_index
    end

    traces << trace
  end
  traces
end
build_txn_hist_obj(data) click to toggle source
# File lib/atatus/collector/builder.rb, line 219
def build_txn_hist_obj(data)
  txn_hist = []
  data.each do |t, v|
    hist = build_hist_metric(t, v)
    if hist
      txn_hist << hist
    end
  end
  txn_hist
end
build_txns_obj(data) click to toggle source
# File lib/atatus/collector/builder.rb, line 205
def build_txns_obj(data)
  txns = []
  data.each do |t, v|
    txn = build_metric(t, v, background: v.background)
    txn[:traces] = []
    v.spans.each do |l, u|
      txn[:traces] << build_metric(l, u)
    end

    txns << txn
  end
  txns
end
keyword_field(value) click to toggle source
# File lib/atatus/collector/builder.rb, line 96
def keyword_field(value)
  Util.truncate(value)
end