apminsight 0.0.3

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.
@@ -0,0 +1,29 @@
1
+ require 'agent/am_objectholder'
2
+
3
+ module ManageEngine
4
+ class APMMetricsStore
5
+ attr_accessor :metrics
6
+ def initialize
7
+ @metrics = Hash.new
8
+ end
9
+
10
+ def remove keys
11
+ if keys!=nil
12
+ keys.each {|key| @metrics.delete("#{key}")}
13
+ end
14
+ end
15
+
16
+ def metrics_dup
17
+ @metrics.dup
18
+ end
19
+
20
+ def removeData key, strt_indx,end_indx
21
+ if @metrics.has_key?(key)
22
+ val = @metrics[key]
23
+ val = val.drop(end_indx)
24
+ @metrics[key]=val
25
+ end
26
+ end
27
+
28
+ end
29
+ end
@@ -0,0 +1,108 @@
1
+ require "agent/am_objectholder"
2
+ require "agent/server/worker/am_worker"
3
+
4
+ require 'socket'
5
+
6
+ module ManageEngine
7
+ class APMAgent
8
+ def initialize
9
+ @obj = ManageEngine::APMObjectHolder.instance
10
+ @obj.log.debug "Agent Initialization - START"
11
+ doConnect
12
+
13
+ if !@obj.shutdown && @obj.agent_initialized
14
+ @obj.log.info "Agent Initialization - DONE"
15
+ @obj.instrumenter.doSubscribe
16
+ doDispatcherActions
17
+ doCollect
18
+ puts "ManageEngine APM Ruby Agent Started"
19
+ else
20
+ @obj.log.info "Agent Initialization Failed - Going to shutdown"
21
+ @obj.instrumenter.doSubscribe
22
+ @obj.shutdownagent
23
+ end
24
+
25
+
26
+ end
27
+
28
+ def doConnect
29
+ begin
30
+ if @obj.shutdown
31
+ @obj.log.info "[ Problem in Agent Startup ]"
32
+ else
33
+ agentInfo = @obj.config.getAgentInfo
34
+ resp = nil
35
+ if @obj.config.alreadyconnected
36
+ @obj.log.debug "[doConnect] Already Connected - Make Contact - Instance id = #{@obj.config.instance_id}"
37
+ resp = startConnect "?instance_id="+@obj.config.instance_id,agentInfo
38
+ else
39
+ @obj.log.debug "[doConnect] Going to connect - New "
40
+ resp = startConnect "",agentInfo
41
+ if resp.has_key?("instance-info")
42
+ aData = resp["instance-info"]
43
+ aData["agent.id"]=aData.delete("instanceid")
44
+ aData["agent.enabled"]=true
45
+ @obj.config.updateAgentInfoFile(aData)
46
+ @obj.log.debug "[doConnect] Connected - InstanceID : #{@obj.config.instance_id}"
47
+ else
48
+ @obj.log.info "[doConnect] [ Problem in connecting server] [ Going to shutdown ]"
49
+ @obj.shutdown=true
50
+ end
51
+ end
52
+
53
+ if resp==nil
54
+ @obj.log.info "[doConnect] [ Error in Response while connecting Server . [ Going to shutdown ]"
55
+ @obj.shutdown= true
56
+ end
57
+
58
+ if(!@obj.shutdown)
59
+ @obj.agent_initialized=true
60
+ end
61
+ end
62
+ rescue Exception=>e
63
+ @obj.shutdown = true
64
+ @obj.log.logException "[doConnect] Exception while connecting server. [ Going to shutdown ] ",e
65
+ end
66
+ end
67
+
68
+
69
+ def doCollect
70
+ @obj.log.info "[doCollect] Starts - Wait time : #{@obj.config.connect_interval} seconds "
71
+ begin
72
+ ManageEngine::APMWorker.getInstance.start
73
+ rescue Exception=>e
74
+ @obj.log.logException "[doCollect] Exception during worker startup #{e.message}",e
75
+ @obj.shutdown=true
76
+ end
77
+ end
78
+
79
+
80
+ def startConnect uri,data
81
+ resp = @obj.connector.post @obj.constants.connect_uri+uri,data
82
+ end
83
+
84
+ def doDispatcherActions
85
+ case @obj.config.app_dispatcher
86
+ when 'passenger'
87
+ #starting a new process
88
+ PhusionPassenger.on_event(:starting_worker_process) do |forked|
89
+ if forked
90
+ @obj.log.info "starting_worker_process : Process ID :#{Process.pid} : Creating new apm worker"
91
+ doCollect
92
+ else
93
+ doCollect
94
+ @obj.log.info "starting_worker_process : Conservative Process ID :#{Process.pid} - No new worker"
95
+ end
96
+ end
97
+ # shutting down a process.
98
+ PhusionPassenger.on_event(:stopping_worker_process) do
99
+ ManageEngine::APMWorker.getInstance.stop
100
+ @obj.log.info "stopping_worker_process :Process ID :#{Process.pid} ----> #$$ "
101
+ end
102
+ else#case
103
+
104
+ end#case
105
+ end
106
+ end#c
107
+ end#m
108
+
@@ -0,0 +1,195 @@
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="http"
70
+ if(@obj.config.is_secured)
71
+ p="https"
72
+ end
73
+ u = p+"://"+@obj.config.apmhost+":#{@obj.config.apmport}/"+uri
74
+ begin
75
+ ru = URI.parse(u)
76
+ rescue
77
+ raise URI::InvalidURIError, "Invalid url '#{ru}'"
78
+ end
79
+
80
+ if (ru.class != URI::HTTP && ru.class != URI::HTTPS)
81
+ raise URI::InvalidURIError, "Invalid url '#{u}'"
82
+ end
83
+ ru
84
+ end
85
+
86
+ def connection(url)
87
+
88
+ if (@obj.config.proxyneeded)
89
+ @obj.log.debug "[connect] Through Proxy"
90
+ 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)
91
+ else
92
+ #@obj.log.info "Proxy Not Needed"
93
+ con = Net::HTTP.new(url.host, url.port)
94
+ end
95
+ con=getScheme(con)
96
+ con.open_timeout = @obj.constants.connection_open_timeout
97
+ con.read_timeout = @obj.constants.connection_read_timeout
98
+ con
99
+ end
100
+
101
+ def getScheme(con)
102
+ if(@obj.config.is_secured)
103
+ #@obj.log.info "[connect] Secured"
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
+ con.use_ssl=true
106
+ con.verify_mode=OpenSSL::SSL::VERIFY_NONE
107
+ end
108
+ con
109
+ end
110
+
111
+ def responseParser resp
112
+ if resp == Net::HTTPSuccess || Net::HTTPOK
113
+ rawData = resp.body
114
+ if rawData.length>=2
115
+ rBody = JSON.parse(rawData)
116
+ result = rBody["result"]
117
+ data = rBody["data"]
118
+ if !@obj.util.getBooleanValue result
119
+ if data!=nil
120
+ if data.has_key?("exception")
121
+ raise Exception.new("Exception from server - "+data["exception"])
122
+ end
123
+ end
124
+
125
+ end
126
+ if data!=nil && data.has_key?(@obj.constants.response_code)
127
+
128
+ srCode = data[@obj.constants.response_code]
129
+ response_action srCode
130
+ end
131
+ return data
132
+ end
133
+ return rawData
134
+ else
135
+ raise Exception.new("Http Connection Response Error #{resp.to_s}")
136
+ end
137
+ end
138
+
139
+
140
+
141
+ def response_action rCode
142
+ case rCode
143
+ when @obj.constants.licence_expired then
144
+ @obj.log.info "License Expired. Going to shutdown"
145
+ raise Exception.new("License Expired. Going to shutdown")
146
+ when @obj.constants.licence_exceeds then
147
+ @obj.log.info "License Exceeds. Going to shutdown"
148
+ raise Exception.new("License Exceeds. Going to shutdown")
149
+ when @obj.constants.delete_agent then
150
+ @obj.log.info "Action from Server - Delete the Agent. Going to shutdown and remove the Agent"
151
+ deleteAgent
152
+ raise Exception.new("Action from Server - Delete the Agent. Going to shutdown and remove the Agent")
153
+ when @obj.constants.unmanage_agent then
154
+ @obj.log.info "Action from Server - Unmanage the Agent. Going to Stop the DC - Disabling the Agent"
155
+ unManage
156
+ when @obj.constants.manage_agent then
157
+ @obj.log.info "Action from Server - Manage the Agent. Going to Sart the DC - Enabling the Agent"
158
+ manage
159
+ end
160
+ end
161
+
162
+ def unManage
163
+ @obj.instrumenter.doUnSubscribe
164
+ @obj.instrumenter =nil
165
+ @obj.instrumenter = ManageEngine::APMInstrumenter.new
166
+ uManage = Hash.new
167
+ uManage["agent.id"]=@obj.config.instance_id
168
+ uManage["agent.enabled"]=false
169
+ @obj.config.updateAgentInfoFile uManage
170
+ end
171
+
172
+ def manage
173
+ @obj.instrumenter.doSubscribe
174
+ uManage = Hash.new
175
+ uManage["agent.id"]=@obj.config.instance_id
176
+ uManage["agent.enabled"]=true
177
+ @obj.config.updateAgentInfoFile uManage
178
+ end
179
+
180
+ def deleteAgent
181
+ @obj.instrumenter.doUnSubscribe
182
+ @obj.instrumenter =nil
183
+ uManage = Hash.new
184
+ uManage["agent.id"]=@obj.config.instance_id
185
+ uManage["agent.enabled"]=false
186
+ @obj.config.updateAgentInfoFile uManage
187
+ begin
188
+ File.delete(@obj.constants.agent_conf)
189
+ rescue Exceptione=>e
190
+ @obj.log.logException "#{e.message}",e
191
+ end
192
+ end
193
+
194
+ end#c
195
+ 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