elastic-apm 2.2.0 → 2.3.0
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.
Potentially problematic release.
This version of elastic-apm might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.rubocop.yml +3 -0
- data/CHANGELOG.md +6 -0
- data/docs/configuration.asciidoc +17 -0
- data/docs/index.asciidoc +2 -0
- data/docs/metrics.asciidoc +72 -0
- data/lib/elastic_apm/agent.rb +7 -2
- data/lib/elastic_apm/config.rb +15 -2
- data/lib/elastic_apm/error.rb +3 -2
- data/lib/elastic_apm/error_builder.rb +4 -3
- data/lib/elastic_apm/metrics.rb +84 -0
- data/lib/elastic_apm/metrics/cpu_mem.rb +214 -0
- data/lib/elastic_apm/metricset.rb +19 -0
- data/lib/elastic_apm/transport/serializers.rb +7 -3
- data/lib/elastic_apm/transport/serializers/error_serializer.rb +1 -0
- data/lib/elastic_apm/transport/serializers/metricset_serializer.rb +28 -0
- data/lib/elastic_apm/util.rb +1 -1
- data/lib/elastic_apm/version.rb +1 -1
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d759346f9597d0a9b179ca5b0f4b888c6b95b0f3b36efa26c568c423d82a6701
|
4
|
+
data.tar.gz: 1a9a46998c62b9f5d337cf4371f8472c5e337f1fb75a4094f3bd6347e4e9d537
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a969fa9e0929166458d40d775d8577d0579a193f5d2b8fece6e26ddf3d15b8bdb8a5551efd7872d2a6e28a321dff77aadf433eccc4c707be0a70d560d947ccba
|
7
|
+
data.tar.gz: 2f849a3f13569328da9d6726a89ee80e5c9d233c53e4191525e6b95daa64f8b92cba98b981c8591d4440f86f7509056d5a578b9a481a4d278a43c6a9923e70ad
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.
|
|
4
4
|
|
5
5
|
This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
6
6
|
|
7
|
+
## 2.3.0 (2019-01-29)
|
8
|
+
|
9
|
+
### Added
|
10
|
+
|
11
|
+
- Support for Metrics ([#276](https://github.com/elastic/apm-agent-ruby/pull/276))
|
12
|
+
|
7
13
|
## 2.2.0 (2019-01-22)
|
8
14
|
|
9
15
|
### Added
|
data/docs/configuration.asciidoc
CHANGED
@@ -397,6 +397,23 @@ By default Elastic APM logs to `stdout` or uses `Rails.log` when used with Rails
|
|
397
397
|
|
398
398
|
Use this to provide another logger. Expected to have the same API as Ruby's built-in `Logger`.
|
399
399
|
|
400
|
+
[float]
|
401
|
+
[[config-metrics-interval]]
|
402
|
+
==== `metrics_interval`
|
403
|
+
|
404
|
+
[options="header"]
|
405
|
+
|============
|
406
|
+
| Environment | `Config` key | Default
|
407
|
+
| `ELASTIC_APM_METRICS_INTERVAL` | `metrics_interval` | `'30s'`
|
408
|
+
|============
|
409
|
+
|
410
|
+
Specify the interval for reporting metrics to APM Server.
|
411
|
+
The interval should be in seconds,
|
412
|
+
or should include a time suffix.
|
413
|
+
|
414
|
+
To disable metrics reporting,
|
415
|
+
set the interval to `0`.
|
416
|
+
|
400
417
|
[float]
|
401
418
|
[[config-pool-size]]
|
402
419
|
==== `pool_size`
|
data/docs/index.asciidoc
CHANGED
@@ -0,0 +1,72 @@
|
|
1
|
+
ifdef::env-github[]
|
2
|
+
NOTE: For the best reading experience,
|
3
|
+
please view this documentation at https://www.elastic.co/guide/en/apm/agent/ruby[elastic.co]
|
4
|
+
endif::[]
|
5
|
+
|
6
|
+
[[metrics]]
|
7
|
+
== Metrics
|
8
|
+
|
9
|
+
The Ruby agent tracks various system and application metrics.
|
10
|
+
These metrics will be sent regularly to the APM Server and from there to Elasticsearch.
|
11
|
+
You can adjust the interval by setting <<config-metrics-interval,`metrics_interval`>>.
|
12
|
+
|
13
|
+
The metrics will be stored in the `apm-*` index and have the `processor.event` property set to `metric`.
|
14
|
+
|
15
|
+
**Note:** Metrics from the Ruby agent are Linux only for now.
|
16
|
+
|
17
|
+
[float]
|
18
|
+
[[metric-system.cpu.total.norm.pct]]
|
19
|
+
=== `system.cpu.total.norm.pct`
|
20
|
+
|
21
|
+
* *Type:* Float
|
22
|
+
* *Format:* Percent
|
23
|
+
|
24
|
+
The percentage of CPU time in states other than Idle and IOWait,
|
25
|
+
normalised by the number of cores.
|
26
|
+
|
27
|
+
[float]
|
28
|
+
[[metric-system.memory.total]]
|
29
|
+
=== `system.memory.total`
|
30
|
+
|
31
|
+
* *Type:* Long
|
32
|
+
* *Format:* Bytes
|
33
|
+
|
34
|
+
The total memory of the system in bytes.
|
35
|
+
|
36
|
+
[float]
|
37
|
+
[[metric-system.memory.actual.free]]
|
38
|
+
=== `system.memory.actual.free`
|
39
|
+
|
40
|
+
* *Type:* Long
|
41
|
+
* *Format:* Bytes
|
42
|
+
|
43
|
+
Free memory of the system in bytes.
|
44
|
+
|
45
|
+
[float]
|
46
|
+
[[metric-system.process.cpu.total.norm.pct]]
|
47
|
+
=== `system.process.cpu.total.norm.pct`
|
48
|
+
|
49
|
+
* *Type:* Float
|
50
|
+
* *Format:* Percent
|
51
|
+
|
52
|
+
The percentage of CPU time spent by the process since the last event.
|
53
|
+
This value is normalized by the number of CPU cores and it ranges from 0 to 100%.
|
54
|
+
|
55
|
+
[float]
|
56
|
+
[[metric-system.process.memory.size]]
|
57
|
+
=== `system.process.memory.size`
|
58
|
+
|
59
|
+
* *Type:* Long
|
60
|
+
* *Format:* Bytes
|
61
|
+
|
62
|
+
The total virtual memory the process has.
|
63
|
+
|
64
|
+
[float]
|
65
|
+
[[metric-system.process.memory.rss.bytes]]
|
66
|
+
=== `system.process.memory.rss.bytes`
|
67
|
+
|
68
|
+
* *Type:* Long
|
69
|
+
* *Format:* Bytes
|
70
|
+
|
71
|
+
The Resident Set Size,
|
72
|
+
the amount of memory the process occupies in main memory (RAM).
|
data/lib/elastic_apm/agent.rb
CHANGED
@@ -6,6 +6,7 @@ require 'elastic_apm/stacktrace_builder'
|
|
6
6
|
require 'elastic_apm/error'
|
7
7
|
require 'elastic_apm/transport/base'
|
8
8
|
require 'elastic_apm/spies'
|
9
|
+
require 'elastic_apm/metrics'
|
9
10
|
|
10
11
|
module ElasticAPM
|
11
12
|
# rubocop:disable Metrics/ClassLength
|
@@ -55,18 +56,21 @@ module ElasticAPM
|
|
55
56
|
|
56
57
|
@transport = Transport::Base.new(config)
|
57
58
|
@instrumenter = Instrumenter.new(
|
58
|
-
config,
|
59
|
+
config,
|
60
|
+
stacktrace_builder: stacktrace_builder
|
59
61
|
) { |event| enqueue event }
|
62
|
+
@metrics = Metrics.new(config) { |event| enqueue event }
|
60
63
|
end
|
61
64
|
|
62
65
|
attr_reader :config, :transport, :instrumenter,
|
63
|
-
:stacktrace_builder, :context_builder, :error_builder
|
66
|
+
:stacktrace_builder, :context_builder, :error_builder, :metrics
|
64
67
|
|
65
68
|
def start
|
66
69
|
info '[%s] Starting agent, reporting to %s', VERSION, config.server_url
|
67
70
|
|
68
71
|
transport.start
|
69
72
|
instrumenter.start
|
73
|
+
metrics.start
|
70
74
|
|
71
75
|
config.enabled_spies.each do |lib|
|
72
76
|
require "elastic_apm/spies/#{lib}"
|
@@ -80,6 +84,7 @@ module ElasticAPM
|
|
80
84
|
|
81
85
|
instrumenter.stop
|
82
86
|
transport.stop
|
87
|
+
metrics.stop
|
83
88
|
|
84
89
|
self
|
85
90
|
end
|
data/lib/elastic_apm/config.rb
CHANGED
@@ -40,6 +40,7 @@ module ElasticAPM
|
|
40
40
|
instrumented_rake_tasks: [],
|
41
41
|
log_level: Logger::INFO,
|
42
42
|
log_path: nil,
|
43
|
+
metrics_interval: 30,
|
43
44
|
pool_size: 1,
|
44
45
|
source_lines_error_app_frames: 5,
|
45
46
|
source_lines_error_library_frames: 0,
|
@@ -78,6 +79,7 @@ module ElasticAPM
|
|
78
79
|
[:list, 'instrumented_rake_tasks'],
|
79
80
|
'ELASTIC_APM_LOG_LEVEL' => [:int, 'log_level'],
|
80
81
|
'ELASTIC_APM_LOG_PATH' => 'log_path',
|
82
|
+
'ELASTIC_APM_METRICS_INTERVAL' => [:int, 'metrics_interval'],
|
81
83
|
'ELASTIC_APM_POOL_SIZE' => [:int, 'pool_size'],
|
82
84
|
'ELASTIC_APM_SERVICE_NAME' => 'service_name',
|
83
85
|
'ELASTIC_APM_SERVICE_VERSION' => 'service_version',
|
@@ -96,8 +98,14 @@ module ElasticAPM
|
|
96
98
|
'ELASTIC_APM_VERIFY_SERVER_CERT' => [:bool, 'verify_server_cert']
|
97
99
|
}.freeze
|
98
100
|
|
99
|
-
DURATION_KEYS = %i[
|
100
|
-
|
101
|
+
DURATION_KEYS = %i[
|
102
|
+
api_request_time
|
103
|
+
span_frames_min_duration
|
104
|
+
metrics_interval
|
105
|
+
].freeze
|
106
|
+
DURATION_DEFAULT_UNITS = { # default is 's'
|
107
|
+
span_frames_min_duration: 'ms'
|
108
|
+
}.freeze
|
101
109
|
|
102
110
|
SIZE_KEYS = %i[api_request_size].freeze
|
103
111
|
SIZE_DEFAULT_UNITS = { api_request_size: 'kb' }.freeze
|
@@ -146,6 +154,7 @@ module ElasticAPM
|
|
146
154
|
attr_accessor :log_level
|
147
155
|
attr_accessor :log_path
|
148
156
|
attr_accessor :logger
|
157
|
+
attr_accessor :metrics_interval
|
149
158
|
attr_accessor :pool_size
|
150
159
|
attr_accessor :service_name
|
151
160
|
attr_accessor :service_version
|
@@ -277,6 +286,10 @@ module ElasticAPM
|
|
277
286
|
super
|
278
287
|
end
|
279
288
|
|
289
|
+
def collect_metrics?
|
290
|
+
metrics_interval != 0
|
291
|
+
end
|
292
|
+
|
280
293
|
private
|
281
294
|
|
282
295
|
def assign(options)
|
data/lib/elastic_apm/error.rb
CHANGED
@@ -17,11 +17,12 @@ module ElasticAPM
|
|
17
17
|
@context = Context.new
|
18
18
|
|
19
19
|
@transaction_id = nil
|
20
|
+
@transaction = nil
|
20
21
|
@parent_id = nil
|
21
22
|
end
|
22
23
|
|
23
|
-
attr_accessor :id, :culprit, :exception, :log, :transaction_id,
|
24
|
-
:parent_id, :trace_id
|
24
|
+
attr_accessor :id, :culprit, :exception, :log, :transaction_id,
|
25
|
+
:transaction, :context, :parent_id, :trace_id
|
25
26
|
attr_reader :timestamp
|
26
27
|
end
|
27
28
|
end
|
@@ -16,7 +16,7 @@ module ElasticAPM
|
|
16
16
|
add_stacktrace error, :exception, exception.backtrace
|
17
17
|
end
|
18
18
|
|
19
|
-
|
19
|
+
add_current_transaction_fields error
|
20
20
|
|
21
21
|
if (transaction = ElasticAPM.current_transaction)
|
22
22
|
error.context = transaction.context.dup
|
@@ -37,7 +37,7 @@ module ElasticAPM
|
|
37
37
|
add_stacktrace error, :log, backtrace
|
38
38
|
end
|
39
39
|
|
40
|
-
|
40
|
+
add_current_transaction_fields error
|
41
41
|
|
42
42
|
error
|
43
43
|
end
|
@@ -59,9 +59,10 @@ module ElasticAPM
|
|
59
59
|
error.culprit = stacktrace.frames.first.function
|
60
60
|
end
|
61
61
|
|
62
|
-
def
|
62
|
+
def add_current_transaction_fields(error)
|
63
63
|
return unless (transaction = ElasticAPM.current_transaction)
|
64
64
|
error.transaction_id = transaction.id
|
65
|
+
error.transaction = { sampled: transaction.sampled? }
|
65
66
|
end
|
66
67
|
end
|
67
68
|
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'elastic_apm/metricset'
|
4
|
+
|
5
|
+
module ElasticAPM
|
6
|
+
# @api private
|
7
|
+
module Metrics
|
8
|
+
MUTEX = Mutex.new
|
9
|
+
|
10
|
+
def self.new(config, &block)
|
11
|
+
Collector.new(config, &block)
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.platform
|
15
|
+
@platform ||= Gem::Platform.local.os.to_sym
|
16
|
+
end
|
17
|
+
|
18
|
+
# @api private
|
19
|
+
class Collector
|
20
|
+
include Logging
|
21
|
+
|
22
|
+
TIMEOUT_INTERVAL = 5 # seconds
|
23
|
+
|
24
|
+
def initialize(config, tags: nil, &block)
|
25
|
+
@config = config
|
26
|
+
@tags = tags
|
27
|
+
@samplers = [CpuMem].map { |kls| kls.new(config) }
|
28
|
+
@callback = block
|
29
|
+
end
|
30
|
+
|
31
|
+
attr_reader :config, :samplers, :callback, :tags
|
32
|
+
|
33
|
+
# rubocop:disable Metrics/MethodLength
|
34
|
+
def start
|
35
|
+
return unless config.collect_metrics?
|
36
|
+
|
37
|
+
@timer_task = Concurrent::TimerTask.execute(
|
38
|
+
run_now: true,
|
39
|
+
execution_interval: config.metrics_interval,
|
40
|
+
timeout_interval: TIMEOUT_INTERVAL
|
41
|
+
) do
|
42
|
+
begin
|
43
|
+
collect_and_send
|
44
|
+
true
|
45
|
+
rescue StandardError => e
|
46
|
+
error 'Error while collecting metrics: %e', e.inspect
|
47
|
+
debug { e.backtrace.join("\n") }
|
48
|
+
false
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
@running = true
|
53
|
+
end
|
54
|
+
# rubocop:enable Metrics/MethodLength
|
55
|
+
|
56
|
+
def stop
|
57
|
+
@timer_task.shutdown
|
58
|
+
@running = false
|
59
|
+
end
|
60
|
+
|
61
|
+
def running?
|
62
|
+
!!@running
|
63
|
+
end
|
64
|
+
|
65
|
+
def collect_and_send
|
66
|
+
metricset = Metricset.new(tags: tags, **collect)
|
67
|
+
return if metricset.empty?
|
68
|
+
|
69
|
+
callback.call(metricset)
|
70
|
+
end
|
71
|
+
|
72
|
+
def collect
|
73
|
+
MUTEX.synchronize do
|
74
|
+
samplers.each_with_object({}) do |sampler, samples|
|
75
|
+
next unless (sample = sampler.collect)
|
76
|
+
samples.merge!(sample)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
require 'elastic_apm/metrics/cpu_mem'
|
@@ -0,0 +1,214 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ElasticAPM
|
4
|
+
module Metrics
|
5
|
+
# @api private
|
6
|
+
class CpuMem
|
7
|
+
include Logging
|
8
|
+
|
9
|
+
# @api private
|
10
|
+
class Sample
|
11
|
+
# rubocop:disable Metrics/ParameterLists
|
12
|
+
def initialize(
|
13
|
+
system_cpu_total:,
|
14
|
+
system_cpu_usage:,
|
15
|
+
system_memory_total:,
|
16
|
+
system_memory_free:,
|
17
|
+
process_cpu_usage:,
|
18
|
+
process_memory_size:,
|
19
|
+
process_memory_rss:,
|
20
|
+
page_size:
|
21
|
+
)
|
22
|
+
@system_cpu_total = system_cpu_total
|
23
|
+
@system_cpu_usage = system_cpu_usage
|
24
|
+
@system_memory_total = system_memory_total
|
25
|
+
@system_memory_free = system_memory_free
|
26
|
+
@process_cpu_usage = process_cpu_usage
|
27
|
+
@process_memory_size = process_memory_size
|
28
|
+
@process_memory_rss = process_memory_rss
|
29
|
+
@page_size = page_size
|
30
|
+
end
|
31
|
+
# rubocop:enable Metrics/ParameterLists
|
32
|
+
|
33
|
+
attr_accessor :system_cpu_total, :system_cpu_usage,
|
34
|
+
:system_memory_total, :system_memory_free, :process_cpu_usage,
|
35
|
+
:process_memory_size, :process_memory_rss, :page_size
|
36
|
+
|
37
|
+
def delta(previous)
|
38
|
+
dup.tap do |sample|
|
39
|
+
sample.system_cpu_total =
|
40
|
+
system_cpu_total - previous.system_cpu_total
|
41
|
+
sample.system_cpu_usage =
|
42
|
+
system_cpu_usage - previous.system_cpu_usage
|
43
|
+
sample.process_cpu_usage =
|
44
|
+
process_cpu_usage - previous.process_cpu_usage
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def initialize(config)
|
50
|
+
@config = config
|
51
|
+
@sampler = sampler_for_platform(Metrics.platform)
|
52
|
+
end
|
53
|
+
|
54
|
+
attr_reader :config, :sampler
|
55
|
+
|
56
|
+
def sample
|
57
|
+
@sampler.sample
|
58
|
+
end
|
59
|
+
|
60
|
+
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
61
|
+
def collect
|
62
|
+
return unless sampler
|
63
|
+
|
64
|
+
current = sample
|
65
|
+
|
66
|
+
unless @previous
|
67
|
+
@previous = current
|
68
|
+
return
|
69
|
+
end
|
70
|
+
|
71
|
+
delta = current.delta(@previous)
|
72
|
+
|
73
|
+
cpu_usage_pct = delta.system_cpu_usage.to_f / delta.system_cpu_total
|
74
|
+
cpu_process_pct = delta.process_cpu_usage.to_f / delta.system_cpu_total
|
75
|
+
|
76
|
+
@previous = current
|
77
|
+
|
78
|
+
{
|
79
|
+
'system.cpu.total.norm.pct': cpu_usage_pct,
|
80
|
+
'system.memory.actual.free': current.system_memory_free,
|
81
|
+
'system.memory.total': current.system_memory_total,
|
82
|
+
'system.process.cpu.total.norm.pct': cpu_process_pct,
|
83
|
+
'system.process.memory.size': current.process_memory_size,
|
84
|
+
'system.process.memory.rss.bytes':
|
85
|
+
current.process_memory_rss * current.page_size
|
86
|
+
}
|
87
|
+
end
|
88
|
+
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
|
89
|
+
|
90
|
+
private
|
91
|
+
|
92
|
+
def sampler_for_platform(platform)
|
93
|
+
case platform
|
94
|
+
when :linux then Linux.new
|
95
|
+
else
|
96
|
+
warn "Unsupported platform '#{platform}' - Disabling metrics"
|
97
|
+
@disabled = true
|
98
|
+
nil
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# @api private
|
103
|
+
class Linux
|
104
|
+
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
105
|
+
def sample
|
106
|
+
proc_stat = ProcStat.new.read!
|
107
|
+
proc_self_stat = ProcSelfStat.new.read!
|
108
|
+
meminfo = Meminfo.new.read!
|
109
|
+
|
110
|
+
Sample.new(
|
111
|
+
system_cpu_total: proc_stat.total,
|
112
|
+
system_cpu_usage: proc_stat.usage,
|
113
|
+
system_memory_total: meminfo.total,
|
114
|
+
system_memory_free: meminfo.available,
|
115
|
+
process_cpu_usage: proc_self_stat.total,
|
116
|
+
process_memory_size: proc_self_stat.vsize,
|
117
|
+
process_memory_rss: proc_self_stat.rss,
|
118
|
+
page_size: meminfo.page_size
|
119
|
+
)
|
120
|
+
end
|
121
|
+
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
|
122
|
+
|
123
|
+
# @api private
|
124
|
+
class ProcStat
|
125
|
+
attr_reader :total, :usage
|
126
|
+
|
127
|
+
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
128
|
+
def read!
|
129
|
+
stat =
|
130
|
+
IO.readlines('/proc/stat')
|
131
|
+
.lazy
|
132
|
+
.find { |sp| sp.start_with?('cpu ') }
|
133
|
+
.split
|
134
|
+
.map(&:to_i)[1..-1]
|
135
|
+
|
136
|
+
user, nice, system, idle, iowait, irq, softirq, steal,
|
137
|
+
_guest, _guest_nice = stat
|
138
|
+
|
139
|
+
@total =
|
140
|
+
user +
|
141
|
+
nice +
|
142
|
+
system +
|
143
|
+
idle +
|
144
|
+
iowait +
|
145
|
+
irq +
|
146
|
+
softirq +
|
147
|
+
steal
|
148
|
+
|
149
|
+
@usage = @total - (idle + iowait)
|
150
|
+
|
151
|
+
self
|
152
|
+
end
|
153
|
+
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
|
154
|
+
end
|
155
|
+
|
156
|
+
UTIME_POS = 13
|
157
|
+
STIME_POS = 14
|
158
|
+
VSIZE_POS = 22
|
159
|
+
RSS_POS = 23
|
160
|
+
|
161
|
+
# @api private
|
162
|
+
class ProcSelfStat
|
163
|
+
attr_reader :total, :vsize, :rss
|
164
|
+
|
165
|
+
def read!
|
166
|
+
stat =
|
167
|
+
IO.readlines('/proc/self/stat')
|
168
|
+
.lazy
|
169
|
+
.first
|
170
|
+
.split
|
171
|
+
.map(&:to_i)
|
172
|
+
|
173
|
+
@total = stat[UTIME_POS] + stat[STIME_POS]
|
174
|
+
@vsize = stat[VSIZE_POS]
|
175
|
+
@rss = stat[RSS_POS]
|
176
|
+
|
177
|
+
self
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
# @api private
|
182
|
+
class Meminfo
|
183
|
+
attr_reader :total, :available, :page_size
|
184
|
+
|
185
|
+
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
186
|
+
def read!
|
187
|
+
# rubocop:disable Style/RescueModifier
|
188
|
+
@page_size = `getconf PAGESIZE`.chomp.to_i rescue 4096
|
189
|
+
# rubocop:enable Style/RescueModifier
|
190
|
+
|
191
|
+
info =
|
192
|
+
IO.readlines('/proc/meminfo')
|
193
|
+
.lazy
|
194
|
+
.each_with_object({}) do |line, hsh|
|
195
|
+
if line.start_with?('MemTotal:')
|
196
|
+
hsh[:total] = line.split[1].to_i * 1024
|
197
|
+
elsif line.start_with?('MemAvailable:')
|
198
|
+
hsh[:available] = line.split[1].to_i * 1024
|
199
|
+
end
|
200
|
+
|
201
|
+
break hsh if hsh.length == 2
|
202
|
+
end
|
203
|
+
|
204
|
+
@total = info[:total]
|
205
|
+
@available = info[:available]
|
206
|
+
|
207
|
+
self
|
208
|
+
end
|
209
|
+
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ElasticAPM
|
4
|
+
# @api private
|
5
|
+
class Metricset
|
6
|
+
def initialize(timestamp: Util.micros, tags: nil, **samples)
|
7
|
+
@timestamp = timestamp
|
8
|
+
@tags = tags
|
9
|
+
@samples = samples
|
10
|
+
end
|
11
|
+
|
12
|
+
attr_accessor :timestamp
|
13
|
+
attr_reader :samples, :tags
|
14
|
+
|
15
|
+
def empty?
|
16
|
+
samples.empty?
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -43,9 +43,10 @@ module ElasticAPM
|
|
43
43
|
@span = Serializers::SpanSerializer.new(config)
|
44
44
|
@error = Serializers::ErrorSerializer.new(config)
|
45
45
|
@metadata = Serializers::MetadataSerializer.new(config)
|
46
|
+
@metricset = Serializers::MetricsetSerializer.new(config)
|
46
47
|
end
|
47
48
|
|
48
|
-
attr_reader :transaction, :span, :error, :metadata
|
49
|
+
attr_reader :transaction, :span, :error, :metadata, :metricset
|
49
50
|
|
50
51
|
# rubocop:disable Metrics/MethodLength
|
51
52
|
def serialize(resource)
|
@@ -56,6 +57,8 @@ module ElasticAPM
|
|
56
57
|
span.build(resource)
|
57
58
|
when Error
|
58
59
|
error.build(resource)
|
60
|
+
when Metricset
|
61
|
+
metricset.build(resource)
|
59
62
|
when Metadata
|
60
63
|
metadata.build(resource)
|
61
64
|
else
|
@@ -73,7 +76,8 @@ module ElasticAPM
|
|
73
76
|
end
|
74
77
|
|
75
78
|
require 'elastic_apm/transport/serializers/context_serializer'
|
79
|
+
require 'elastic_apm/transport/serializers/transaction_serializer'
|
80
|
+
require 'elastic_apm/transport/serializers/span_serializer'
|
76
81
|
require 'elastic_apm/transport/serializers/error_serializer'
|
82
|
+
require 'elastic_apm/transport/serializers/metricset_serializer'
|
77
83
|
require 'elastic_apm/transport/serializers/metadata_serializer'
|
78
|
-
require 'elastic_apm/transport/serializers/span_serializer'
|
79
|
-
require 'elastic_apm/transport/serializers/transaction_serializer'
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ElasticAPM
|
4
|
+
module Transport
|
5
|
+
module Serializers
|
6
|
+
# @api private
|
7
|
+
class MetricsetSerializer < Serializer
|
8
|
+
def build(metricset)
|
9
|
+
{
|
10
|
+
metricset: {
|
11
|
+
timestamp: metricset.timestamp.to_i,
|
12
|
+
tags: keyword_object(metricset.tags),
|
13
|
+
samples: build_samples(metricset.samples)
|
14
|
+
}
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def build_samples(samples)
|
21
|
+
samples.each_with_object({}) do |(key, value), hsh|
|
22
|
+
hsh[key] = { value: value }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/elastic_apm/util.rb
CHANGED
data/lib/elastic_apm/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: elastic-apm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mikkel Malmberg
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-01-
|
11
|
+
date: 2019-01-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|
@@ -75,6 +75,7 @@ files:
|
|
75
75
|
- docs/getting-started-rails.asciidoc
|
76
76
|
- docs/index.asciidoc
|
77
77
|
- docs/introduction.asciidoc
|
78
|
+
- docs/metrics.asciidoc
|
78
79
|
- docs/opentracing.asciidoc
|
79
80
|
- docs/supported-technologies.asciidoc
|
80
81
|
- elastic-apm.gemspec
|
@@ -103,6 +104,9 @@ files:
|
|
103
104
|
- lib/elastic_apm/metadata/process_info.rb
|
104
105
|
- lib/elastic_apm/metadata/service_info.rb
|
105
106
|
- lib/elastic_apm/metadata/system_info.rb
|
107
|
+
- lib/elastic_apm/metrics.rb
|
108
|
+
- lib/elastic_apm/metrics/cpu_mem.rb
|
109
|
+
- lib/elastic_apm/metricset.rb
|
106
110
|
- lib/elastic_apm/middleware.rb
|
107
111
|
- lib/elastic_apm/naively_hashable.rb
|
108
112
|
- lib/elastic_apm/normalizers.rb
|
@@ -146,6 +150,7 @@ files:
|
|
146
150
|
- lib/elastic_apm/transport/serializers/context_serializer.rb
|
147
151
|
- lib/elastic_apm/transport/serializers/error_serializer.rb
|
148
152
|
- lib/elastic_apm/transport/serializers/metadata_serializer.rb
|
153
|
+
- lib/elastic_apm/transport/serializers/metricset_serializer.rb
|
149
154
|
- lib/elastic_apm/transport/serializers/span_serializer.rb
|
150
155
|
- lib/elastic_apm/transport/serializers/transaction_serializer.rb
|
151
156
|
- lib/elastic_apm/transport/worker.rb
|