Module: TingYun::TingYunService::UploadService

Included in:
TingYun::TingYunService
Defined in:
lib/ting_yun/ting_yun_service/upload_service.rb

Constant Summary collapse

EMPTY_PARENT =
''.freeze

Instance Method Summary collapse

Instance Method Details

#base64_compressed_jsonObject



15
16
17
# File 'lib/ting_yun/ting_yun_service/upload_service.rb', line 15

def base64_compressed_json
  TingYun::Support::Serialize::Encoders::Base64CompressedJSON
end

#build_metric_data_array(stats_hash) ⇒ Object

The collector wants to recieve metric data in a format that’s different from how we store it inte -nally, so this method handles the translation. It also handles translating metric names to IDs using our metric ID cache.



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/ting_yun/ting_yun_service/upload_service.rb', line 49

def build_metric_data_array(stats_hash)
  action_array = []
  adpex_array = []
  general_array = []
  components_array = []
  errors_array = []
  stats_hash.each do |metric_spec, stats|

    # Omit empty stats as an optimization
    unless stats.is_reset?
      metric_id = metric_id_cache[metric_spec.hash]

      if metric_spec.name.start_with?('WebAction','BackgroundAction')
        action_array << TingYun::Metrics::MetricData.new(metric_spec, stats, metric_id)
      elsif metric_spec.name.start_with?('Apdex')
        adpex_array << TingYun::Metrics::MetricData.new(metric_spec, stats, metric_id)
      elsif metric_spec.name.start_with?('Errors') && metric_spec.scope.empty?
        errors_array << TingYun::Metrics::MetricData.new(metric_spec, stats, metric_id)
      elsif metric_spec.name.start_with?('Database','View','MongoDB','Redis','Memcached','External','Nested', 'CPU', 'Memory', 'WebFrontend','Rake')
        if metric_spec.scope.empty?
          general_array << TingYun::Metrics::MetricData.new(metric_spec, stats, metric_id)
        else
          components_array << TingYun::Metrics::MetricData.new(metric_spec, stats, metric_id) unless metric_spec.name.start_with?('External/NULL')
        end
      elsif metric_spec.name.start_with?('cross_app')
        external =  metric_spec.name.split(';')
        if metric_spec.scope.empty?
          metric_spec.name = "ExternalTransaction/NULL/#{external[1]}"
          general_array << TingYun::Metrics::MetricData.new(metric_spec, stats, metric_id)
        else
          metric_spec.name = "External/#{external[3]}"
          metric_spec.calleeId = external[1]
          metric_spec.calleeName = external[2]
          components_array << TingYun::Metrics::MetricData.new(metric_spec, stats, metric_id)
        end

      end
    end
  end

  [action_array, adpex_array, general_array, components_array, errors_array]
end

#compressed_jsonObject



11
12
13
# File 'lib/ting_yun/ting_yun_service/upload_service.rb', line 11

def compressed_json
  TingYun::Support::Serialize::Encoders::CompressedJSON
end

#fill_metric_id_cache(pairs_of_specs_and_ids) ⇒ Object

takes an array of arrays of spec and id, adds it into the metric cache so we can save the collector some work by sending integers instead of strings the next time around



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/ting_yun/ting_yun_service/upload_service.rb', line 96

def fill_metric_id_cache(pairs_of_specs_and_ids)
  pairs_of_specs_and_ids.each do |_, value|
    if value.is_a? Array
      value.each do |array|
        if array.is_a? Array
          metric_id_cache[array[0]['name'].hash ^ (array[0]['parent']||EMPTY_PARENT).hash] = array[1]
        end
      end
    end
  end
rescue => e
  # If we've gotten this far, we don't want this error to propagate and
  # make this post appear to have been non-successful, which would trigger
  # re-aggregation of the same metric data into the next post, so just log
  TingYun::Agent.logger.error("Failed to fill metric ID cache from response, error details follow ", e)
end

#jsonObject



19
20
21
# File 'lib/ting_yun/ting_yun_service/upload_service.rb', line 19

def json
  TingYun::Support::Serialize::Encoders::Json
end

#metric_data(stats_hash) ⇒ Object



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/ting_yun/ting_yun_service/upload_service.rb', line 23

def metric_data(stats_hash)

  timeslice_start = stats_hash.started_at
  timeslice_end = stats_hash.harvested_at || Time.now

  action_array, adpex_array, general_array, components_array, errors_array = build_metric_data_array(stats_hash)

  upload_data = {
      :type => 'perfMetrics',
      :timeFrom => timeslice_start.to_i,
      :timeTo => timeslice_end.to_i,
      :interval => 60,
      :actions => action_array,
      :apdex => adpex_array,
      :components => components_array,
      :general => general_array,
      :errors  => errors_array
  }
  result = invoke_remote(:upload, [upload_data])
  fill_metric_id_cache(result)
  result
end