site24x7_apminsight 1.5.3 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- This License Agreement details the policy for license of ManageEngine APM Insight Ruby Agent ("Licensed Software")
1
+ This License Agreement details the policy for license of Site24x7 APM Insight Ruby Agent ("Licensed Software")
2
2
  Please read the following license carefully, before either (i) downloading the Licensed Software from an authorized website, or (ii) installing the Licensed Software. You acknowledge that you have read this License Agreement, have understood it, and agree to be bound by its terms. If you do not agree to the terms and conditions of this Agreement, do not download or install the Licensed Software.
3
3
 
4
4
  1. LICENSE GRANT
data/README.rdoc CHANGED
@@ -1,5 +1,5 @@
1
1
  APM Insight Ruby Agent
2
- Applications Manager's Ruby agent gives you end-to-end web-transaction awareness enabling you to isolate performance issues and resolve them quickly.Applications Manager requires a monitoring agent (ruby gem) to be deployed in your application server to monitor Ruby application performance. Download the latest Ruby Agent(apminsight.gem) and deploy it in your application server. The agent collects application performance metrics and sends it to the central Applications Manager server at fixed intervals i.e. every 60 seconds.
2
+ Site24x7 APM Insight Ruby agent gives you end-to-end web-transaction awareness enabling you to isolate performance issues and resolve them quickly. Site24x7 APM Insight requires a monitoring agent (ruby gem) to be deployed in your application server to monitor Ruby application performance. Download the latest Ruby Agent(site24x7_apminsight.gem) and deploy it in your application server. The agent collects application performance metrics and sends it to the central Site24x7 server at fixed intervals i.e. every 60 seconds. You can view them at https://site24x7.com in your accounts page.
3
3
 
4
4
  Installing APM Insight Agent
5
5
 
@@ -7,13 +7,13 @@ Installing APM Insight Agent
7
7
 
8
8
  * Install from RubyGems by using the following command in the system where Ruby is installed :
9
9
 
10
- gem install apminsight
10
+ gem install site24x7_apminsight
11
11
 
12
12
  OR
13
13
 
14
- * Download the apminsight.gem file directly from our website or the RubyGems website and run the command
14
+ * Download the site24x7_apminsight.gem file from your accounts page in https://site24x7.com (after sign in) or the RubyGems website and run the command
15
15
 
16
- gem install apminsight.gem
16
+ gem install site24x7_apminsight.gem
17
17
 
18
18
  Configuration
19
19
 
@@ -21,30 +21,28 @@ Configuration
21
21
 
22
22
  For each of your applications, add the following line to the application gemfile:
23
23
 
24
- gem 'apminsight'
24
+ gem 'site24x7_apminsight'
25
25
 
26
26
  OR
27
27
 
28
28
  For each of your applications, add the following line to the application initializer block:
29
29
 
30
- require 'apminsight'
30
+ require 'site24x7_apminsight'
31
31
 
32
- A copy of the configuration file apminsight.conf will be available in the <Gem Installed folder> /apminsight/conf/. Configure the class name in the configuration file(include.packages), so that all the methods in that class can be instrumented and details will be reported in tracedata.
32
+ A copy of the configuration file apminsight.conf will be available in the <Gem Installed folder> /site24x7_apminsight/conf/. Configure the class name in the configuration file(include.packages), so that all the methods in that class can be instrumented and details will be reported in tracedata.
33
33
 
34
34
 
35
35
  The following configuration options are mandatory and should be provided for the agent to be initialized:
36
36
 
37
- application.name - The application's name to be displayed in Applications Manager.
37
+ application.name - The application's name to be displayed in Site24x7 server.
38
38
 
39
- apm.host - The host where Applications Manager is running.
40
-
41
- apm.port - The HTTP port of Applications Manager.
39
+ license.key - The license api key from your account page after sign in (https://site24x7.com)
42
40
 
43
41
  behind.proxy - The proxy network under which the agent is installed
44
42
 
45
43
  agent.server.port - The HTTP listening port of the Application Server.
46
44
 
47
- More configuration options of APM Insight Ruby Agent can be found here.
45
+ More configuration options of APM Insight Ruby Agent can be found here. https://www.site24x7.com/help/apm/apm-insight-configuration.html
48
46
 
49
47
  Supported Environments :
50
48
 
@@ -54,16 +52,16 @@ Supported Environments :
54
52
 
55
53
  References
56
54
 
57
- * Download link for Applications Manager
58
-
59
- http://www.manageengine.com/products/applications_manager/
55
+ * Create an apminsight account in Site24x7 server (https://www.site24x7.com)
60
56
 
61
- * Download link for apminsight
57
+ * Download link for site24x7_apminsight gem
62
58
 
63
- http://www.manageengine.com/products/applications_manager/
64
- http://rubygems.org/gems/apminsight
59
+ From your account page after valid sign in
60
+ or
61
+ http://rubygems.org/gems/site24x7_apminsight
65
62
 
66
63
  * Help Documentation for apminsight
67
64
 
68
- http://www.manageengine.com/products/applications_manager/help/APMInsight/installing-transaction-agent.html
69
-
65
+ https://www.site24x7.com/help/apm/ruby-agent.html
66
+ https://support.site24x7.com/portal/helpcenter/site24x7/apm-insight/ruby-monitoring
67
+
data/Rakefile CHANGED
@@ -14,13 +14,13 @@ require 'rake'
14
14
  require 'jeweler'
15
15
  Jeweler::Tasks.new do |gem|
16
16
  # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
- gem.name = "apminsight"
18
- gem.homepage = "http://www.manageengine.com/products/applications_manager/ruby-webtransaction-monitoring.html"
17
+ gem.name = "site24x7_apminsight"
18
+ gem.homepage = "https://www.site24x7.com/help/apm/ruby-agent.html"
19
19
  gem.license = "MIT"
20
20
  gem.summary = %Q{Application Performace Monitor}
21
21
  gem.description = %Q{Application Performace Monitor : Monitor the web tranasactions}
22
22
  gem.email = "apm-insight@zohocorp.com"
23
- gem.authors = ["Sabarinathan P"]
23
+ gem.authors = ["Rajalakshmi Ezhilan"]
24
24
  gem.files=Dir.glob('lib/**/*.*')
25
25
  # dependencies defined in Gemfile
26
26
  end
@@ -48,7 +48,7 @@ Rake::RDocTask.new do |rdoc|
48
48
  version = File.exist?('VERSION') ? File.read('VERSION') : ""
49
49
 
50
50
  rdoc.rdoc_dir = 'rdoc'
51
- rdoc.title = "apminsight #{version}"
51
+ rdoc.title = "site24x7_apminsight #{version}"
52
52
  rdoc.rdoc_files.include('README*')
53
53
  rdoc.rdoc_files.include('lib/**/*.*')
54
54
  rdoc.rdoc_files.include('lib/agent/**/*.*')
@@ -0,0 +1,79 @@
1
+ require 'agent/handler/custom_api_handler'
2
+
3
+ module APMInsight
4
+ module API
5
+ module CustomTracker
6
+
7
+ def self.included clazz
8
+ clazz.extend CustomMethodTracker
9
+ end
10
+
11
+ module CustomMethodTracker
12
+ # @api public
13
+ def track_method(method_name)
14
+
15
+ # Check whether the method exists
16
+ return unless method_defined?(method_name) || private_method_defined?(method_name)
17
+
18
+ # Check whether the method is already instrumented
19
+ return if is_instrumented?(method_name)
20
+
21
+ # Injecting code into the class
22
+ class_eval(get_instrumentation_code(method_name), __FILE__, __LINE__)
23
+
24
+ # Setting alias to invoke agent methods
25
+ alias_method "original_#{method_name}", "#{method_name}"
26
+ alias_method "#{method_name}", "apminsight_#{method_name}"
27
+
28
+ # TODO: set visibility
29
+ # visibility = instance_method_visibility(self, method_name)
30
+ # send visibility, method_name
31
+ # send visibility, "apminsight_#{method_name}"
32
+ end
33
+
34
+
35
+ def is_instrumented?(method_name)
36
+ method_name = "apminsight_#{method_name}"
37
+ return method_defined?(method_name)
38
+ end
39
+
40
+ # TODO: Capture exception, attach tracker
41
+ # TODO: Create agent handler and call respective methods like in java agent
42
+ def get_instrumentation_code(method_name)
43
+ "def apminsight_#{method_name}(*args, &block)
44
+ tracker = ::APMInsight::API::CustomAPIHandler.invokeTracker \"\#{self.class.name}.#{method_name}\"
45
+ begin
46
+ original_#{method_name}(*args, &block)
47
+ rescue Exception=>e
48
+ if tracker != nil
49
+ tracker.setError e
50
+ end
51
+ raise e
52
+ ensure
53
+ ::APMInsight::API::CustomAPIHandler.exitTracker tracker
54
+ end
55
+ end"
56
+ end
57
+
58
+ # def instance_method_visibility(klass, method_name)
59
+ # if klass.private_instance_methods.map{|s|s.to_sym}.include? method_name.to_sym
60
+ # :private
61
+ # elsif klass.protected_instance_methods.map{|s|s.to_sym}.include? method_name.to_sym
62
+ # :protected
63
+ # else
64
+ # :public
65
+ # end
66
+ # end
67
+ end #CustomMethodTracker
68
+
69
+ def self.trackException(exception)
70
+ return unless exception != nil
71
+
72
+ # Check for active transaction
73
+ # Associate exception to current transaction
74
+ ::APMInsight::API::CustomAPIHandler.track_exception(exception)
75
+ end
76
+
77
+ end #CustomTracker
78
+ end #API
79
+ end
@@ -1,13 +1,13 @@
1
1
  require 'rubygems'
2
2
  require 'json'
3
3
  require 'socket'
4
- #require 'rails'
4
+ require 'net/http'
5
5
  require 'agent/am_objectholder'
6
6
  require 'version'
7
7
 
8
8
  module ManageEngine
9
9
  class APMConfig
10
- attr_reader :agenthost,:agentport,:instance_id,:alreadyconnected,:apmhost,:apmport,:license_key,:site24x7, :site24x7url
10
+ attr_reader :agenthost,:agentport,:instance_id,:alreadyconnected,:apmhost,:apmport,:license_key,:site24x7, :site24x7url, :hostType
11
11
  attr_reader :appname,:proxyneeded, :apdex_t, :trans_trace, :trans_trace_t, :sql_capture, :sql_capture_params, :sql_trace_t,:proxy_user,:proxy_pass, :metric_overflow_t, :trace_overflow_t, :dbmetric_overflow_t
12
12
  attr_reader :proxy_host,:proxy_port ,:is_secured, :logs_dir ,:connection_retry,:agent_enabled,:connect_interval,:db_operations,:txn_skip_listen, :url_merge_pattern
13
13
  attr_accessor :app_db,:app_dispatcher,:lastupdatedtime
@@ -28,12 +28,14 @@ module ManageEngine
28
28
  end
29
29
  @db_operations =["select","insert","update","delete"]
30
30
  urlMergePattern
31
+ @hostType = getHostType
31
32
  @obj.log.info "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"
32
33
  @obj.log.info "APP HOME #{File.absolute_path(".")} "
33
34
  @obj.log.info "APP HOME #{Dir.pwd} "
34
35
  @obj.log.info "Agent Version : #{ManageEngine::APMInsight::VERSION}"
35
36
  @obj.log.info "Configuration : "
36
37
  @obj.log.info "Hostname : #{@agenthost}"
38
+ @obj.log.info "Host Type: #{@hostType}"
37
39
  @obj.log.info "Agent Already Connected : #{@alreadyconnected}"
38
40
  @obj.log.info "Agent Enabled : #{@agent_enabled}"
39
41
  @obj.log.info "Allowed DB Operations : #{@db_operations}"
@@ -210,10 +212,37 @@ module ManageEngine
210
212
  end
211
213
  end
212
214
 
215
+ def getHostType
216
+ begin
217
+ # Check for AWS environment
218
+ response = Net::HTTP.get_response(URI('http://169.254.169.254/latest/meta-data/'))
219
+ if (response.kind_of? Net::HTTPOK)
220
+ @hostType = "AWS"
221
+ return @hostType
222
+ end
223
+ rescue Exception => e
224
+ end
225
+
226
+ begin
227
+ #Check for Azure environment
228
+ response = Net::HTTP.get_response(URI('http://169.254.169.254/metadata/v1/maintenance'))
229
+ if (response.kind_of? Net::HTTPOK)
230
+ @hostType = "AZURE"
231
+ return @hostType
232
+ end
233
+ rescue Exception => e
234
+ end
235
+
236
+ @hostType = nil
237
+ end
238
+
213
239
  def getAgentInfo
214
240
  data = Hash.new
215
241
  agentdata = Hash.new
216
242
  agentdata = {"application.type"=>"RUBY","application.name"=>@appname,"hostname"=>@agenthost,"port"=>@agentport,"agent.version"=>ManageEngine::APMInsight::MAJOR_VERSION}
243
+ if (@hostType != nil)
244
+ agentdata["host.type"]=@hostType
245
+ end
217
246
  data["agent_info"]=agentdata
218
247
  data["environment"]=getEnvData
219
248
  data["custom_config_info"]=getAgentConfigData
@@ -0,0 +1,40 @@
1
+ require 'agent/handler/sequence_book'
2
+
3
+ module APMInsight
4
+ module API
5
+ class CustomAPIHandler
6
+
7
+ ## Create tracker for custom instrumented methods and send them to tracker handler
8
+ def self.invokeTracker name
9
+ begin
10
+ # @obj = ManageEngine::APMObjectHolder.instance
11
+
12
+ if Thread.current[:apminsight] != nil
13
+ tracker = ManageEngine::Tracker::DefaultTracker.new(name)
14
+ tracker = ManageEngine::Agent::TrackerHandler.invokeTracker(tracker)
15
+ return tracker
16
+ end
17
+
18
+ return nil
19
+ rescue Exception=>e
20
+ return nil
21
+ end
22
+ end
23
+
24
+ def self.exitTracker tracker
25
+ if tracker != nil
26
+ tracker.finish
27
+ ManageEngine::Agent::TrackerHandler.exitTracker(tracker)
28
+ end
29
+ end
30
+
31
+ def self.track_exception exception
32
+ seqBook = Thread.current[:apminsight]
33
+ if seqBook != nil
34
+ seqBook.addExceptionInfo exception
35
+ end
36
+ end
37
+
38
+ end #class CustomAPIhandler
39
+ end #module API
40
+ end
@@ -0,0 +1,115 @@
1
+ require 'agent/metrics/exception_record'
2
+
3
+ module APMInsight
4
+ module Agent
5
+ class SequenceBook
6
+ attr_reader :openTracker, :closedTracker, :rootTracker, :trackerCount, :exceptionBag, :listenFlag
7
+
8
+ def initialize
9
+ @rootTracker = createDummyTracker()
10
+ @closedTracker = @rootTracker
11
+ @openTracker = nil
12
+
13
+ @trackerCount = 0
14
+ @listenFlag = -1
15
+ # @exceptionBag = Array.new
16
+ end
17
+
18
+ def attachTracker tracker
19
+ if tracker == nil
20
+ return nil
21
+ end
22
+
23
+ # If RootTracker is not set, check type and set
24
+ if @rootTracker == @closedTracker
25
+ if !tracker.is_a?(ManageEngine::Tracker::RootTracker)
26
+ closeSequence()
27
+ return nil
28
+ end
29
+ @rootTracker = tracker
30
+
31
+ updateListenFlag()
32
+ end
33
+
34
+
35
+ # Attach tracker as Sibling or Child and set nominee
36
+ if @closedTracker != nil
37
+ tracker.sibling = @closedTracker
38
+ @closedTracker.sibling = tracker # Nominee - if dropped/corrupted, defaults to this tracker
39
+ @openTracker = tracker
40
+ @closedTracker = nil
41
+ else
42
+ if tracker.equal?(@openTracker)
43
+ return nil
44
+ end
45
+
46
+ @openTracker.child = tracker
47
+ tracker.sibling = @openTracker
48
+ @openTracker = tracker
49
+ end
50
+
51
+ checkAndArrestSequence()
52
+
53
+ return tracker
54
+ end
55
+
56
+ def closeTracker tracker
57
+ @closedTracker = tracker
58
+ tracker.sibling = nil
59
+ @openTracker = nil
60
+
61
+ # Marks end of transaction
62
+ if @rootTracker == tracker
63
+ if @listenFlag < 1 || (@listenFlag >= 1 && @trackerCount > 1)
64
+
65
+ sequenceBag = Hash.new
66
+ sequenceBag["roottracker"] = @rootTracker
67
+ sequenceBag["exceptions"] = @exceptionBag
68
+
69
+ ManageEngine::APMObjectHolder.instance.collector.updateTransaction(@rootTracker.url, sequenceBag)
70
+ end
71
+ closeSequence()
72
+ end
73
+ end
74
+
75
+ def closeSequence
76
+ @rootTracker = nil
77
+ @openTracker = @closedTracker = nil
78
+ @trackerCount = 0
79
+ Thread.current[:apminsight] = nil
80
+ end
81
+
82
+ def addExceptionInfo(exception)
83
+ begin
84
+ if @exceptionBag == nil
85
+ @exceptionBag = Set.new
86
+ end
87
+ exceptionRecord = ::APMInsight::Errors::ExceptionRecord.new(exception)
88
+ @exceptionBag.add(exceptionRecord)
89
+ rescue Exception=>e
90
+ end
91
+ end
92
+
93
+ def updateListenFlag
94
+ if !ManageEngine::APMObjectHolder.instance.txn_util.listen?(@rootTracker.url())
95
+ @listenFlag = 1
96
+ end
97
+
98
+ ## Check for sampling factor & for bg txn chk if enabled
99
+ end
100
+
101
+ def checkAndArrestSequence
102
+ if ++@trackerCount == 1000
103
+ @listenFlag = 1
104
+ end
105
+
106
+ ## Can check for timeout
107
+ end
108
+
109
+ def createDummyTracker
110
+ return ManageEngine::Tracker::DefaultTracker.new("dummy")
111
+ end
112
+
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,56 @@
1
+ require 'agent/handler/sequence_book'
2
+
3
+ module ManageEngine
4
+ module Agent
5
+ class TrackerHandler
6
+
7
+ def self.invokeTracker tracker
8
+ begin
9
+ @obj = ManageEngine::APMObjectHolder.instance
10
+
11
+ if !@obj.config.agent_enabled || tracker == nil
12
+ return nil
13
+ end
14
+
15
+ seqBook = Thread.current[:apminsight]
16
+ if seqBook != nil
17
+ if seqBook.listenFlag == 1
18
+ return nil
19
+ end
20
+ else
21
+ seqBook = ::APMInsight::Agent::SequenceBook.new
22
+ Thread.current[:apminsight] = seqBook
23
+ end
24
+
25
+ tracker = seqBook.attachTracker(tracker)
26
+
27
+ return tracker
28
+ rescue Exception=>ex
29
+ # Logging to be done here, Not sure whether its safe to do
30
+ if (@obj != nil)
31
+ @obj.log.logException "[TrackerHandler] Exception occurred at invoketracker.", ex
32
+ end
33
+ return nil
34
+ end
35
+ end
36
+
37
+
38
+ # Closes tracker properly and set everything ready to process next tracker
39
+ # If roottracker closes, sequence book is cleaned and data are push to store
40
+ def self.exitTracker tracker
41
+ begin
42
+ if tracker != nil
43
+ seqBook = Thread.current[:apminsight]
44
+ seqBook.closeTracker tracker
45
+ end
46
+ rescue Exception=>ex
47
+ if (@obj != nil)
48
+ @obj.log.logException "[TrackerHandler] Exception occurred at exittracker.", ex
49
+ end
50
+ end
51
+ end
52
+
53
+ end # Class TrackerHandler
54
+
55
+ end # module Agent
56
+ end
@@ -163,14 +163,17 @@ module ManageEngine
163
163
  begin
164
164
  pl = d["td"]
165
165
  dbl = d["db"]
166
+ exc = d["exception"]
166
167
 
167
168
  rt = pl["rt"].round(2)
168
169
  path = @obj.constants.mf_transaction + @obj.constants.mf_separator + pl["path"]
169
170
 
170
171
 
171
172
  apx_stat = nil
173
+ additionalInfo = nil
172
174
  if(@transaction.has_key?(path))
173
175
  apx_stat = @transaction[path][0]
176
+ additionalInfo = @transaction[path][1]
174
177
  else
175
178
  if @transaction.length == @obj.config.metric_overflow_t
176
179
  @obj.log.debug "Metricstore overflow. Current Size: #{@obj.config.metric_overflow_t} #{path}"
@@ -178,6 +181,7 @@ module ManageEngine
178
181
  end
179
182
  apx_stat = Array.new
180
183
  apx_stat = [0,0,0,0,0,0,0,0,0]
184
+ additionalInfo = Hash.new
181
185
  end
182
186
 
183
187
  if (pl.has_key?("error"))
@@ -186,9 +190,15 @@ module ManageEngine
186
190
  apx_stat = apxarray apx_stat,rt
187
191
  end
188
192
 
189
- additionalInfo = Hash.new
190
- if (pl.has_key?("exception"))
191
- additionalInfo[@obj.constants.mf_logmetric] = pl["exception"]
193
+ if (exc != nil)
194
+ logmetric = additionalInfo[@obj.constants.mf_logmetric]
195
+ if (logmetric == nil)
196
+ additionalInfo[@obj.constants.mf_logmetric] = exc
197
+ else
198
+ exc.each do |name, count|
199
+ logmetric[name] = logmetric[name].to_i + count
200
+ end
201
+ end
192
202
  end
193
203
 
194
204
  @transaction[path] = [apx_stat, additionalInfo]
@@ -272,7 +282,7 @@ module ManageEngine
272
282
  stat = Array.new
273
283
  stat = [0,rt,rt,0,0]
274
284
  end
275
- if (pl["error"] != nil)
285
+ if (pl.has_key?("error"))
276
286
  stat[4] += 1
277
287
  else
278
288
  stat = updatert stat,rt