site24x7_apminsight 1.4 → 1.5
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/conf/apminsight.conf +0 -15
- data/lib/agent/am_objectholder.rb +4 -4
- data/lib/agent/configuration/am_configuration.rb +5 -5
- data/lib/agent/metrics/am_metricsformatter.rb +1 -4
- data/lib/agent/metrics/am_metricsparser.rb +139 -509
- data/lib/agent/metrics/am_metricstore.rb +7 -6
- data/lib/agent/server/am_agent.rb +3 -1
- data/lib/agent/server/am_connector.rb +5 -8
- data/lib/agent/server/instrument/active_record.rb +50 -0
- data/lib/agent/server/instrument/am_apm.rb +107 -97
- data/lib/agent/server/instrument/am_instrumenter.rb +54 -42
- data/lib/agent/server/instrument/environment.rb +29 -0
- data/lib/agent/server/instrument/rails.rb +56 -0
- data/lib/agent/server/instrument/sinatra.rb +96 -0
- data/lib/agent/trackers/database_tracker.rb +107 -0
- data/lib/agent/trackers/default_tracker.rb +49 -0
- data/lib/agent/trackers/root_tracker.rb +46 -0
- data/lib/agent/util/am_constants.rb +2 -1
- data/lib/agent/util/am_util.rb +21 -0
- data/lib/agent/util/transaction_util.rb +35 -0
- data/lib/version.rb +2 -2
- data/site24x7-agent.gemspec +12 -23
- metadata +26 -18
@@ -0,0 +1,56 @@
|
|
1
|
+
module ManageEngine
|
2
|
+
module Instrumentation
|
3
|
+
class RailsFramework
|
4
|
+
|
5
|
+
def present?
|
6
|
+
defined?(::Rails) && defined?(::ActionController)
|
7
|
+
end
|
8
|
+
|
9
|
+
def version
|
10
|
+
Rails::VERSION::STRING
|
11
|
+
end
|
12
|
+
|
13
|
+
def env
|
14
|
+
if Rails::VERSION::MAJOR >= 3
|
15
|
+
::Rails.env
|
16
|
+
else
|
17
|
+
RAILS_ENV.dup
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def name
|
22
|
+
'Rails'
|
23
|
+
end
|
24
|
+
|
25
|
+
def instrument
|
26
|
+
@obj = ManageEngine::APMObjectHolder.instance
|
27
|
+
@obj.log.info "Instrumenting ActionController.. Rails Version: #{version}"
|
28
|
+
|
29
|
+
ActiveSupport::Notifications.subscribe('start_processing.action_controller') do |name, start, finish, id, payload|
|
30
|
+
if @obj.config.agent_enabled && @obj.txn_util.listen?(payload[:path])
|
31
|
+
url = "#{payload[:path]} #{payload[:controller]}##{payload[:action]}"
|
32
|
+
railsTracker = ManageEngine::Tracker::RootTracker.new(url, start.to_f * 1000)
|
33
|
+
Thread.current[:apminsight] = railsTracker
|
34
|
+
end
|
35
|
+
end # subscribe
|
36
|
+
|
37
|
+
|
38
|
+
ActiveSupport::Notifications.subscribe('process_action.action_controller') do |name, start, finish, id, payload|
|
39
|
+
tracker = Thread.current[:apminsight]
|
40
|
+
if tracker != nil
|
41
|
+
tracker.finish(finish.to_f * 1000)
|
42
|
+
exception = payload[:exception_object]
|
43
|
+
if exception != nil
|
44
|
+
tracker.setError(exception)
|
45
|
+
tracker.setStatus(500) # By default, set 500 as status for error txns
|
46
|
+
end
|
47
|
+
ManageEngine::APMObjectHolder.instance.collector.updateTransaction(tracker.name, tracker)
|
48
|
+
Thread.current[:apminsight] = nil # Removing threadlocal
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
end # def instrument
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require 'agent/am_objectholder'
|
2
|
+
require 'agent/trackers/root_tracker'
|
3
|
+
|
4
|
+
module ManageEngine
|
5
|
+
module Instrumentation
|
6
|
+
class SinatraFramework
|
7
|
+
|
8
|
+
def present?
|
9
|
+
defined?(::Sinatra) && defined?(::Sinatra::Base)
|
10
|
+
end
|
11
|
+
|
12
|
+
def version
|
13
|
+
::Sinatra::VERSION
|
14
|
+
end
|
15
|
+
|
16
|
+
def env
|
17
|
+
ENV['RACK_ENV'] || ENV['RAILS_ENV'] || 'development'
|
18
|
+
end
|
19
|
+
|
20
|
+
def name
|
21
|
+
'Sinatra'
|
22
|
+
end
|
23
|
+
|
24
|
+
def instrument
|
25
|
+
ManageEngine::APMObjectHolder.instance.log.info "Instrumenting Sinatra framework. Version: #{version}"
|
26
|
+
::Sinatra::Base.class_eval do
|
27
|
+
include ManageEngine::Instrumentation::APMInsightSinatra
|
28
|
+
|
29
|
+
alias original_route_eval route_eval
|
30
|
+
alias route_eval apminsight_route_eval
|
31
|
+
|
32
|
+
# alias sinatra_exception_handler! handle_exception!
|
33
|
+
# alias handle_exception! apminsight_exception_handler!
|
34
|
+
|
35
|
+
end # class_eval
|
36
|
+
end # def instrument
|
37
|
+
|
38
|
+
end # class Sinatra
|
39
|
+
|
40
|
+
module APMInsightSinatra
|
41
|
+
|
42
|
+
def apminsight_route_eval(*args, &block)
|
43
|
+
|
44
|
+
# http://www.rubydoc.info/github/rack/rack/master/Rack/Request
|
45
|
+
url = env.has_key?('sinatra.route') ? env['sinatra.route'] : @request.path
|
46
|
+
@obj = ManageEngine::APMObjectHolder.instance
|
47
|
+
|
48
|
+
if !@obj.config.agent_enabled || !@obj.txn_util.listen?(url)
|
49
|
+
original_route_eval(*args, &block)
|
50
|
+
end
|
51
|
+
|
52
|
+
sinatraTracker = ManageEngine::Tracker::RootTracker.new(url)
|
53
|
+
Thread.current[:apminsight] = sinatraTracker
|
54
|
+
# TODO: capture all additional details @request.query_string @request.params
|
55
|
+
|
56
|
+
begin
|
57
|
+
original_route_eval(*args, &block)
|
58
|
+
|
59
|
+
rescue Exception => e # On application error, above method throws exception
|
60
|
+
sinatraTracker.setError(e)
|
61
|
+
sinatraTracker.setStatus(500) # By default, set 500 as status for error txns
|
62
|
+
raise e
|
63
|
+
|
64
|
+
ensure
|
65
|
+
sinatraTracker.finish
|
66
|
+
ManageEngine::APMObjectHolder.instance.collector.updateTransaction(sinatraTracker.name, sinatraTracker)
|
67
|
+
Thread.current[:apminsight] = nil
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
# def apminsight_exception_handler!(*args, &block)
|
73
|
+
# begin
|
74
|
+
# sinatra_exception_handler!(*args, &block)
|
75
|
+
# ensure
|
76
|
+
# tracker = Thread.current[:apminsight]
|
77
|
+
# puts "tracker is #{(tracker == nil)}"
|
78
|
+
# if tracker != nil
|
79
|
+
# tracker.error(args[0]) # Other way, env[sinatra.error]
|
80
|
+
# tracker.status(@response.status)
|
81
|
+
# finishTracker tracker
|
82
|
+
# end #if
|
83
|
+
# end#begin
|
84
|
+
# end#def
|
85
|
+
#
|
86
|
+
# def finishTracker(tracker)
|
87
|
+
# tracker.finish
|
88
|
+
# #ManageEngine::APMObjectHolder.instance.collector.updateTransaction(id,stats)
|
89
|
+
# puts tracker.to_s
|
90
|
+
# Thread.current[:apminsight] = nil
|
91
|
+
# end
|
92
|
+
|
93
|
+
end # module SinatraFramework
|
94
|
+
|
95
|
+
end # module Instrumentation
|
96
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
module ManageEngine
|
2
|
+
module Tracker
|
3
|
+
class DatabaseTracker < DefaultTracker
|
4
|
+
|
5
|
+
def sql(query)
|
6
|
+
@query = format(query.dup)
|
7
|
+
end
|
8
|
+
|
9
|
+
def params(binds = [])
|
10
|
+
@binds = binds
|
11
|
+
end
|
12
|
+
|
13
|
+
def sqlBacktrace(backtrace)
|
14
|
+
@backtrace = backtrace
|
15
|
+
end
|
16
|
+
|
17
|
+
def getRawQuery
|
18
|
+
@query
|
19
|
+
end
|
20
|
+
|
21
|
+
def getObfuscatedQuery
|
22
|
+
ManageEngine::APMObjectHolder.instance.util.parametrizeQuery @query
|
23
|
+
end
|
24
|
+
|
25
|
+
def getCompleteQuery
|
26
|
+
begin
|
27
|
+
query = @query # Maintaining the original query
|
28
|
+
if query != nil && @binds != nil && @binds.length > 0
|
29
|
+
@binds.each do |ar|
|
30
|
+
if query.index("?") != nil
|
31
|
+
query["?"]=ar.value.to_s
|
32
|
+
end
|
33
|
+
end
|
34
|
+
return query
|
35
|
+
end
|
36
|
+
rescue Exception=>exe
|
37
|
+
@logger.logException "Not severe -#{exe.message}",exe
|
38
|
+
end
|
39
|
+
@query
|
40
|
+
end
|
41
|
+
|
42
|
+
# Returns array [db_operation, tablename]
|
43
|
+
def getQueryInfo
|
44
|
+
sql = @query
|
45
|
+
sql.strip!
|
46
|
+
sql.downcase!
|
47
|
+
sqlArr = sql.split(" ")
|
48
|
+
|
49
|
+
begin
|
50
|
+
tableName = case sqlArr[0]
|
51
|
+
when "select" then sqlArr[sqlArr.index("from")+1]
|
52
|
+
when "insert" then sqlArr[sqlArr.index("into")+1]
|
53
|
+
when "update" then sqlArr[1]
|
54
|
+
when "delete" then sqlArr[sqlArr.index("from")+1]
|
55
|
+
when "create" then sqlArr[1] + sqlArr[2]
|
56
|
+
when "alter" then sqlArr[1] + sqlArr[2]
|
57
|
+
when "drop" then sqlArr[1] + sqlArr[2]
|
58
|
+
when "show" then sqlArr[1]
|
59
|
+
when "describe" then sqlArr[1]
|
60
|
+
else "-"
|
61
|
+
end
|
62
|
+
|
63
|
+
return [sqlArr[0], tableName]
|
64
|
+
|
65
|
+
rescue Exception=>e
|
66
|
+
@logger.logException "#{e.message}",e
|
67
|
+
return [sqlArr[0], '-']
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def format s
|
72
|
+
s.gsub!("\"", '')
|
73
|
+
s.gsub!("\n", '')
|
74
|
+
s
|
75
|
+
end
|
76
|
+
|
77
|
+
def getAdditionalInfo
|
78
|
+
info = super
|
79
|
+
begin
|
80
|
+
if (@query != nil)
|
81
|
+
if (info == nil)
|
82
|
+
info = Hash.new
|
83
|
+
end
|
84
|
+
|
85
|
+
obj = ManageEngine::APMObjectHolder.instance
|
86
|
+
|
87
|
+
info["query"] = !obj.config.sql_capture_params ? getCompleteQuery : getObfuscatedQuery
|
88
|
+
# send only one backtrace, Exception backtrace have more priority
|
89
|
+
if (@backtrace != nil && @error == nil)
|
90
|
+
info["stacktrace"] = obj.util.formatStacktrace(@backtrace)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
rescue Exception => e
|
94
|
+
@logger.logException("Error updating additionalInfo in dbTracker.", e)
|
95
|
+
end
|
96
|
+
|
97
|
+
info
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
def to_s
|
102
|
+
"#{@name} - #{@query}"
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module ManageEngine
|
2
|
+
module Tracker
|
3
|
+
|
4
|
+
class DefaultTracker
|
5
|
+
|
6
|
+
attr_accessor :name, :error, :endtime, :starttime
|
7
|
+
|
8
|
+
def initialize(name = "unknonwn", time = ManageEngine::APMObjectHolder.instance.util.currenttimemillis)
|
9
|
+
@starttime = time.to_i
|
10
|
+
@name = ManageEngine::APMObjectHolder.instance.txn_util.normalizeName(name)
|
11
|
+
@logger = ManageEngine::APMObjectHolder.instance.log
|
12
|
+
end
|
13
|
+
|
14
|
+
def finish(time = ManageEngine::APMObjectHolder.instance.util.currenttimemillis)
|
15
|
+
@endtime = time.to_i
|
16
|
+
end
|
17
|
+
|
18
|
+
def error?
|
19
|
+
@error != nil
|
20
|
+
end
|
21
|
+
|
22
|
+
def setError(exception)
|
23
|
+
@error = exception
|
24
|
+
end
|
25
|
+
|
26
|
+
def setName(context)
|
27
|
+
@name = context
|
28
|
+
end
|
29
|
+
|
30
|
+
def duration
|
31
|
+
(@endtime - @starttime).to_i
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_s
|
35
|
+
@name
|
36
|
+
end
|
37
|
+
|
38
|
+
def getAdditionalInfo
|
39
|
+
if error?
|
40
|
+
{ManageEngine::APMObjectHolder.instance.constants.mf_exception_st => ManageEngine::APMObjectHolder.instance.util.formatStacktrace(@error.backtrace)}
|
41
|
+
else
|
42
|
+
nil
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'agent/trackers/default_tracker'
|
2
|
+
|
3
|
+
module ManageEngine
|
4
|
+
module Tracker
|
5
|
+
class RootTracker < DefaultTracker
|
6
|
+
|
7
|
+
attr_accessor :children, :status
|
8
|
+
|
9
|
+
def http_method(method)
|
10
|
+
@http_method = method
|
11
|
+
end
|
12
|
+
|
13
|
+
def http_params(params)
|
14
|
+
@http_params = params
|
15
|
+
end
|
16
|
+
|
17
|
+
def queryString(querystring)
|
18
|
+
@queryString = querystring
|
19
|
+
end
|
20
|
+
|
21
|
+
def setStatus(httpcode)
|
22
|
+
@status = httpcode
|
23
|
+
end
|
24
|
+
|
25
|
+
def addChild(tracker)
|
26
|
+
if @children == nil
|
27
|
+
@children = Array.new
|
28
|
+
end
|
29
|
+
@children.push(tracker)
|
30
|
+
end
|
31
|
+
|
32
|
+
def getAdditionalInfo
|
33
|
+
info = super
|
34
|
+
if (@http_method != nil && @queryString != nil && @status != nil)
|
35
|
+
if (info == nil)
|
36
|
+
info = Hash.new
|
37
|
+
end
|
38
|
+
info["http_method_name"] = @http_method
|
39
|
+
info["http_query_str"] = @queryString
|
40
|
+
info["httpcode"] = @status
|
41
|
+
end
|
42
|
+
info
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -3,7 +3,7 @@ module ManageEngine
|
|
3
3
|
class APMConstants
|
4
4
|
|
5
5
|
attr_reader :apm_gem,:s247_apm_gem,:apm_conf,:agent_conf,:connection_open_timeout,:connection_read_timeout,:connect_uri,:connect_data_uri,:connect_trace_uri,:connect_config_update_uri,:site24x7USurl, :site24x7EUurl, :mergepattern_conf
|
6
|
-
attr_reader :licence_exceeds,:licence_expired,:unmanage_agent,:manage_agent,:agent_config_updated,:error_notfound,:error_server,:delete_agent,:response_code,:custom_config_info
|
6
|
+
attr_reader :licence_exceeds,:licence_expired,:unmanage_agent,:manage_agent,:agent_config_updated,:error_notfound,:error_server,:delete_agent,:response_code,:custom_config_info, :agent_specific_info
|
7
7
|
attr_reader :mf_transaction,:mf_separator,:mf_db,:mf_apdex,:mf_namespace,:mf_name,:mf_all,:agent_store,:agent_lock,:mf_overflow
|
8
8
|
attr_reader :mf_logmetric, :mf_logmetric_warning, :mf_exception_st, :mf_err_st, :mf_loginfo, :mf_loginfo_time, :mf_loginfo_level, :mf_loginfo_str, :mf_loginfo_err_clz, :mf_loginfo_st, :mf_loginfo_level_warn
|
9
9
|
|
@@ -63,6 +63,7 @@ module ManageEngine
|
|
63
63
|
@error_server = 500
|
64
64
|
@response_code = "response-code"
|
65
65
|
@custom_config_info = "custom_config_info"
|
66
|
+
@agent_specific_info = "agent_specific_info"
|
66
67
|
|
67
68
|
#Metrics Formatter -mf
|
68
69
|
@mf_apdex = "apdex"
|
data/lib/agent/util/am_util.rb
CHANGED
@@ -126,5 +126,26 @@ module ManageEngine
|
|
126
126
|
qry
|
127
127
|
end
|
128
128
|
|
129
|
+
def formatStacktrace(stacktrace)
|
130
|
+
strace = Array.new;
|
131
|
+
begin
|
132
|
+
stacktrace.each do |stackelement|
|
133
|
+
temp = Array.new
|
134
|
+
temp[0] = stackelement
|
135
|
+
temp[1] = ""
|
136
|
+
temp[2] = ""
|
137
|
+
temp[3] = ""
|
138
|
+
strace.push(temp)
|
139
|
+
if (strace.size == 10)
|
140
|
+
break;
|
141
|
+
end
|
142
|
+
end
|
143
|
+
rescue Exception=>e
|
144
|
+
@obj.log.logException "Error while formatting stack trace. #{e.message}", e
|
145
|
+
end
|
146
|
+
|
147
|
+
strace
|
148
|
+
end
|
149
|
+
|
129
150
|
end#c
|
130
151
|
end#m
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module ManageEngine
|
2
|
+
class TransactionUtil
|
3
|
+
|
4
|
+
def initialize
|
5
|
+
@obj = ManageEngine::APMObjectHolder.instance
|
6
|
+
end
|
7
|
+
|
8
|
+
def normalizeName(txnName)
|
9
|
+
if (txnName != nil)
|
10
|
+
txnName.gsub!(/\/\d+/, "/*") # Replace all numbers with *
|
11
|
+
# Transaction merge patterns - provided by user
|
12
|
+
@obj.config.url_merge_pattern.each do |key, val|
|
13
|
+
if (txnName.match(key) != nil)
|
14
|
+
txnName=val
|
15
|
+
break
|
16
|
+
end
|
17
|
+
end # do
|
18
|
+
end # if (txnName != nil)
|
19
|
+
txnName
|
20
|
+
end # def normalizeName
|
21
|
+
|
22
|
+
def listen?(txnName)
|
23
|
+
if (txnName != nil)
|
24
|
+
@obj.config.txn_skip_listen.each do |pattern|
|
25
|
+
pattern = pattern.start_with?('.*') ? pattern : ('.' + pattern)
|
26
|
+
if (txnName.match(pattern) != nil)
|
27
|
+
return false
|
28
|
+
end
|
29
|
+
end # do
|
30
|
+
end
|
31
|
+
true
|
32
|
+
end # def listen?
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|