netuitived 0.10.1 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +21 -10
- data/bin/netuitived +12 -53
- data/config/agent.yml +3 -0
- data/lib/netuitived.rb +137 -12
- data/lib/netuitived/api_emissary.rb +51 -0
- data/lib/netuitived/config_manager.rb +91 -0
- data/lib/netuitived/event_handler.rb +40 -0
- data/lib/netuitived/ingest_attribute.rb +12 -0
- data/lib/netuitived/ingest_element.rb +26 -0
- data/lib/netuitived/ingest_event.rb +25 -0
- data/lib/netuitived/ingest_metric.rb +21 -0
- data/lib/netuitived/ingest_sample.rb +27 -0
- data/lib/netuitived/ingest_tag.rb +13 -0
- data/lib/netuitived/metric_aggregator.rb +142 -0
- data/lib/netuitived/netuitive_logger.rb +49 -0
- data/lib/netuitived/netuitived_server.rb +58 -0
- data/lib/netuitived/scheduler.rb +17 -0
- metadata +15 -13
- data/lib/netuitive/api_emissary.rb +0 -43
- data/lib/netuitive/ingest_attribute.rb +0 -10
- data/lib/netuitive/ingest_element.rb +0 -17
- data/lib/netuitive/ingest_metric.rb +0 -15
- data/lib/netuitive/ingest_sample.rb +0 -18
- data/lib/netuitive/ingest_tag.rb +0 -10
- data/lib/netuitive/metric_aggregator.rb +0 -146
- data/lib/netuitive/netuitived_config_manager.rb +0 -92
- data/lib/netuitive/netuitived_logger.rb +0 -24
- data/lib/netuitive/netuitived_server.rb +0 -53
- data/lib/netuitive/scheduler.rb +0 -14
@@ -0,0 +1,26 @@
|
|
1
|
+
module NetuitiveD
|
2
|
+
class IngestElement
|
3
|
+
attr_accessor :id, :name, :type, :location, :metrics, :samples, :tags, :attributes
|
4
|
+
def initialize(id, name, type, location, metrics, samples, tags, attributes)
|
5
|
+
@id = id
|
6
|
+
@name = name
|
7
|
+
@type = type
|
8
|
+
@location = location
|
9
|
+
@metrics = metrics
|
10
|
+
@samples = samples
|
11
|
+
@tags = tags
|
12
|
+
@attributes = attributes
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_json(_options = {})
|
16
|
+
{ 'id' => @id,
|
17
|
+
'name' => @name,
|
18
|
+
'type' => @type,
|
19
|
+
'location' => @location,
|
20
|
+
'metrics' => @metrics,
|
21
|
+
'samples' => @samples,
|
22
|
+
'tags' => @tags,
|
23
|
+
'attributes' => @attributes }.to_json.tr('\\"', '"')
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module NetuitiveD
|
2
|
+
class IngestEvent
|
3
|
+
attr_accessor :source, :timestamp, :title, :type, :tags, :data
|
4
|
+
def initialize(elementId, message, timestamp, title, level, source, type, tags)
|
5
|
+
@source = source
|
6
|
+
@timestamp = timestamp
|
7
|
+
@title = title
|
8
|
+
@type = type
|
9
|
+
@tags = tags
|
10
|
+
@data = { 'elementId' => elementId,
|
11
|
+
'level' => level,
|
12
|
+
'message' => message }
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_json(_options = {})
|
16
|
+
millis = @timestamp.to_f * 1000
|
17
|
+
{ 'source' => @source,
|
18
|
+
'timestamp' => millis.round,
|
19
|
+
'title' => @title,
|
20
|
+
'type' => @type,
|
21
|
+
'tags' => @tags,
|
22
|
+
'data' => @data }.to_json.tr('\\"', '"')
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module NetuitiveD
|
2
|
+
class IngestMetric
|
3
|
+
attr_accessor :id, :name, :unit, :type, :tags, :aggregate
|
4
|
+
def initialize(id, name, unit, type, tags, aggregate)
|
5
|
+
@id = id
|
6
|
+
@name = name
|
7
|
+
@unit = unit
|
8
|
+
@type = type
|
9
|
+
@tags = tags
|
10
|
+
@aggregate = aggregate
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_json(_options = {})
|
14
|
+
{ 'id' => @id,
|
15
|
+
'name' => @name,
|
16
|
+
'unit' => @unit,
|
17
|
+
'type' => @type,
|
18
|
+
'tags' => @tags }.to_json
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module NetuitiveD
|
2
|
+
class IngestSample
|
3
|
+
attr_accessor :metricId, :timestamp, :val, :min, :max, :avg, :sum, :cnt
|
4
|
+
def initialize(metricId, timestamp, val, min, max, avg, sum, cnt)
|
5
|
+
@metricId = metricId
|
6
|
+
@timestamp = timestamp
|
7
|
+
@val = val
|
8
|
+
@min = min
|
9
|
+
@max = max
|
10
|
+
@avg = avg
|
11
|
+
@sum = sum
|
12
|
+
@cnt = cnt
|
13
|
+
end
|
14
|
+
|
15
|
+
def to_json(_options = {})
|
16
|
+
millis = @timestamp.to_f * 1000
|
17
|
+
{ 'metricId' => @metricId,
|
18
|
+
'timestamp' => millis.round,
|
19
|
+
'val' => @val,
|
20
|
+
'min' => @min,
|
21
|
+
'max' => @max,
|
22
|
+
'avg' => @avg,
|
23
|
+
'sum' => @sum,
|
24
|
+
'cnt' => @cnt }.to_json
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,142 @@
|
|
1
|
+
module NetuitiveD
|
2
|
+
class MetricAggregator
|
3
|
+
attr_reader :samples
|
4
|
+
attr_reader :metrics
|
5
|
+
attr_reader :aggregatedSamples
|
6
|
+
|
7
|
+
def initialize(apiEmissary)
|
8
|
+
@metrics = []
|
9
|
+
@samples = []
|
10
|
+
@aggregatedSamples = {}
|
11
|
+
@metricMutex = Mutex.new
|
12
|
+
@apiEmissary = apiEmissary
|
13
|
+
end
|
14
|
+
|
15
|
+
def sendMetrics
|
16
|
+
elementString = nil
|
17
|
+
addSample('netuitive.collection_interval', NetuitiveD::ConfigManager.interval)
|
18
|
+
@metricMutex.synchronize do
|
19
|
+
NetuitiveD::NetuitiveLogger.log.debug "self: #{object_id}"
|
20
|
+
NetuitiveD::NetuitiveLogger.log.debug "Thread: #{Thread.current.object_id}"
|
21
|
+
NetuitiveD::NetuitiveLogger.log.debug "metrics id: #{@metrics.object_id}"
|
22
|
+
NetuitiveD::NetuitiveLogger.log.debug "samples id: #{@samples.object_id}"
|
23
|
+
NetuitiveD::NetuitiveLogger.log.debug "aggregatedSamples id: #{@aggregatedSamples.object_id}"
|
24
|
+
NetuitiveD::NetuitiveLogger.log.debug "metrics before send: #{@metrics.count}"
|
25
|
+
NetuitiveD::NetuitiveLogger.log.debug "samples before send: #{@aggregatedSamples.count + @samples.count}"
|
26
|
+
|
27
|
+
if @metrics.empty?
|
28
|
+
NetuitiveD::NetuitiveLogger.log.info 'no netuitive metrics to report'
|
29
|
+
return
|
30
|
+
end
|
31
|
+
aggregatedSamplesArray = @aggregatedSamples.values
|
32
|
+
aggregatedSamplesArray.each do |sample|
|
33
|
+
sample.timestamp = Time.new
|
34
|
+
end
|
35
|
+
element = NetuitiveD::IngestElement.new(NetuitiveD::ConfigManager.elementName, NetuitiveD::ConfigManager.elementName, 'Ruby', nil, @metrics, @samples + aggregatedSamplesArray, nil, nil)
|
36
|
+
elements = [element]
|
37
|
+
elementString = elements.to_json
|
38
|
+
clearMetrics
|
39
|
+
end
|
40
|
+
@apiEmissary.sendElements(elementString)
|
41
|
+
end
|
42
|
+
|
43
|
+
def addSample(metricId, val)
|
44
|
+
addSampleWithType(metricId, val, 'GAUGE')
|
45
|
+
end
|
46
|
+
|
47
|
+
def addCounterSample(metricId, val)
|
48
|
+
addSampleWithType(metricId, val, 'COUNTER')
|
49
|
+
end
|
50
|
+
|
51
|
+
def addSampleWithType(metricId, val, type)
|
52
|
+
@metricMutex.synchronize do
|
53
|
+
NetuitiveD::NetuitiveLogger.log.debug 'start addSample method'
|
54
|
+
NetuitiveD::NetuitiveLogger.log.debug "Thread: #{Thread.current.object_id}"
|
55
|
+
NetuitiveD::NetuitiveLogger.log.debug "self: #{object_id}"
|
56
|
+
NetuitiveD::NetuitiveLogger.log.debug "metrics id: #{@metrics.object_id}"
|
57
|
+
NetuitiveD::NetuitiveLogger.log.debug "samples id: #{@samples.object_id}"
|
58
|
+
NetuitiveD::NetuitiveLogger.log.debug "aggregatedSamples id: #{@aggregatedSamples.object_id}"
|
59
|
+
NetuitiveD::NetuitiveLogger.log.debug "metrics before add: #{@metrics.count}"
|
60
|
+
NetuitiveD::NetuitiveLogger.log.debug "samples before add: #{@aggregatedSamples.count + @samples.count}"
|
61
|
+
if metricId.nil?
|
62
|
+
NetuitiveD::NetuitiveLogger.log.info 'null metricId for addSample'
|
63
|
+
return false
|
64
|
+
end
|
65
|
+
if val.nil?
|
66
|
+
NetuitiveD::NetuitiveLogger.log.info "null value for addSample for metricId #{metricId}"
|
67
|
+
return false
|
68
|
+
end
|
69
|
+
unless metricExists metricId
|
70
|
+
NetuitiveD::NetuitiveLogger.log.info "adding new metric: #{metricId}"
|
71
|
+
@metrics.push(NetuitiveD::IngestMetric.new(metricId, metricId, nil, type, nil, false))
|
72
|
+
end
|
73
|
+
@samples.push(NetuitiveD::IngestSample.new(metricId, Time.new, val, nil, nil, nil, nil, nil))
|
74
|
+
NetuitiveD::NetuitiveLogger.log.info "netuitive sample added #{metricId} val: #{val}"
|
75
|
+
NetuitiveD::NetuitiveLogger.log.debug "metrics after add: #{@metrics.count}"
|
76
|
+
NetuitiveD::NetuitiveLogger.log.debug "samples after add: #{@aggregatedSamples.count + @samples.count}"
|
77
|
+
NetuitiveD::NetuitiveLogger.log.debug 'end addSample method'
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def metricExists(metricId)
|
82
|
+
@metrics.each do |metric|
|
83
|
+
return true if metric.id == metricId
|
84
|
+
end
|
85
|
+
false
|
86
|
+
end
|
87
|
+
|
88
|
+
def aggregateMetric(metricId, val)
|
89
|
+
aggregateMetricWithType(metricId, val, 'GAUGE')
|
90
|
+
end
|
91
|
+
|
92
|
+
def aggregateCounterMetric(metricId, val)
|
93
|
+
aggregateMetricWithType(metricId, val, 'COUNTER')
|
94
|
+
end
|
95
|
+
|
96
|
+
def aggregateMetricWithType(metricId, val, type)
|
97
|
+
@metricMutex.synchronize do
|
98
|
+
NetuitiveD::NetuitiveLogger.log.debug 'start addSample method'
|
99
|
+
NetuitiveD::NetuitiveLogger.log.debug "Thread: #{Thread.current.object_id}"
|
100
|
+
NetuitiveD::NetuitiveLogger.log.debug "self: #{object_id}"
|
101
|
+
NetuitiveD::NetuitiveLogger.log.debug "metrics id: #{@metrics.object_id}"
|
102
|
+
NetuitiveD::NetuitiveLogger.log.debug "samples id: #{@samples.object_id}"
|
103
|
+
NetuitiveD::NetuitiveLogger.log.debug "aggregatedSamples id: #{@aggregatedSamples.object_id}"
|
104
|
+
NetuitiveD::NetuitiveLogger.log.debug "metrics before aggregate: #{@metrics.count}"
|
105
|
+
NetuitiveD::NetuitiveLogger.log.debug "samples before aggregate: #{@aggregatedSamples.count + @samples.count}"
|
106
|
+
if metricId.nil?
|
107
|
+
NetuitiveD::NetuitiveLogger.log.info 'null metricId for aggregateMetric'
|
108
|
+
return false
|
109
|
+
end
|
110
|
+
if val.nil?
|
111
|
+
NetuitiveD::NetuitiveLogger.log.info "null value for aggregateMetric for metricId #{metricId}"
|
112
|
+
return false
|
113
|
+
end
|
114
|
+
if !metricExists metricId
|
115
|
+
NetuitiveD::NetuitiveLogger.log.info "adding new metric: #{metricId}"
|
116
|
+
@metrics.push(NetuitiveD::IngestMetric.new(metricId, metricId, nil, type, nil, false))
|
117
|
+
@aggregatedSamples[metricId.to_s] = NetuitiveD::IngestSample.new(metricId, Time.new, val, nil, nil, nil, nil, nil)
|
118
|
+
else
|
119
|
+
if @aggregatedSamples[metricId.to_s].nil?
|
120
|
+
NetuitiveD::NetuitiveLogger.log.info "cannot aggregate metric #{metricId} that already has samples for this interval"
|
121
|
+
return false
|
122
|
+
end
|
123
|
+
previousVal = @aggregatedSamples[metricId.to_s].val
|
124
|
+
@aggregatedSamples[metricId.to_s].val += val
|
125
|
+
NetuitiveD::NetuitiveLogger.log.info "netuitive sample aggregated #{metricId} old val: #{previousVal} new val: #{@aggregatedSamples[metricId.to_s].val}"
|
126
|
+
end
|
127
|
+
NetuitiveD::NetuitiveLogger.log.debug "metrics after aggregate: #{@metrics.count}"
|
128
|
+
NetuitiveD::NetuitiveLogger.log.debug "samples after aggregate: #{@aggregatedSamples.count + @samples.count}"
|
129
|
+
NetuitiveD::NetuitiveLogger.log.debug 'end addSample method'
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def clearMetrics
|
134
|
+
NetuitiveD::NetuitiveLogger.log.debug 'start clearMetrics method'
|
135
|
+
@metrics = []
|
136
|
+
@samples = []
|
137
|
+
@aggregatedSamples = {}
|
138
|
+
NetuitiveD::NetuitiveLogger.log.info 'netuitive metrics cleared'
|
139
|
+
NetuitiveD::NetuitiveLogger.log.debug 'end clearMetrics method'
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module NetuitiveD
|
2
|
+
class CheaterLogger
|
3
|
+
attr_accessor :level
|
4
|
+
def debug(message)
|
5
|
+
end
|
6
|
+
|
7
|
+
def error(message)
|
8
|
+
end
|
9
|
+
|
10
|
+
def info(message)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class NetuitiveLogger
|
15
|
+
class << self
|
16
|
+
attr_accessor :log
|
17
|
+
def setup
|
18
|
+
file = NetuitiveD::ConfigManager.property('logLocation', 'NETUITIVED_LOG_LOCATION', "#{File.expand_path('../../..', __FILE__)}/log/netuitive.log")
|
19
|
+
age = NetuitiveD::ConfigManager.property('logAge', 'NETUITIVED_LOG_AGE', 'daily')
|
20
|
+
age = NetuitiveD::NetuitiveLogger.format_age(age)
|
21
|
+
size = NetuitiveD::ConfigManager.property('logSize', 'NETUITIVED_LOG_SIZE', 1_000_000)
|
22
|
+
size = NetuitiveD::NetuitiveLogger.format_size(size)
|
23
|
+
NetuitiveD::NetuitiveLogger.log = Logger.new(file, age, size)
|
24
|
+
rescue => e
|
25
|
+
puts 'netuitive unable to open log file'
|
26
|
+
puts "error: #{e.message}"
|
27
|
+
NetuitiveD::NetuitiveLogger.log = NetuitiveD::CheaterLogger.new
|
28
|
+
end
|
29
|
+
|
30
|
+
def format_age(age)
|
31
|
+
return 'daily' if age.nil?
|
32
|
+
begin
|
33
|
+
Integer(age)
|
34
|
+
rescue
|
35
|
+
age
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def format_size(size)
|
40
|
+
return 1_000_000 if size.nil?
|
41
|
+
begin
|
42
|
+
Integer(size)
|
43
|
+
rescue
|
44
|
+
size
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module NetuitiveD
|
2
|
+
class NetuitivedServer
|
3
|
+
def initialize(metricAggregator, eventHandler)
|
4
|
+
@metricAggregator = metricAggregator
|
5
|
+
@eventHandler = eventHandler
|
6
|
+
end
|
7
|
+
|
8
|
+
def sendMetrics
|
9
|
+
@metricAggregator.sendMetrics
|
10
|
+
end
|
11
|
+
|
12
|
+
def addSample(metricId, val)
|
13
|
+
@metricAggregator.addSample(metricId, val)
|
14
|
+
end
|
15
|
+
|
16
|
+
def addCounterSample(metricId, val)
|
17
|
+
@metricAggregator.addCounterSample(metricId, val)
|
18
|
+
end
|
19
|
+
|
20
|
+
def aggregateMetric(metricId, val)
|
21
|
+
@metricAggregator.aggregateMetric(metricId, val)
|
22
|
+
end
|
23
|
+
|
24
|
+
def aggregateCounterMetric(metricId, val)
|
25
|
+
@metricAggregator.aggregateCounterMetric(metricId, val)
|
26
|
+
end
|
27
|
+
|
28
|
+
def clearMetrics
|
29
|
+
@metricAggregator.clearMetrics
|
30
|
+
end
|
31
|
+
|
32
|
+
def interval
|
33
|
+
NetuitiveD::ConfigManager.interval
|
34
|
+
end
|
35
|
+
|
36
|
+
def event(message, timestamp = Time.new, title = 'Ruby Event', level = 'Info', source = 'Ruby Agent', type = 'INFO', tags = nil)
|
37
|
+
@eventHandler.handleEvent(message, timestamp, title, level, source, type, tags)
|
38
|
+
end
|
39
|
+
|
40
|
+
def exceptionEvent(exception, klass = nil, tags = nil)
|
41
|
+
@eventHandler.handleExceptionEvent(exception, klass, tags)
|
42
|
+
end
|
43
|
+
|
44
|
+
def stopServer
|
45
|
+
Thread.new do
|
46
|
+
exitProcess
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def exitProcess
|
51
|
+
sleep(1)
|
52
|
+
NetuitiveD::NetuitiveLogger.log.info 'stopping netuitived'
|
53
|
+
Process.exit!(true)
|
54
|
+
end
|
55
|
+
|
56
|
+
private :exitProcess
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module NetuitiveD
|
2
|
+
class Scheduler
|
3
|
+
def self.startSchedule
|
4
|
+
Thread.new do
|
5
|
+
loop do
|
6
|
+
NetuitiveD::NetuitiveLogger.log.debug "scheduler sleeping for: #{NetuitiveD::ConfigManager.interval}"
|
7
|
+
sleep(NetuitiveD::ConfigManager.interval)
|
8
|
+
Thread.new do
|
9
|
+
NetuitiveD::NetuitiveLogger.log.debug 'scheduler sending metrics'
|
10
|
+
Netuitived.front_object.sendMetrics
|
11
|
+
NetuitiveD::NetuitiveLogger.log.debug 'scheduler sent metrics'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: netuitived
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2016-
|
12
|
+
date: 2016-10-17 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: Collects metrics over a certain interval and then sends them to Netuitive
|
15
15
|
email: jking@netuitive.com
|
@@ -19,17 +19,19 @@ extensions: []
|
|
19
19
|
extra_rdoc_files: []
|
20
20
|
files:
|
21
21
|
- lib/netuitived.rb
|
22
|
-
- lib/
|
23
|
-
- lib/
|
24
|
-
- lib/
|
25
|
-
- lib/
|
26
|
-
- lib/
|
27
|
-
- lib/
|
28
|
-
- lib/
|
29
|
-
- lib/
|
30
|
-
- lib/
|
31
|
-
- lib/
|
32
|
-
- lib/
|
22
|
+
- lib/netuitived/ingest_tag.rb
|
23
|
+
- lib/netuitived/ingest_element.rb
|
24
|
+
- lib/netuitived/ingest_attribute.rb
|
25
|
+
- lib/netuitived/metric_aggregator.rb
|
26
|
+
- lib/netuitived/netuitive_logger.rb
|
27
|
+
- lib/netuitived/ingest_event.rb
|
28
|
+
- lib/netuitived/scheduler.rb
|
29
|
+
- lib/netuitived/api_emissary.rb
|
30
|
+
- lib/netuitived/netuitived_server.rb
|
31
|
+
- lib/netuitived/config_manager.rb
|
32
|
+
- lib/netuitived/ingest_sample.rb
|
33
|
+
- lib/netuitived/ingest_metric.rb
|
34
|
+
- lib/netuitived/event_handler.rb
|
33
35
|
- config/agent.yml
|
34
36
|
- ./LICENSE
|
35
37
|
- log/netuitive.log
|