weblogic-jmx4r 0.1.9
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.
- checksums.yaml +7 -0
- data/LICENSE.txt +202 -0
- data/README.rdoc +45 -0
- data/Rakefile +39 -0
- data/examples/class_loading.rb +16 -0
- data/examples/jvm_mngmt.rb +12 -0
- data/examples/logging.rb +26 -0
- data/examples/memory.rb +21 -0
- data/examples/memory_on_many_nodes.rb +44 -0
- data/examples/memory_types.rb +9 -0
- data/examples/ruby_mbean.rb +41 -0
- data/examples/runtime_sysprops.rb +14 -0
- data/examples/weblogic.rb +127 -0
- data/lib/dynamic_mbean.rb +277 -0
- data/lib/jconsole.rb +75 -0
- data/lib/jdk/jdk4.rb +16 -0
- data/lib/jdk/jdk5.rb +34 -0
- data/lib/jdk/jdk6.rb +69 -0
- data/lib/jdk_helper.rb +69 -0
- data/lib/jmx4r.rb +304 -0
- data/lib/jmx4r/version.rb +3 -0
- data/lib/objectname_helper.rb +21 -0
- data/lib/open_data_helper.rb +50 -0
- data/test/tc_attributes.rb +44 -0
- data/test/tc_auth.rb +70 -0
- data/test/tc_composite_data.rb +77 -0
- data/test/tc_connection.rb +92 -0
- data/test/tc_dynamic_mbean.rb +157 -0
- data/test/tc_methods.rb +30 -0
- data/test/tc_multiple_connections.rb +66 -0
- data/test/ts_all.rb +12 -0
- metadata +81 -0
@@ -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
|
data/lib/jconsole.rb
ADDED
@@ -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
|