netuitived 0.10.1 → 1.0.1
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.
- 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
|