site24x7_apminsight 1.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.
- data/LICENSE.txt +60 -0
- data/README.rdoc +67 -0
- data/Rakefile +63 -0
- data/VERSION +1 -0
- data/conf/apminsight.conf +96 -0
- data/lib/agent/am_objectholder.rb +66 -0
- data/lib/agent/configuration/am_configuration.rb +268 -0
- data/lib/agent/logging/am_logger.rb +109 -0
- data/lib/agent/metrics/am_metricscollector.rb +30 -0
- data/lib/agent/metrics/am_metricsformatter.rb +277 -0
- data/lib/agent/metrics/am_metricsparser.rb +569 -0
- data/lib/agent/metrics/am_metricstore.rb +29 -0
- data/lib/agent/server/am_agent.rb +116 -0
- data/lib/agent/server/am_connector.rb +242 -0
- data/lib/agent/server/instrument/am_apm.rb +99 -0
- data/lib/agent/server/instrument/am_instrumenter.rb +43 -0
- data/lib/agent/server/worker/am_worker.rb +271 -0
- data/lib/agent/util/am_constants.rb +80 -0
- data/lib/agent/util/am_util.rb +130 -0
- data/lib/site24x7_apminsight.rb +5 -0
- metadata +131 -0
@@ -0,0 +1,242 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'net/https'
|
3
|
+
require 'uri'
|
4
|
+
require 'json'
|
5
|
+
require "agent/server/instrument/am_instrumenter"
|
6
|
+
|
7
|
+
module ManageEngine
|
8
|
+
class APMConnector
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
@obj = ManageEngine::APMObjectHolder.instance
|
12
|
+
@pretry =0
|
13
|
+
@gretry =0
|
14
|
+
end
|
15
|
+
|
16
|
+
def post uri,data
|
17
|
+
@pretry = @pretry +1
|
18
|
+
begin
|
19
|
+
|
20
|
+
u = url uri
|
21
|
+
#@obj.log.info "[connector] [ POST] START"
|
22
|
+
@obj.log.debug "[connector] [ POST] : \n\n#{u}\n\n#{data}\n\n"
|
23
|
+
con = connection(u)
|
24
|
+
req = Net::HTTP::Post.new(u.request_uri,initheader = {'Content-Type' =>'application/json'})
|
25
|
+
req.body=data.to_json
|
26
|
+
resp = con.request(req)
|
27
|
+
@obj.log.debug "[connector] [POST ] \n Response : #{resp} \nResponse Code : #{resp.code}\nMessage : #{resp.message}\nBody : #{resp.body}"
|
28
|
+
rdata = responseParser resp
|
29
|
+
@pretry = 0
|
30
|
+
#@obj.log.info "[connector] [ POST] END"
|
31
|
+
return rdata
|
32
|
+
rescue Exception=>e
|
33
|
+
@obj.log.logException "[connector] Exception while connecting server- Data not sent \n",e
|
34
|
+
if @pretry >=@obj.config.connection_retry
|
35
|
+
#@obj.shutdown= true
|
36
|
+
return nil
|
37
|
+
else
|
38
|
+
@obj.log.info "[connector] Exception found in Post request - Retrying - Count - #{@pretry}"
|
39
|
+
return post uri,data
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
@pretry = 0
|
44
|
+
end
|
45
|
+
|
46
|
+
def get uri
|
47
|
+
@gretry = @gretry +1
|
48
|
+
begin
|
49
|
+
u = url uri
|
50
|
+
#@obj.log.info "[connector] [ GET ] START"
|
51
|
+
@obj.log.debug "[connector] [ GET] : \n#{u}\n"
|
52
|
+
req = Net::HTTP::Get.new(u.request_uri)
|
53
|
+
resp = con.request(req)
|
54
|
+
#@obj.log.info "[connector] [ GET ] END"
|
55
|
+
rescue Exception=>e
|
56
|
+
@obj.log.logException "[connector] [ GET] Exception while connecting server - Data not sent ",e
|
57
|
+
if @pretry >=@obj.config.connection_retry
|
58
|
+
#@obj.shutdown= true
|
59
|
+
else
|
60
|
+
@obj.log.info "[connector] Exception found in Get request - Retrying - Count - #{@gretry}"
|
61
|
+
return get uri
|
62
|
+
end
|
63
|
+
end
|
64
|
+
@gretry = 0
|
65
|
+
end
|
66
|
+
|
67
|
+
def url(uri)
|
68
|
+
ru=nil
|
69
|
+
p="https"
|
70
|
+
if(!@obj.config.is_secured)
|
71
|
+
p="http"
|
72
|
+
end
|
73
|
+
if(@obj.config.license_key != nil)
|
74
|
+
if(!@obj.config.license_key.empty?)
|
75
|
+
if(@obj.config.apmhost != nil && !@obj.config.apmhost.empty?)
|
76
|
+
u = @obj.config.apmhost+uri
|
77
|
+
else
|
78
|
+
u = @obj.constants.site24x7url+uri
|
79
|
+
end
|
80
|
+
else
|
81
|
+
#empty license key - print error
|
82
|
+
@obj.log.info "license key is present, but empty"
|
83
|
+
end
|
84
|
+
else
|
85
|
+
@obj.log.info "license key is null"
|
86
|
+
u = p+"://"+@obj.config.apmhost+":#{@obj.config.apmport}/"+uri
|
87
|
+
end
|
88
|
+
begin
|
89
|
+
ru = URI.parse(u)
|
90
|
+
rescue
|
91
|
+
raise URI::InvalidURIError, "Invalid url '#{ru}'"
|
92
|
+
end
|
93
|
+
|
94
|
+
if (ru.class != URI::HTTP && ru.class != URI::HTTPS)
|
95
|
+
raise URI::InvalidURIError, "Invalid url '#{u}'"
|
96
|
+
end
|
97
|
+
ru
|
98
|
+
end
|
99
|
+
|
100
|
+
def connection(url)
|
101
|
+
|
102
|
+
if (@obj.config.proxyneeded)
|
103
|
+
@obj.log.debug "[connect] Through Proxy"
|
104
|
+
con = Net::HTTP::Proxy(@obj.config.proxy_host, @obj.config.proxy_port,@obj.config.proxy_user,@obj.config.proxy_pass).new(url.host, url.port)
|
105
|
+
else
|
106
|
+
#@obj.log.info "Proxy Not Needed #{url.host} #{url.port}"
|
107
|
+
con = Net::HTTP.new(url.host, url.port)
|
108
|
+
con.use_ssl=true
|
109
|
+
con.verify_mode=OpenSSL::SSL::VERIFY_NONE
|
110
|
+
#@obj.log.info "connection = #{con}"
|
111
|
+
end
|
112
|
+
con=getScheme(con)
|
113
|
+
con.open_timeout = @obj.constants.connection_open_timeout
|
114
|
+
con.read_timeout = @obj.constants.connection_read_timeout
|
115
|
+
con
|
116
|
+
end
|
117
|
+
|
118
|
+
def getScheme(con)
|
119
|
+
if(@obj.config.is_secured)
|
120
|
+
#@obj.log.info "[connect] Secured"
|
121
|
+
con = Net::HTTP::Proxy(@obj.config.proxy_host, @obj.config.proxy_port,@obj.config.proxy_user,@obj.config.proxy_pass).new(url.host, url.port)
|
122
|
+
con.use_ssl=true
|
123
|
+
con.verify_mode=OpenSSL::SSL::VERIFY_NONE
|
124
|
+
end
|
125
|
+
con
|
126
|
+
end
|
127
|
+
|
128
|
+
def responseParser resp
|
129
|
+
if resp == Net::HTTPSuccess || Net::HTTPOK
|
130
|
+
rawData = resp.body
|
131
|
+
if rawData.length>=2
|
132
|
+
rBody = JSON.parse(rawData)
|
133
|
+
result = rBody["result"]
|
134
|
+
data = rBody["data"]
|
135
|
+
if !@obj.util.getBooleanValue result
|
136
|
+
if data!=nil
|
137
|
+
if data.has_key?("exception")
|
138
|
+
raise Exception.new("Exception from server - "+data["exception"])
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|
143
|
+
if data!=nil
|
144
|
+
if data.has_key?(@obj.constants.response_code)
|
145
|
+
srCode = data[@obj.constants.response_code]
|
146
|
+
response_action srCode
|
147
|
+
end
|
148
|
+
if data.has_key?(@obj.constants.custom_config_info)
|
149
|
+
config_info = data[@obj.constants.custom_config_info]
|
150
|
+
update_config config_info
|
151
|
+
end
|
152
|
+
end
|
153
|
+
return data
|
154
|
+
end
|
155
|
+
return rawData
|
156
|
+
else
|
157
|
+
raise Exception.new("Http Connection Response Error #{resp.to_s}")
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
|
162
|
+
|
163
|
+
def response_action rCode
|
164
|
+
case rCode
|
165
|
+
when @obj.constants.licence_expired then
|
166
|
+
@obj.log.info "License Expired. Going to shutdown"
|
167
|
+
raise Exception.new("License Expired. Going to shutdown")
|
168
|
+
when @obj.constants.licence_exceeds then
|
169
|
+
@obj.log.info "License Exceeds. Going to shutdown"
|
170
|
+
raise Exception.new("License Exceeds. Going to shutdown")
|
171
|
+
when @obj.constants.delete_agent then
|
172
|
+
@obj.log.info "Action from Server - Delete the Agent. Going to shutdown and remove the Agent"
|
173
|
+
deleteAgent
|
174
|
+
raise Exception.new("Action from Server - Delete the Agent. Going to shutdown and remove the Agent")
|
175
|
+
when @obj.constants.unmanage_agent then
|
176
|
+
@obj.log.info "Action from Server - Unmanage the Agent. Going to Stop the DC - Disabling the Agent"
|
177
|
+
unManage
|
178
|
+
when @obj.constants.manage_agent then
|
179
|
+
@obj.log.info "Action from Server - Manage the Agent. Going to Sart the DC - Enabling the Agent"
|
180
|
+
manage
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
def update_config configInfo
|
185
|
+
existingConfigInfo = @obj.config.getAgentConfigData
|
186
|
+
sendUpdate = "false"
|
187
|
+
existingConfigInfo.each do|key,value|
|
188
|
+
if key != "last.modified.time"
|
189
|
+
newValue = configInfo[key]
|
190
|
+
if key == "sql.capture.enabled" || key == "transaction.trace.enabled" || key == "transaction.trace.sql.parametrize"
|
191
|
+
if newValue
|
192
|
+
newValue = 1
|
193
|
+
else
|
194
|
+
newValue = 0
|
195
|
+
end
|
196
|
+
end
|
197
|
+
if value != newValue
|
198
|
+
sendUpdate = "true"
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
if sendUpdate == "true"
|
203
|
+
@obj.log.info "Action from Server - Agent configuration updated from UI. Going to update the same in apminsight.conf file"
|
204
|
+
@obj.log.info "config info = #{configInfo}"
|
205
|
+
@obj.config.update_config configInfo
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
def unManage
|
210
|
+
@obj.instrumenter.doUnSubscribe
|
211
|
+
@obj.instrumenter =nil
|
212
|
+
@obj.instrumenter = ManageEngine::APMInstrumenter.new
|
213
|
+
uManage = Hash.new
|
214
|
+
uManage["agent.id"]=@obj.config.instance_id
|
215
|
+
uManage["agent.enabled"]=false
|
216
|
+
@obj.config.updateAgentInfoFile uManage
|
217
|
+
end
|
218
|
+
|
219
|
+
def manage
|
220
|
+
@obj.instrumenter.doSubscribe
|
221
|
+
uManage = Hash.new
|
222
|
+
uManage["agent.id"]=@obj.config.instance_id
|
223
|
+
uManage["agent.enabled"]=true
|
224
|
+
@obj.config.updateAgentInfoFile uManage
|
225
|
+
end
|
226
|
+
|
227
|
+
def deleteAgent
|
228
|
+
@obj.instrumenter.doUnSubscribe
|
229
|
+
@obj.instrumenter =nil
|
230
|
+
uManage = Hash.new
|
231
|
+
uManage["agent.id"]=@obj.config.instance_id
|
232
|
+
uManage["agent.enabled"]=false
|
233
|
+
@obj.config.updateAgentInfoFile uManage
|
234
|
+
begin
|
235
|
+
File.delete(@obj.constants.agent_conf)
|
236
|
+
rescue Exceptione=>e
|
237
|
+
@obj.log.logException "#{e.message}",e
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
end#c
|
242
|
+
end#m
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'agent/am_objectholder'
|
2
|
+
@obj = ManageEngine::APMObjectHolder.instance
|
3
|
+
class Class
|
4
|
+
alias old_new new
|
5
|
+
def new(*args, &block)
|
6
|
+
result =nil;
|
7
|
+
begin
|
8
|
+
if(block==nil || block=="")
|
9
|
+
result = old_new(*args)
|
10
|
+
elsif
|
11
|
+
result = old_new(*args,&block)
|
12
|
+
end
|
13
|
+
rescue Excetion=>exe
|
14
|
+
raise exe
|
15
|
+
result = self
|
16
|
+
end
|
17
|
+
me_apm_injector(self,result)
|
18
|
+
|
19
|
+
return result
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def me_apm_injector(s,result)
|
24
|
+
begin
|
25
|
+
if(ManageEngine::APMObjectHolder.instance.config.include_packages.index(s.name)!=nil)
|
26
|
+
ms =s.instance_methods(false)
|
27
|
+
cms = s.methods(false)
|
28
|
+
begin
|
29
|
+
ms.each do |m|
|
30
|
+
if( m.to_s.index("APMTEST"))
|
31
|
+
return;
|
32
|
+
end
|
33
|
+
end
|
34
|
+
cms.each do |m|
|
35
|
+
if( m.to_s.index("APMTEST"))
|
36
|
+
return;
|
37
|
+
end
|
38
|
+
end
|
39
|
+
rescue Exception=>e
|
40
|
+
return;
|
41
|
+
end
|
42
|
+
ManageEngine::APMObjectHolder.instance.log.debug "Injection Method : #{ms} "
|
43
|
+
ManageEngine::APMObjectHolder.instance.log.debug "Injection Class Method : #{cms} "
|
44
|
+
ms.each do |m|
|
45
|
+
mn = m.to_s
|
46
|
+
#ManageEngine::APMObjectHolder.instance.log.info "ManageEngine Monitor Method : #{s.name} # #{m.to_s}"
|
47
|
+
omn = "APMTEST"+mn+"APMTEST"
|
48
|
+
s.class_eval %{
|
49
|
+
alias_method :#{omn}, :#{mn}
|
50
|
+
def #{mn} *args, &block
|
51
|
+
begin
|
52
|
+
ActiveSupport::Notifications.instrument("apm.methodstart", {:method=>"#{mn}",:args=>args})
|
53
|
+
res = #{omn} *args, &block
|
54
|
+
ActiveSupport::Notifications.instrument("apm.methodend", {:method=>"#{mn}",:args=>args})
|
55
|
+
return res
|
56
|
+
rescue Exception => exe
|
57
|
+
puts "error in calling method"
|
58
|
+
raise exe
|
59
|
+
ensure
|
60
|
+
end
|
61
|
+
end
|
62
|
+
}
|
63
|
+
end#do
|
64
|
+
default_methods = Array.new
|
65
|
+
default_methods.push("_helpers");
|
66
|
+
default_methods.push("middleware_stack");
|
67
|
+
default_methods.push("helpers_path");
|
68
|
+
default_methods.push("_wrapper_options");
|
69
|
+
cms.each do |m|
|
70
|
+
if(default_methods.index(m.to_s)==nil)
|
71
|
+
mn = m.to_s
|
72
|
+
#ManageEngine::APMObjectHolder.instance.log.debug "ManageEngine Monitor Singleton Method : #{s.name} ---> #{m.to_s}"
|
73
|
+
omn = "APMTEST"+mn+"APMTEST"
|
74
|
+
s.instance_eval %{
|
75
|
+
class << self
|
76
|
+
alias_method :#{omn}, :#{mn}
|
77
|
+
end
|
78
|
+
def self.#{mn} *args, &block
|
79
|
+
begin
|
80
|
+
ActiveSupport::Notifications.instrument("apm.methodstart", {:method=>"#{mn}",:args=>args})
|
81
|
+
res = #{omn} *args, &block
|
82
|
+
ActiveSupport::Notifications.instrument("apm.methodend", {:method=>"#{mn}",:args=>args})
|
83
|
+
return res
|
84
|
+
rescue Exception=>exe
|
85
|
+
puts "Instrument : error in calling class method"
|
86
|
+
raise exe
|
87
|
+
ensure
|
88
|
+
end
|
89
|
+
end
|
90
|
+
}
|
91
|
+
end
|
92
|
+
end#do
|
93
|
+
end#if
|
94
|
+
rescue Exception=>e
|
95
|
+
puts "Exception in instrument : #{e}"
|
96
|
+
ensure
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'agent/am_objectholder'
|
2
|
+
require 'socket'
|
3
|
+
module ManageEngine
|
4
|
+
class APMInstrumenter
|
5
|
+
@t =nil;
|
6
|
+
def initialize
|
7
|
+
@obj=ManageEngine::APMObjectHolder.instance
|
8
|
+
end
|
9
|
+
|
10
|
+
def doSubscribe
|
11
|
+
@obj=ManageEngine::APMObjectHolder.instance
|
12
|
+
@obj.log.debug "[ instrumenter ] [ Subscriber for Agent ]"
|
13
|
+
@subscriber = ActiveSupport::Notifications.subscribe do |name, start, finish, id, payload|
|
14
|
+
if(ManageEngine::APMObjectHolder.instance.config.agent_enabled)
|
15
|
+
rt = (finish-start).to_i
|
16
|
+
ManageEngine::APMWorker.getInstance.start
|
17
|
+
ManageEngine::APMObjectHolder.instance.log.debug "[ Notifications for Agent ] #{Thread.current} #{id} #{name} - #{rt} - #{payload}"
|
18
|
+
trace= caller;
|
19
|
+
id = "#{Thread.current}"
|
20
|
+
stats = Hash.new
|
21
|
+
stats["name"] = name;
|
22
|
+
stats["start"] = start.to_f * 1000;
|
23
|
+
stats["end"] = finish.to_f * 1000;
|
24
|
+
stats["id"] = id;
|
25
|
+
stats["payload"] = payload;
|
26
|
+
if (name=="sql.active_record" && (finish-start)>=(ManageEngine::APMObjectHolder.instance.config.sql_trace_t * 1000 ).to_i)
|
27
|
+
stats["trace"] = trace;
|
28
|
+
end
|
29
|
+
stats["ctime"] =ManageEngine::APMObjectHolder.instance.util.currenttimemillis;
|
30
|
+
ManageEngine::APMObjectHolder.instance.collector.updateTransaction(id,stats);
|
31
|
+
else
|
32
|
+
ActiveSupport::Notifications.unsubscribe @subscriber
|
33
|
+
@obj.log.info "[ instrumenter ] [ RETURNING NO METRICS] "
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def doUnSubscribe
|
39
|
+
ActiveSupport::Notifications.unsubscribe @subscriber
|
40
|
+
end
|
41
|
+
|
42
|
+
end #class
|
43
|
+
end#module
|
@@ -0,0 +1,271 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'thread'
|
3
|
+
|
4
|
+
module ManageEngine
|
5
|
+
class APMWorker
|
6
|
+
@work =nil;
|
7
|
+
@status = 'not_init'
|
8
|
+
@id = 0
|
9
|
+
attr_accessor :id
|
10
|
+
def initialize
|
11
|
+
@status = "initialized"
|
12
|
+
@id = Process.pid
|
13
|
+
end
|
14
|
+
|
15
|
+
def start
|
16
|
+
@obj = ManageEngine::APMObjectHolder.instance
|
17
|
+
|
18
|
+
if @status=="working"
|
19
|
+
@obj.log.debug "woker thread already started"
|
20
|
+
elsif @status == "initialized"
|
21
|
+
@obj.log.info "start worker thread for - #{Process.pid} :: #{@status} "
|
22
|
+
#@obj.log.info "Starting APMWorker Thread #{Process.pid} "
|
23
|
+
@apm = Thread.new do
|
24
|
+
@status = 'working'
|
25
|
+
while !@obj.shutdown do
|
26
|
+
checkforagentstatus
|
27
|
+
updateConfig
|
28
|
+
dc
|
29
|
+
sleep (@obj.config.connect_interval).to_i
|
30
|
+
end#w
|
31
|
+
@status= "end"
|
32
|
+
@obj.log.debug "Worker thread ends"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.getInstance
|
38
|
+
if(@work==nil || @work.id!=Process.pid)
|
39
|
+
@work = ManageEngine::APMWorker.new
|
40
|
+
end
|
41
|
+
return @work
|
42
|
+
end
|
43
|
+
|
44
|
+
def updateConfig
|
45
|
+
if(@obj.config.lastupdatedtime!=File.mtime(@obj.constants.apm_conf).to_i)
|
46
|
+
@obj.log.info "Configuration File Changed... So Updating Configuration."
|
47
|
+
agent_config_data = @obj.config.getAgentConfigData
|
48
|
+
@obj.config.lastupdatedtime=File.mtime(@obj.constants.apm_conf).to_i
|
49
|
+
@obj.config.configureFile
|
50
|
+
@obj.config.assignConfig
|
51
|
+
new_agent_config_data = @obj.config.getAgentConfigData
|
52
|
+
sendUpdate = "false"
|
53
|
+
agent_config_data.each do|key,value|
|
54
|
+
if key != "last.modified.time"
|
55
|
+
newValue = new_agent_config_data[key]
|
56
|
+
if value != newValue
|
57
|
+
sendUpdate = "true"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
if sendUpdate == "true"
|
62
|
+
@obj.log.info "sending update to server #{new_agent_config_data}"
|
63
|
+
data1 = Hash.new
|
64
|
+
data1["custom_config_info"]=new_agent_config_data
|
65
|
+
resp = @obj.connector.post @obj.constants.connect_config_update_uri+@obj.config.instance_id,data1
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def checkforagentstatus
|
71
|
+
prevState = @obj.config.agent_enabled
|
72
|
+
@obj.config.checkAgentInfo
|
73
|
+
if !@obj.config.agent_enabled
|
74
|
+
@obj.log.info "Agent in Disabled State."
|
75
|
+
if prevState
|
76
|
+
@obj.log.info "Agent in Disabled State. Going to unsubscribe"
|
77
|
+
@obj.instrumenter.doUnSubscribe
|
78
|
+
end
|
79
|
+
else
|
80
|
+
if !prevState
|
81
|
+
@obj.log.info "Agent in Active State."
|
82
|
+
@obj.instrumenter.doSubscribe
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def stop
|
88
|
+
dc
|
89
|
+
@obj.shutdown = true;
|
90
|
+
end
|
91
|
+
|
92
|
+
def dc
|
93
|
+
begin
|
94
|
+
@obj.log.debug "[dc] collecting..."
|
95
|
+
now = @obj.util.currenttimemillis
|
96
|
+
result = Array.new
|
97
|
+
result.push(@obj.last_dispatch_time)
|
98
|
+
result.push(now)
|
99
|
+
data = Array.new
|
100
|
+
trd= nil;
|
101
|
+
@last_dispatch_time = now
|
102
|
+
if @obj.config.agent_enabled
|
103
|
+
d = @obj.parser.parse @obj.store.metrics_dup
|
104
|
+
if(d!=nil && d.has_key?("trace-data"))
|
105
|
+
trd = d.delete("trace-data");
|
106
|
+
#@obj.log.info "[dc] [TRACE] : #{d}"
|
107
|
+
end
|
108
|
+
#@obj.log.info "[dc] Data - #{d}"
|
109
|
+
if(d.length>0)
|
110
|
+
data =@obj.formatter.format d
|
111
|
+
#@obj.log.debug "[dc] Formatted Data - #{data}"
|
112
|
+
end
|
113
|
+
@obj.store.remove @obj.formatter.keysToRemove
|
114
|
+
end #if
|
115
|
+
fd = Array.new
|
116
|
+
fd.push(data)
|
117
|
+
if(trd!=nil)
|
118
|
+
fd.push(trd)
|
119
|
+
end
|
120
|
+
@obj.log.debug "[dc] data to store : #{fd}"
|
121
|
+
send_save fd
|
122
|
+
@obj.log.debug "[dc] collecting ends"
|
123
|
+
rescue Exception=>e
|
124
|
+
@obj.log.logException "[dc] Exception during data Collection. #{e.message}",e
|
125
|
+
@obj.shutdown=true
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def senddata d
|
130
|
+
# @obj.log.info("Send data --- #{d}")
|
131
|
+
result = Array.new
|
132
|
+
result.push( (File.mtime(@obj.constants.agent_lock).to_f*1000).to_i)
|
133
|
+
now = @obj.util.currenttimemillis
|
134
|
+
result.push(now)
|
135
|
+
write @obj.constants.agent_lock ,"#{Process.pid}"
|
136
|
+
data = read @obj.constants.agent_store
|
137
|
+
data.push(d);
|
138
|
+
tdata = Array.new;
|
139
|
+
trdata = Array.new;
|
140
|
+
data.each do |val|
|
141
|
+
case val.size
|
142
|
+
when 1
|
143
|
+
tdata.concat(val[0])
|
144
|
+
when 2
|
145
|
+
tdata.concat(val[0])
|
146
|
+
trdata.concat(val[1])
|
147
|
+
end
|
148
|
+
end
|
149
|
+
result.push(merge(tdata))
|
150
|
+
resp = @obj.connector.post @obj.constants.connect_data_uri+@obj.config.instance_id,result
|
151
|
+
if trdata.size>0
|
152
|
+
result[2]=trdata;
|
153
|
+
resp = @obj.connector.post @obj.constants.connect_trace_uri+@obj.config.instance_id,result
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
def save fd
|
158
|
+
begin
|
159
|
+
data = fd.to_json;
|
160
|
+
write @obj.constants.agent_store,data
|
161
|
+
rescue Exception=>e
|
162
|
+
@obj.log.logException "[dc] Exception during save. #{e.message}",e
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def send_save data
|
167
|
+
begin
|
168
|
+
if FileTest.exist?(@obj.constants.agent_lock)
|
169
|
+
if Time.now.to_i - File.mtime(@obj.constants.agent_lock).to_i >= (@obj.config.connect_interval).to_i
|
170
|
+
@obj.log.debug "worker send signal"
|
171
|
+
senddata data
|
172
|
+
else
|
173
|
+
@obj.log.info "worker save signal"
|
174
|
+
save data
|
175
|
+
end
|
176
|
+
else
|
177
|
+
@obj.log.info "worker save signals"
|
178
|
+
save data
|
179
|
+
write @obj.constants.agent_lock,"#{Process.pid}"
|
180
|
+
end
|
181
|
+
rescue Exception=>e
|
182
|
+
@obj.log.logException "Exception in decision making send or save #{e.message}",e
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
def read p
|
187
|
+
data = Array.new
|
188
|
+
File.open( p, "r+" ) { |f|
|
189
|
+
f.flock(File::LOCK_EX)
|
190
|
+
begin
|
191
|
+
f.each_line do |line|
|
192
|
+
data.push(JSON.parse(line))
|
193
|
+
end
|
194
|
+
f.truncate 0
|
195
|
+
rescue Exception=>e
|
196
|
+
@obj.log.logException "Exception while reading data #{e}",e
|
197
|
+
ensure
|
198
|
+
f.flock(File::LOCK_UN)
|
199
|
+
end
|
200
|
+
}
|
201
|
+
data
|
202
|
+
end
|
203
|
+
|
204
|
+
|
205
|
+
def write (p, data )
|
206
|
+
File.open( p, "a+" ) { |f|
|
207
|
+
f.flock(File::LOCK_EX)
|
208
|
+
begin
|
209
|
+
f.write "#{data}\n"
|
210
|
+
rescue Exception=>e
|
211
|
+
@obj.log.logException "Exception while writing data #{e.message}",e
|
212
|
+
ensure
|
213
|
+
f.flock(File::LOCK_UN)
|
214
|
+
end
|
215
|
+
}
|
216
|
+
end
|
217
|
+
|
218
|
+
def merge data
|
219
|
+
# @obj.log.info "BEFORE MERGE : #{data}"
|
220
|
+
tdata =Hash.new ;
|
221
|
+
data.each do |sd|
|
222
|
+
name= sd[0]["ns"] + sd[0]["name"];
|
223
|
+
if tdata.has_key?(name)
|
224
|
+
if (sd[0]["name"]=="apdex")
|
225
|
+
tdata[name][1] = mapdx(tdata[name][1],sd[1])
|
226
|
+
else
|
227
|
+
tdata[name][1] = mapdb(tdata[name][1],sd[1])
|
228
|
+
end
|
229
|
+
else
|
230
|
+
tdata[name]=sd;
|
231
|
+
end
|
232
|
+
end
|
233
|
+
#@obj.log.info "MERGED DATA : #{tdata}"
|
234
|
+
res = Array.new;
|
235
|
+
tdata.each do|key,value|
|
236
|
+
res.push(value);
|
237
|
+
end
|
238
|
+
res
|
239
|
+
end
|
240
|
+
|
241
|
+
|
242
|
+
def mapdx res,dat
|
243
|
+
res[0] = res[0]+dat[0];
|
244
|
+
if dat[1]<res[1]
|
245
|
+
res[1]=dat[1]
|
246
|
+
end
|
247
|
+
if dat[2]>res[2]
|
248
|
+
res[2]=dat[2]
|
249
|
+
end
|
250
|
+
res[3] = res[3]+dat[3]
|
251
|
+
res[5] = res[5]+dat[5]
|
252
|
+
res[6] = res[6]+dat[6]
|
253
|
+
res[7] = res[7]+dat[7]
|
254
|
+
res[4] = (res[5].to_f + (res[6].to_f/2).to_f).to_f/res[3].to_f
|
255
|
+
res
|
256
|
+
end
|
257
|
+
|
258
|
+
def mapdb res,dat
|
259
|
+
res[0] = res[0]+dat[0];
|
260
|
+
if dat[1]<res[1]
|
261
|
+
res[1]=dat[1]
|
262
|
+
end
|
263
|
+
if dat[2]>res[2]
|
264
|
+
res[2]=dat[2]
|
265
|
+
end
|
266
|
+
res[3] = res[3]+dat[3]
|
267
|
+
res
|
268
|
+
end
|
269
|
+
|
270
|
+
end#c
|
271
|
+
end#m
|