apminsight 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,254 @@
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
+ @obj.config.lastupdatedtime=File.mtime(@obj.constants.apm_conf).to_i
48
+ @obj.config.configureFile
49
+ @obj.config.assignConfig
50
+ end
51
+ end
52
+
53
+ def checkforagentstatus
54
+ prevState = @obj.config.agent_enabled
55
+ @obj.config.checkAgentInfo
56
+ if !@obj.config.agent_enabled
57
+ @obj.log.info "Agent in Disabled State."
58
+ if prevState
59
+ @obj.log.info "Agent in Disabled State. Going to unsubscribe"
60
+ @obj.instrumenter.doUnSubscribe
61
+ end
62
+ else
63
+ if !prevState
64
+ @obj.log.info "Agent in Active State."
65
+ @obj.instrumenter.doSubscribe
66
+ end
67
+ end
68
+ end
69
+
70
+ def stop
71
+ dc
72
+ @obj.shutdown = true;
73
+ end
74
+
75
+ def dc
76
+ begin
77
+ @obj.log.debug "[dc] collecting..."
78
+ now = @obj.util.currenttimemillis
79
+ result = Array.new
80
+ result.push(@obj.last_dispatch_time)
81
+ result.push(now)
82
+ data = Array.new
83
+ trd= nil;
84
+ @last_dispatch_time = now
85
+ if @obj.config.agent_enabled
86
+ d = @obj.parser.parse @obj.store.metrics_dup
87
+ if(d!=nil && d.has_key?("trace-data"))
88
+ trd = d.delete("trace-data");
89
+ #@obj.log.info "[dc] [TRACE] : #{d}"
90
+ end
91
+ #@obj.log.info "[dc] Data - #{d}"
92
+ if(d.length>0)
93
+ data =@obj.formatter.format d
94
+ #@obj.log.debug "[dc] Formatted Data - #{data}"
95
+ end
96
+ @obj.store.remove @obj.formatter.keysToRemove
97
+ end #if
98
+ fd = Array.new
99
+ fd.push(data)
100
+ if(trd!=nil)
101
+ fd.push(trd)
102
+ end
103
+ @obj.log.debug "[dc] data to store : #{fd}"
104
+ send_save fd
105
+ @obj.log.debug "[dc] collecting ends"
106
+ rescue Exception=>e
107
+ @obj.log.logException "[dc] Exception during data Collection. #{e.message}",e
108
+ @obj.shutdown=true
109
+ end
110
+ end
111
+
112
+ def senddata d
113
+ # @obj.log.info("Send data --- #{d}")
114
+ result = Array.new
115
+ result.push( (File.mtime(@obj.constants.agent_lock).to_f*1000).to_i)
116
+ now = @obj.util.currenttimemillis
117
+ result.push(now)
118
+ write @obj.constants.agent_lock ,"#{Process.pid}"
119
+ data = read @obj.constants.agent_store
120
+ data.push(d);
121
+ tdata = Array.new;
122
+ trdata = Array.new;
123
+ data.each do |val|
124
+ case val.size
125
+ when 1
126
+ tdata.concat(val[0])
127
+ when 2
128
+ tdata.concat(val[0])
129
+ trdata.concat(val[1])
130
+ end
131
+ end
132
+ result.push(merge(tdata))
133
+ resp = @obj.connector.post @obj.constants.connect_data_uri+@obj.config.instance_id,result
134
+ if trdata.size>0
135
+ result[2]=trdata;
136
+ resp = @obj.connector.post @obj.constants.connect_trace_uri+@obj.config.instance_id,result
137
+ end
138
+ end
139
+
140
+ def save fd
141
+ begin
142
+ data = fd.to_json;
143
+ write @obj.constants.agent_store,data
144
+ rescue Exception=>e
145
+ @obj.log.logException "[dc] Exception during save. #{e.message}",e
146
+ end
147
+ end
148
+
149
+ def send_save data
150
+ begin
151
+ if FileTest.exist?(@obj.constants.agent_lock)
152
+ if Time.now.to_i - File.mtime(@obj.constants.agent_lock).to_i > (@obj.config.connect_interval).to_i
153
+ @obj.log.debug "worker send signal"
154
+ senddata data
155
+ else
156
+ @obj.log.info "worker save signal"
157
+ save data
158
+ end
159
+ else
160
+ @obj.log.info "worker save signals"
161
+ save data
162
+ write @obj.constants.agent_lock,"#{Process.pid}"
163
+ end
164
+ rescue Exception=>e
165
+ @obj.log.logException "Exception in decision making send or save #{e.message}",e
166
+ end
167
+ end
168
+
169
+ def read p
170
+ data = Array.new
171
+ File.open( p, "r+" ) { |f|
172
+ f.flock(File::LOCK_EX)
173
+ begin
174
+ f.each_line do |line|
175
+ data.push(JSON.parse(line))
176
+ end
177
+ f.truncate 0
178
+ rescue Exception=>e
179
+ @obj.log.logException "Exception while reading data #{e}",e
180
+ ensure
181
+ f.flock(File::LOCK_UN)
182
+ end
183
+ }
184
+ data
185
+ end
186
+
187
+
188
+ def write (p, data )
189
+ File.open( p, "a+" ) { |f|
190
+ f.flock(File::LOCK_EX)
191
+ begin
192
+ f.write "#{data}\n"
193
+ rescue Exception=>e
194
+ @obj.log.logException "Exception while writing data #{e.message}",e
195
+ ensure
196
+ f.flock(File::LOCK_UN)
197
+ end
198
+ }
199
+ end
200
+
201
+ def merge data
202
+ # @obj.log.info "BEFORE MERGE : #{data}"
203
+ tdata =Hash.new ;
204
+ data.each do |sd|
205
+ name= sd[0]["ns"] + sd[0]["name"];
206
+ if tdata.has_key?(name)
207
+ if (sd[0]["name"]=="apdex")
208
+ tdata[name][1] = mapdx(tdata[name][1],sd[1])
209
+ else
210
+ tdata[name][1] = mapdb(tdata[name][1],sd[1])
211
+ end
212
+ else
213
+ tdata[name]=sd;
214
+ end
215
+ end
216
+ #@obj.log.info "MERGED DATA : #{tdata}"
217
+ res = Array.new;
218
+ tdata.each do|key,value|
219
+ res.push(value);
220
+ end
221
+ res
222
+ end
223
+
224
+
225
+ def mapdx res,dat
226
+ res[0] = res[0]+dat[0];
227
+ if dat[1]<res[1]
228
+ res[1]=dat[1]
229
+ end
230
+ if dat[2]>res[2]
231
+ res[2]=dat[2]
232
+ end
233
+ res[3] = res[3]+dat[3]
234
+ res[5] = res[5]+dat[5]
235
+ res[6] = res[6]+dat[6]
236
+ res[7] = res[7]+dat[7]
237
+ res[4] = (res[5].to_f + (res[6].to_f/2).to_f).to_f/res[3].to_f
238
+ res
239
+ end
240
+
241
+ def mapdb res,dat
242
+ res[0] = res[0]+dat[0];
243
+ if dat[1]<res[1]
244
+ res[1]=dat[1]
245
+ end
246
+ if dat[2]>res[2]
247
+ res[2]=dat[2]
248
+ end
249
+ res[3] = res[3]+dat[3]
250
+ res
251
+ end
252
+
253
+ end#c
254
+ end#m
@@ -0,0 +1,64 @@
1
+
2
+ module ManageEngine
3
+ class APMConstants
4
+
5
+ attr_reader :apm_gem,:apm_conf,:agent_conf,:connection_open_timeout,:connection_read_timeout,:connect_uri,:connect_data_uri,:connect_trace_uri
6
+ attr_reader :licence_exceeds,:licence_expired,:unmanage_agent,:manage_agent,:error_notfound,:error_server,:delete_agent,:response_code
7
+ attr_reader :mf_transaction,:mf_separator,:mf_db,:mf_apdex,:mf_namespace,:mf_name,:mf_all,:agent_store,:agent_lock
8
+
9
+ def initialize
10
+
11
+ #File path for APM Conf file
12
+ @apm_gem="apminsight"
13
+ #File path for APM Conf file
14
+ @apm_conf="apminsight.conf"
15
+
16
+ #file path for agent id, enable details
17
+ @agent_conf="apminsight.info"
18
+
19
+ #file path for agent data store lock
20
+ @agent_lock="apminsight.lock"
21
+
22
+ #file path for agent data store lock
23
+ @agent_store="apminsight.store"
24
+
25
+
26
+ #Timeout for opening Connections
27
+ @connection_open_timeout=60
28
+
29
+ #Timeout for Reading data from Connections
30
+ @connection_read_timeout=60
31
+
32
+ #Connection uri
33
+ @connect_uri="arh/connect"
34
+
35
+ #Connection uri for data
36
+ @connect_data_uri="arh/data?instance_id="
37
+
38
+ #Connection uri for trace
39
+ @connect_trace_uri="arh/trace?instance_id="
40
+
41
+ #Response Codes
42
+ @licence_expired = 701
43
+ @licence_exceeds = 702
44
+ @delete_agent = 900
45
+ @unmanage_agent =910
46
+ @manage_agent = 911
47
+ @error_notfound = 404
48
+ @error_server = 500
49
+ @response_code = "response-code"
50
+
51
+ #Metrics Formatter -mf
52
+ @mf_apdex = "apdex"
53
+ @mf_namespace = "ns"
54
+ @mf_name = "name"
55
+ @mf_all = "all"
56
+
57
+ @mf_separator = "/"
58
+ @mf_transaction = "transaction" + @mf_separator + "http"
59
+ @mf_db = "db"
60
+
61
+
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,130 @@
1
+ require 'socket'
2
+ module ManageEngine
3
+ class APMUtil
4
+
5
+ def setLogger log
6
+ @log = log
7
+ end
8
+
9
+ #Reads the Property Files and returns a Hashes
10
+ def readProperties filepath
11
+ props = {}
12
+ begin
13
+ propsFile=File.open(filepath, 'r')
14
+ propsFile.read.each_line do |line|
15
+ line.strip!
16
+ if (line[0] != ?# and line[0] != ?=)
17
+ i = line.index('=')
18
+ if (i)
19
+ props[line[0..i - 1].strip] = line[i + 1..-1].strip
20
+ else
21
+ props[line] = ''
22
+ end
23
+ end
24
+ end
25
+ rescue Exception=>e
26
+ @log.info "Problem in Reading Property File : #{e.message} "
27
+ @log.error "#{e.backtrace}"
28
+ ensure
29
+ propsFile.close
30
+ end
31
+ props
32
+ end
33
+
34
+ #write the Properties into the Property file
35
+ def writeProperties(f,props)
36
+ begin
37
+ file = File.new(f,"w+")
38
+ props.each {|key,value| file.puts "#{key}=#{value}\n"}
39
+ rescue Exception=>e
40
+ @log.info "Problem in Writing Property File : \n File : #{f}"
41
+ @log.logException "#{e.message}",e
42
+ ensure
43
+ file.close
44
+ end
45
+ end
46
+
47
+ def copyFiles src, dest
48
+ result = false
49
+ begin
50
+ srcFile = File.open(src)
51
+ destFile = File.open(dest , "w")
52
+ destFile.write( srcFile.read(100) ) while not srcFile.eof?
53
+ result = true
54
+ rescue Exception=>e
55
+ @log.info "Problem in Copying File : \n File : #{src} to #{dest}"
56
+ @log.logException "#{e.message}",e
57
+ result = false;
58
+ ensure
59
+ srcFile.close
60
+ destFile.close
61
+ end
62
+
63
+ result
64
+ end
65
+
66
+
67
+ def getBooleanValue(str)
68
+ if str == true || str == "true" || str == "True" || str == "TRUE"
69
+ return true
70
+ else
71
+ return false
72
+ end
73
+ end
74
+
75
+ def currenttimemillis
76
+ (Time.now.to_f*1000).to_i
77
+ end
78
+
79
+
80
+ def getArray value,sep
81
+ arr = Array.new
82
+ if(value!=nil && value.length>0)
83
+ arr = value.split(sep)
84
+ end
85
+ arr
86
+ end
87
+ def isPortBusy(port)
88
+ Timeout::timeout(1) do
89
+ begin
90
+ TCPSocket.new('localhost', port).close
91
+ true
92
+ rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH
93
+ false
94
+ end
95
+ end
96
+ rescue Timeout::Error
97
+ false
98
+ end
99
+
100
+ def is_integer(val)
101
+ Integer(val)
102
+ rescue ArgumentError
103
+ false
104
+ else
105
+ true
106
+ end
107
+
108
+ def is_float(val)
109
+ Float(val)
110
+ rescue ArgumentError
111
+ false
112
+ else
113
+ true
114
+ end
115
+
116
+ def parametrizeQuery qry
117
+ begin
118
+ qry.gsub!(/'(.*?[^'])??'/,"?")
119
+ qry.gsub!(/\"(.*?[^\"])??\"/,"?")
120
+ qry.gsub!(/=.\d+/,"=?")
121
+ qry.gsub!(/,.\d+/,", ?")
122
+ rescue Exception=>e
123
+ @log.info "Problem in Parameterizing query: #{e.message} "
124
+ @log.logException "#{e.message}",e
125
+ end
126
+ qry
127
+ end
128
+
129
+ end#c
130
+ end#m
@@ -0,0 +1,5 @@
1
+ require "agent/server/instrument/am_apm"
2
+ require "agent/am_objectholder"
3
+ module ManageEngine
4
+ ManageEngine::APMObjectHolder.instance
5
+ end