weblogic-jmx4r 0.1.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env jruby
2
+ require 'rubygems'
3
+ require 'jmx4r'
4
+
5
+ # This example shows how to iterate on TabularData
6
+
7
+ runtime = JMX::MBean.find_by_name "java.lang:type=Runtime"
8
+
9
+ # The system_properties attribute of the Runtime MBean is an instance of
10
+ # TabularDataSupport
11
+ sysprops = runtime.system_properties
12
+ sysprops.each do | sysprop|
13
+ puts "#{sysprop["key"]} = #{sysprop["value"]}"
14
+ end
@@ -0,0 +1,127 @@
1
+ require 'rubygems'
2
+ require 'jmx4r'
3
+ require 'java'
4
+
5
+
6
+
7
+
8
+ def get_weblogic_metrics(jmx_connection)
9
+
10
+ array_of_hashes = []
11
+
12
+ service_object_name = JMX::MBean::ObjectName.new("com.bea:Name=DomainRuntimeService,Type=weblogic.management.mbeanservers.domainruntime.DomainRuntimeServiceMBean")
13
+ servers = jmx_connection.getAttribute(service_object_name, "ServerRuntimes")
14
+
15
+ for server in servers
16
+ server_state = jmx_connection.getAttribute(server, "State");
17
+ server_name = jmx_connection.getAttribute(server, "Name");
18
+ server_health_state = jmx_connection.getAttribute(server, "HealthState");
19
+
20
+ jvm_runtime = jmx_connection.getAttribute(server, "JVMRuntime");
21
+ heap_free = jmx_connection.getAttribute(jvm_runtime, "HeapFreeCurrent");
22
+
23
+ thread_pool_runtime = jmx_connection.getAttribute(server, "ThreadPoolRuntime");
24
+ thread_idle = jmx_connection.getAttribute(thread_pool_runtime, "ExecuteThreadIdleCount");
25
+
26
+ array_of_hashes << {'server_name' => server_name, 'server_state' => server_state, 'heap_free' => heap_free, 'thread_idle' => thread_idle}
27
+
28
+
29
+ domain_runtime_object_name = jmx_connection.getAttribute(service_object_name, "DomainRuntime");
30
+ apps = jmx_connection.getAttribute(domain_runtime_object_name, "AppRuntimeStateRuntime");
31
+ app_ids = jmx_connection.getAttribute(apps, "ApplicationIds");
32
+ app_runtimes = jmx_connection.getAttribute(server, "ApplicationRuntimes");
33
+
34
+ states = Hash.new
35
+ for app_id in app_ids
36
+ app_name = (app_id.split("#"))[0];
37
+ state = jmx_connection.invoke(apps, "getCurrentState", Array.new(app_id, server_name), Array.new( "java.lang.String", "java.lang.String") )
38
+ states[app_name] = state
39
+ end
40
+
41
+
42
+ for app_runtime in app_runtimes
43
+ appli_name = jmx_connection.getAttribute(app_runtime, "Name");
44
+ component_runtimes_object_name_list = jmx_connection.getAttribute(app_runtime, "ComponentRuntimes");
45
+
46
+ for component_runtimes_object_name in component_runtimes_object_name_list
47
+ app_name = jmx_connection.getAttribute(app_runtime, "Name");
48
+ component_type = jmx_connection.getAttribute(component_runtimes_object_name, "Type");
49
+ if component_type.to_s == "WebAppComponentRuntime"
50
+ open_sessions = jmx_connection.getAttribute(component_runtimes_object_name,"OpenSessionsCurrentCount");
51
+ state = states[appli_name]
52
+
53
+ array_of_hashes << {'app_name' => app_name, 'state' => state, 'open_sessions' => open_sessions, 'server_name' => server_name}
54
+ end
55
+ end
56
+
57
+
58
+ jdbc_runtime_object_name = jmx_connection.getAttribute(server, "JDBCServiceRuntime");
59
+ datastores_object_name_list = jmx_connection.getAttribute(jdbc_runtime_object_name, "JDBCDataSourceRuntimeMBeans");
60
+
61
+ for datastores_object_name in datastores_object_name_list
62
+ datastore_name = jmx_connection.getAttribute(datastores_object_name, "Name");
63
+ datastore_state = jmx_connection.getAttribute(datastores_object_name, "State");
64
+ datastore_connection_total_count = jmx_connection.getAttribute(datastores_object_name, "ConnectionsTotalCount");
65
+ datastore_active_connections_current_count = jmx_connection.getAttribute(datastores_object_name, "ActiveConnectionsCurrentCount");
66
+ datastore_active_connections_high_count = jmx_connection.getAttribute(datastores_object_name, "ActiveConnectionsHighCount");
67
+
68
+ array_of_hashes << {'server_name' => server_name, 'datastore_name' => datastore_name, 'datastore_name' => datastore_name,
69
+ 'datastore_state' => datastore_state, 'datastore_connection_total_count' => datastore_connection_total_count,
70
+ 'datastore_active_connections_current_count' => datastore_active_connections_current_count, 'datastore_active_connections_high_count' => datastore_active_connections_high_count}
71
+ end
72
+
73
+ jms_runtime = jmx_connection.getAttribute(server, "JMSRuntime");
74
+ jms_servers_object_name_list = jmx_connection.getAttribute(jms_runtime, "JMSServers");
75
+
76
+ for jms_servers_object_name in jms_servers_object_name_list
77
+ destinations_object_name_list = jmx_connection.getAttribute(jms_servers_object_name, "Destinations");
78
+
79
+ for destinations_object_name in destinations_object_name_list
80
+ jms_pending_messages = jmx_connection.getAttribute(destinations_object_name, "MessagesPendingCount");
81
+ jms_name = jmx_connection.getAttribute(destinations_object_name, "Name");
82
+
83
+ array_of_hashes << {'server_name' => server_name, 'jms_pending_messages' => jms_pending_messages, 'jms_name' => jms_name}
84
+
85
+ end
86
+
87
+ end
88
+
89
+
90
+ end
91
+
92
+
93
+
94
+
95
+ end
96
+ return array_of_hashes
97
+ end
98
+
99
+ jmx_connection = JMX::MBean.establish_connection :url => "service:jmx:t3://localhost:7001/jndi/weblogic.management.mbeanservers.domainruntime", :provider_package => "weblogic.management.remote", :username => "weblogic", :password => "Gildarex1"
100
+
101
+ #jmx_object_name_s = JMX::MBean.find_all_by_name "com.bea:Name=DomainRuntimeService,Type=weblogic.management.mbeanservers.domainruntime.DomainRuntimeServiceMBean", :connection => jmx_connection
102
+
103
+
104
+ #service = JMX::MBean::ObjectName.new("com.bea:Name=DomainRuntimeService,Type=weblogic.management.mbeanservers.domainruntime.DomainRuntimeServiceMBean")
105
+
106
+
107
+ #servers = jmx_connection.getAttribute(service, "ServerRuntimes")
108
+ #
109
+
110
+
111
+ # for server in servers
112
+ # serverState = jmx_connection.getAttribute(server, "State");
113
+ # serverName = jmx_connection.getAttribute(server, "Name");
114
+ # serverHealthState = jmx_connection.getAttribute(server, "HealthState");
115
+ # puts "Server state #{serverState} #{serverName} #{serverState} #{serverHealthState}"
116
+ #
117
+ # jvmRuntime = jmx_connection.getAttribute(server, "JVMRuntime");
118
+ # heap_free = jmx_connection.getAttribute(jvmRuntime, "HeapFreeCurrent");
119
+ #
120
+ # threadPoolRuntime = jmx_connection.getAttribute(server, "ThreadPoolRuntime");
121
+ # threadIdle = jmx_connection.getAttribute(threadPoolRuntime, "ExecuteThreadIdleCount");
122
+ #
123
+ # puts "Server state #{heap_free} #{threadIdle} "
124
+ # end
125
+ #
126
+ array_of_hashes = get_weblogic_metrics(jmx_connection)
127
+ puts array_of_hashes.to_json
@@ -0,0 +1,277 @@
1
+ # Copyright (c) 2008 Thomas E Enebo <enebo@acm.org>
2
+ #--
3
+ # taken from the 'jmx' gems in jruby-extras
4
+
5
+ module JMX
6
+ java_import javax.management.MBeanParameterInfo
7
+ java_import javax.management.MBeanOperationInfo
8
+ java_import javax.management.MBeanAttributeInfo
9
+ java_import javax.management.MBeanInfo
10
+
11
+ # Module that is used to bridge java to ruby and ruby to java types.
12
+ module JavaTypeAware
13
+ # Current list of types we understand If it's not in this list we are
14
+ # assuming that we are going to convert to a java.object
15
+ SIMPLE_TYPES = {
16
+ :boolean => ['java.lang.Boolean', lambda {|param| param}],
17
+ :byte => ['java.lang.Byte', lambda {|param| param.to_i}],
18
+ :int => ['java.lang.Integer', lambda {|param| param.to_i}],
19
+ :long => ['java.lang.Long', lambda {|param| param.to_i}],
20
+ :float => ['java.lang.Float', lambda {|param| param.to_f}],
21
+ :double => ['java.lang.Double', lambda {|param| param.to_f}],
22
+ :list => ['java.util.ArrayList', lambda {|param| param.to_a}],
23
+ :map => ['java.util.HashMap', lambda {|param| param}],
24
+ :set => ['java.util.HashSet', lambda {|param| param}],
25
+ :string => ['java.lang.String', lambda {|param| param.to_s}],
26
+ :void => ['java.lang.Void', lambda {|param| nil}]
27
+ }
28
+
29
+ def to_java_type(type_name)
30
+ SIMPLE_TYPES[type_name][0] || type_name
31
+ end
32
+ #TODO: I'm not sure this is strictly needed, but funky things can happen if you
33
+ # are expecting your attributes (from the ruby side) to be ruby types and they are java types.
34
+ def to_ruby(type_name)
35
+ SIMPLE_TYPES[type_name][1] || lambda {|param| param}
36
+ end
37
+ end
38
+
39
+ class Parameter
40
+ include JavaTypeAware
41
+
42
+ def initialize(type, name, description)
43
+ @type, @name, @description = type, name, description
44
+ end
45
+
46
+ def to_jmx
47
+ MBeanParameterInfo.new @name.to_s, to_java_type(@type), @description
48
+ end
49
+ end
50
+
51
+ class Operation < Struct.new(:description, :parameters, :return_type, :name, :impact)
52
+ include JavaTypeAware
53
+
54
+ def initialize(description)
55
+ super
56
+ self.parameters, self.impact, self.description = [], MBeanOperationInfo::UNKNOWN, description
57
+ end
58
+
59
+ def to_jmx
60
+ java_parameters = parameters.map { |parameter| parameter.to_jmx }
61
+ MBeanOperationInfo.new name.to_s, description, java_parameters.to_java(javax.management.MBeanParameterInfo), to_java_type(return_type), impact
62
+ end
63
+ end
64
+
65
+ class Attribute < Struct.new(:name, :type, :description, :is_reader, :is_writer, :is_iser)
66
+ include JavaTypeAware
67
+
68
+ def initialize(name, type, description, is_rdr, is_wrtr)
69
+ super
70
+ self.description, self.type, self.name = description, type, name
71
+ self.is_reader,self.is_writer, self.is_iser = is_rdr, is_wrtr, false
72
+ end
73
+
74
+ def to_jmx
75
+ MBeanAttributeInfo.new(name.to_s, to_java_type(type), description, is_reader, is_writer, is_iser)
76
+ end
77
+ end
78
+
79
+ # Creators of Ruby based MBeans must inherit this
80
+ # class (<tt>DynamicMBean</tt>) in their own bean classes and then register them with a JMX mbean server.
81
+ # Here is an example:
82
+ # class MyMBean < DynamicMBean
83
+ # rw_attribute :status, :string, "Status information for this process"
84
+ #
85
+ # operation "Shutdown this process"
86
+ # parameter :string, "user_name", "Name of user requesting shutdown"
87
+ # returns :string
88
+ # def shutdown(user_name)
89
+ # "shutdown requests more time"
90
+ # end
91
+ # end
92
+ # Once you have defined your bean class you can start declaring attributes and operations.
93
+ # Attributes come in three flavors: read, write, and read write. Simmilar to the <tt>attr*</tt>
94
+ # helpers, there are helpers that are used to create management attributes. Use +r_attribute+,
95
+ # +w_attribute+, and +rw_attribute+ to declare attributes, and the +operation+, +returns+,
96
+ # and +parameter+ helpers to define a management operation.
97
+ # Creating attributes with the *_attribute convention ALSO creates ruby accessors
98
+ # (it invokes the attr_accessor/attr_reader/attr_writer ruby helpers) to create ruby methods
99
+ # like: user_name= and username. So in your ruby code you can treat the attributes
100
+ # as "regular" ruby accessors
101
+ class DynamicMBean
102
+ java_import javax.management.MBeanOperationInfo
103
+ java_import javax.management.MBeanAttributeInfo
104
+ java_import javax.management.DynamicMBean
105
+ java_import javax.management.MBeanInfo
106
+ include JMX::JavaTypeAware
107
+
108
+ #NOTE this will not be needed when JRuby-3164 is fixed.
109
+ def self.inherited(cls)
110
+ cls.send(:include, DynamicMBean)
111
+ end
112
+
113
+ def self.mbean_attributes
114
+ @mbean_attributes ||= {}
115
+ end
116
+
117
+ # TODO: preserve any original method_added?
118
+ # TODO: Error handling here when it all goes wrong?
119
+ def self.method_added(name) #:nodoc:
120
+ return if self.mbean_attributes[:op].nil?
121
+ self.mbean_attributes[:op].name = name
122
+ operations << self.mbean_attributes[:op].to_jmx
123
+ self.mbean_attributes[:op] = nil
124
+ end
125
+
126
+ def self.attributes #:nodoc:
127
+ self.mbean_attributes[:attrs] ||= []
128
+ end
129
+
130
+ def self.operations #:nodoc:
131
+ self.mbean_attributes[:ops] ||= []
132
+ end
133
+
134
+ # the <tt>rw_attribute</tt> method is used to declare a JMX read write attribute.
135
+ # see the +JavaSimpleTypes+ module for more information about acceptable types
136
+ # usage:
137
+ # rw_attribute :attribute_name, :string, "Description displayed in a JMX console"
138
+ #
139
+ # The name and type parameters are mandatory
140
+ # The description parameter is optional (defaults to the same value than the env: ruby: No such file or directory
141
+ # name parameter in that case)
142
+ # --
143
+ # methods used to create an attribute. They are modeled on the attrib_accessor
144
+ # patterns of creating getters and setters in ruby
145
+ #++
146
+ def self.rw_attribute(name, type, description=nil)
147
+ description ||= name.to_s
148
+ attributes << JMX::Attribute.new(name, type, description, true, true).to_jmx
149
+ attr_accessor name
150
+ #create a "java" oriented accessor method
151
+ define_method("jmx_get_#{name.to_s.downcase}") do
152
+ begin
153
+ #attempt conversion
154
+ java_type = to_java_type(type)
155
+ value = java_type.new(instance_variable_get("@#{name.to_s}".to_sym))
156
+ rescue
157
+ #otherwise turn it into a java Object type for now.
158
+ value = Java.ruby_to_java(instance_variable_get("@#{name.to_s}".to_sym))
159
+ end
160
+ attribute = javax.management.Attribute.new(name.to_s, value)
161
+ end
162
+
163
+ define_method("jmx_set_#{name.to_s.downcase}") do |value|
164
+ blck = to_ruby(type)
165
+ send "#{name.to_s}=", blck.call(value)
166
+ end
167
+ end
168
+
169
+ # the <tt>r_attribute</tt> method is used to declare a JMX read only attribute.
170
+ # see the +JavaSimpleTypes+ module for more information about acceptable types
171
+ # usage:
172
+ # r_attribute :attribute_name, :string, "Description displayed in a JMX console"
173
+ def self.r_attribute(name, type, description)
174
+ attributes << JMX::Attribute.new(name, type, description, true, false).to_jmx
175
+ attr_reader name
176
+ #create a "java" oriented accessor method
177
+ define_method("jmx_get_#{name.to_s.downcase}") do
178
+ begin
179
+ #attempt conversion
180
+ java_type = to_java_type(type)
181
+ value = java_type.new(instance_variable_get("@#{name.to_s}".to_sym))
182
+ rescue
183
+ #otherwise turn it into a java Object type for now.
184
+ value = Java.ruby_to_java(instance_variable_get("@#{name.to_s}".to_sym))
185
+ end
186
+ attribute = javax.management.Attribute.new(name.to_s, value)
187
+ end
188
+ end
189
+
190
+ # the <tt>w_attribute</tt> method is used to declare a JMX write only attribute.
191
+ # see the +JavaSimpleTypes+ module for more information about acceptable types
192
+ # usage:
193
+ # w_attribute :attribute_name, :string, "Description displayed in a JMX console"
194
+ def self.w_attribute(name, type, description)
195
+ attributes << JMX::Attribute.new(name, type, description, false, true).to_jmx
196
+ attr_writer name
197
+ define_method("jmx_set_#{name.to_s.downcase}") do |value|
198
+ blk = to_ruby(type)
199
+ instance_variable_set("@#{name.to_s}".to_sym, blk.call(value))
200
+ end
201
+ end
202
+
203
+ # Use the operation method to declare the start of an operation
204
+ # It takes as an optional argument the description for the operation
205
+ # Example:
206
+ # operation "Used to start the service"
207
+ # def start
208
+ # end
209
+ #--
210
+ # Last operation wins if more than one
211
+ #++
212
+ def self.operation(description=nil)
213
+ # Wait to error check until method_added so we can know method name
214
+ self.mbean_attributes[:op] = JMX::Operation.new description
215
+ end
216
+
217
+ # Used to declare a parameter (you can declare more than one in succession) that
218
+ # is associated with the currently declared operation.
219
+ # The type is mandatory, the name and description are optional.
220
+ # Example:
221
+ # operation "Used to update the name of a service"
222
+ # parameter :string, "name", "Set the new name of the service"
223
+ # def start(name)
224
+ # ...
225
+ # end
226
+ def self.parameter(type, name=nil, description=nil)
227
+ self.mbean_attributes[:op].parameters << JMX::Parameter.new(type, name, description)
228
+ end
229
+
230
+ # Used to declare the return type of the operation
231
+ # operation "Used to update the name of a service"
232
+ # parameter :string, "name", "Set the new name of the service"
233
+ # returns :void
234
+ # def do_stuff
235
+ # ...
236
+ # end
237
+ def self.returns(type)
238
+ self.mbean_attributes[:op].return_type = type
239
+ end
240
+
241
+ def initialize(description="")
242
+ name = self.class.to_s
243
+ operations = self.class.operations.to_java(MBeanOperationInfo)
244
+ attributes = self.class.attributes.to_java(MBeanAttributeInfo)
245
+ @info = MBeanInfo.new name, description, attributes, nil, operations, nil
246
+ end
247
+
248
+ # Retrieve the value of the requested attribute
249
+ def getAttribute(attribute)
250
+ send("jmx_get_"+attribute.downcase).value
251
+ end
252
+
253
+ def getAttributes(attributes)
254
+ attrs = javax.management.AttributeList.new
255
+ attributes.each { |attribute| attrs.add send("jmx_get_"+attribute.downcase) }
256
+ attrs
257
+ end
258
+
259
+ def getMBeanInfo; @info; end
260
+
261
+ def invoke(actionName, params=nil, signature=nil)
262
+ send(actionName, *params)
263
+ end
264
+
265
+ def setAttribute(attribute)
266
+ send("jmx_set_#{attribute.name.downcase}", attribute.value)
267
+ end
268
+
269
+ def setAttributes(attributes)
270
+ attributes.each { |attribute| setAttribute attribute}
271
+ end
272
+
273
+ def to_s; toString; end
274
+ def inspect; toString; end
275
+ def toString; "#@info.class_name: #@info.description"; end
276
+ end
277
+ end
@@ -0,0 +1,75 @@
1
+ # JConsole module is used by jmx4r unit tests.
2
+ #
3
+ # {jconsole}[http://java.sun.com/j2se/1.5.0/docs/guide/management/jconsole.html]
4
+ # is used as the target remote Java application manageable by JMX
5
+ # (we do not used it for its JMX capability, just because it is a ready to
6
+ # use Java application available with every JDK).
7
+ #
8
+ # Copyright 2007 Jeff Mesnil (http://jmesnil.net)
9
+ module JConsole
10
+
11
+ # Start a new instance of jconsole which is accessible on port 3000.
12
+ # By default, no authentication is required to connect to it.
13
+ #
14
+ # The args hash accepts 3 keys:
15
+ # [:port] the port which will be listens to JMX connections.
16
+ # if the port is 0, jmxrmi port is not published
17
+ # [:pwd_file] the path to the file containing the authentication credentials
18
+ # [:access_file] the path to the file containing the authorization credentials
19
+ #
20
+ # The file path corresponding to :pwd_file must have <b>600 permission</b>
21
+ # (<tt>chmod 600 jmxremote.password</tt>).
22
+ #
23
+ # Both <tt>:pwd_file</tt> and <tt>:access_file+</tt> must be specified to run a secure
24
+ # jconsole (see {JMX password & access files}[http://java.sun.com/j2se/1.5.0/docs/guide/management/agent.html#PasswordAccessFiles])
25
+ def JConsole.start(args={})
26
+ port = args[:port] || 3000
27
+ pwd_file = args[:pwd_file]
28
+ access_file = args[:access_file]
29
+
30
+ cmd =<<-EOCMD.split("\n").join(" ")
31
+ jconsole
32
+ -J-Dcom.sun.management.jmxremote
33
+ EOCMD
34
+
35
+ if port != 0
36
+ cmd << <<-EOCMD.split("\n").join(" ")
37
+ -J-Dcom.sun.management.jmxremote.port=#{port}
38
+ -J-Dcom.sun.management.jmxremote.ssl=false
39
+ -J-Dcom.sun.management.jmxremote.authenticate=#{!pwd_file.nil?}
40
+ EOCMD
41
+
42
+ if pwd_file and access_file
43
+ cmd << " -J-Dcom.sun.management.jmxremote.password.file=#{pwd_file}"
44
+ cmd << " -J-Dcom.sun.management.jmxremote.access.file=#{access_file}"
45
+ end
46
+ end
47
+ Thread.start { system cmd }
48
+ sleep 3
49
+ end
50
+
51
+ # Stop an instance of JConsole (by killing its process)
52
+ #
53
+ # By default, it will kill the process corresponding to an instance JConsole with
54
+ # a port on 3000. Another port can be specified in parameter.
55
+ def JConsole.stop(port=3000)
56
+ ps = "ps a -w -o pid,command | grep -w jconsole"
57
+ ps << " | grep port=#{port}" if port != 0
58
+ ps << " | grep -v grep | grep -v ruby | cut -c -5"
59
+
60
+ jconsole_pid = `#{ps}`
61
+ `kill #{jconsole_pid}` if jconsole_pid != ""
62
+ sleep 1
63
+ end
64
+ end
65
+
66
+ if ARGV.length == 1
67
+ case ARGV[0]
68
+ when "start"
69
+ JConsole::start
70
+ puts "started jconsole"
71
+ when "stop"
72
+ JConsole::stop
73
+ puts "stopped jconsole"
74
+ end
75
+ end