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,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