rlogic 0.1.0

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/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ *.iws
6
+ *~
data/.rakeTasks ADDED
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <Settings><!--This file was automatically generated by Ruby plugin.
3
+ You are allowed to:
4
+ 1. Remove rake task
5
+ 2. Add existing rake tasks
6
+ To add existing rake tasks automatically delete this file and reload the project.
7
+ --><RakeGroup description="" fullCmd="" taksId="rake"><RakeTask description="Build rlogic-0.0.1.gem into the pkg directory" fullCmd="build" taksId="build" /><RakeTask description="Build and install rlogic-0.0.1.gem into system gems" fullCmd="install" taksId="install" /><RakeTask description="Create tag v0.0.1 and build and push rlogic-0.0.1.gem to Rubygems" fullCmd="release" taksId="release" /></RakeGroup></Settings>
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in rlogic.gemspec
4
+ gemspec
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/wlst ADDED
@@ -0,0 +1,175 @@
1
+ #!/usr/bin/env ruby
2
+ # The MIT License
3
+ #
4
+ # Copyright (c) 2012 Marcelo Guimarães <ataxexe@gmail.com>
5
+ #
6
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ # of this software and associated documentation files (the "Software"), to deal
8
+ # in the Software without restriction, including without limitation the rights
9
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ # copies of the Software, and to permit persons to whom the Software is
11
+ # furnished to do so, subject to the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be included in
14
+ # all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ # THE SOFTWARE.
23
+
24
+ require 'optparse'
25
+ require 'logger'
26
+ require 'yaml'
27
+ require 'fileutils'
28
+ require_relative '../lib/rlogic'
29
+ require 'tmpdir'
30
+
31
+ weblogic = {}
32
+ @conf_dir = File.expand_path "~/.rlogic"
33
+ @scripts_dir = File.join @conf_dir, "/scripts"
34
+ @tmp_dir = File.join Dir.tmpdir, "rlogic"
35
+ FileUtils::mkdir_p @conf_dir
36
+ FileUtils::mkdir_p @scripts_dir
37
+ FileUtils::mkdir_p @tmp_dir
38
+
39
+ @script_file = "#{@tmp_dir}/wlst.py"
40
+ @scrtip_log = "#{@tmp_dir}/out.log"
41
+ @scrtip_output = "#{@tmp_dir}/out"
42
+ servers_file = "#{@conf_dir}/servers.yaml"
43
+ @servers_file = File.expand_path(servers_file)
44
+ save = false
45
+ weblogic[:wl_home] = (ENV["WL_HOME"] or Dir.pwd)
46
+
47
+ invokes = {}
48
+ mappings = {}
49
+
50
+ resolver = WLST::ScriptResolver::new :scripts_dir => @scripts_dir
51
+
52
+ def load_yaml
53
+ return Hash::new unless File.exist?(@servers_file)
54
+ config = YAML::load_file(@servers_file)
55
+ end
56
+
57
+ opts = OptionParser::new
58
+ opts.on('--home PATH', 'Defines the WL_HOME variable') do |home|
59
+ weblogic[:wl_home] = home
60
+ end
61
+ opts.on('--host HOST', 'Defines the Weblogic host') do |host|
62
+ weblogic[:host] = host
63
+ end
64
+ opts.on('--port PORT', 'Defines the Weblogic port') do |port|
65
+ weblogic[:port] = port
66
+ end
67
+ opts.on('--connect SERVER_NAME',
68
+ "Uses a configured server in #{servers_file}") do |server|
69
+ config = load_yaml[server]
70
+ abort "No configuration for #{server}" unless config
71
+ config.each do |key, value|
72
+ weblogic[key.to_sym] = value
73
+ end
74
+ end
75
+ opts.on('--save SERVER_NAME', "Saves the server configuration in #{servers_file}") do |server|
76
+ save = (server or 'default')
77
+ end
78
+
79
+ opts.on('--user USER', 'Defines the Weblogic User') do |user|
80
+ weblogic[:user] = user
81
+ end
82
+ opts.on('--password PASSWORD', 'Defines the Weblogic Password') do |password|
83
+ weblogic[:password] = password
84
+ end
85
+ opts.on('--print', 'Prints the script output') do
86
+ @print = true
87
+ end
88
+
89
+ opts.on('--list', 'Lists available scripts') do
90
+ puts "Available templates:"
91
+ resolver.scripts.each do |key, script|
92
+ puts "\t#{key}"
93
+ end
94
+ exit 0
95
+ end
96
+
97
+ opts.on('--info SCRIPT', 'Shows info for selected script') do |script_key|
98
+ script = resolver.scripts[script_key]
99
+ raise "Script not found" unless script
100
+ puts script[:info]
101
+ script[:definition].each do |param, defs|
102
+ puts " - #{param} : #{defs['description']}"
103
+ end
104
+ exit 0
105
+ end
106
+ opts.on('--monitor', 'Runs the script as a monitor') do
107
+ resolver.monitor = true
108
+ end
109
+
110
+ opts.on("-h", "--help", "Shows this help message") do
111
+ puts opts; exit
112
+ end
113
+ opts.parse!(ARGV)
114
+
115
+ if save
116
+ config = load_yaml
117
+ config[save] ||= {}
118
+ server_config = config[save]
119
+ weblogic.delete :wl_home
120
+ weblogic.each do |key, value|
121
+ server_config[key.to_s] = value
122
+ end
123
+ FileUtils::touch @servers_file
124
+ f = File.open(@servers_file, 'w')
125
+ YAML::dump(config, f)
126
+ f.close
127
+ puts "Configuration saved!"
128
+ exit 0
129
+ end
130
+
131
+ @command = WLST::Command::new
132
+ @command.redirect @scrtip_log, 'false'
133
+
134
+ connect = (weblogic[:user] and weblogic[:password] and weblogic[:host] and weblogic[:port])
135
+
136
+ if connect
137
+ @command.connect(weblogic[:user], weblogic[:password], "t3://#{weblogic[:host]}:#{weblogic[:port]}")
138
+ end
139
+
140
+ invokes.each do |id, args|
141
+ mappings[id]::new(@command).execute *args
142
+ end
143
+
144
+ unless ARGV.empty?
145
+ script = ARGV.delete_at 0
146
+ if resolver.has_script? script
147
+ args = ARGV
148
+ @command << resolver.create(
149
+ :script => script,
150
+ :from => :command_line,
151
+ :using => args,
152
+ :for => weblogic
153
+ )
154
+ else
155
+ if ARGV.empty?
156
+ @command.send script
157
+ else
158
+ ARGV.each { |arg| @command.send script, *(arg.split /,/) }
159
+ end
160
+ end
161
+ end
162
+
163
+ if connect
164
+ @command.disconnect
165
+ end
166
+
167
+ if @print
168
+ puts @command.to_s
169
+ else
170
+ @command.to_f @script_file
171
+ runner = WLST::Runner::new weblogic[:wl_home]
172
+ result = runner.run @script_file
173
+ puts result
174
+ File.open(@scrtip_output, 'w') { |f| f.write result }
175
+ end
@@ -0,0 +1,25 @@
1
+ # The MIT License
2
+ #
3
+ # Copyright (c) 2012 Marcelo Guimarães <ataxexe@gmail.com>
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+
23
+ module Rlogic
24
+ VERSION = "0.1.0"
25
+ end
data/lib/rlogic.rb ADDED
@@ -0,0 +1,54 @@
1
+ # The MIT License
2
+ #
3
+ # Copyright (c) 2012 Marcelo Guimarães <ataxexe@gmail.com>
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+
23
+ require_relative "rlogic/version"
24
+ require_relative "wlst/wlst"
25
+
26
+ if RUBY_PLATFORM['linux']
27
+ module WLST
28
+ class Runner
29
+ def command file
30
+ ". #{@wl_home}/server/bin/setWLSEnv.sh && java weblogic.WLST #{file}"
31
+ end
32
+ end
33
+ class ScriptResolver
34
+ def includes
35
+ ["include.py", "include_linux.py"]
36
+ end
37
+ end
38
+ end
39
+ elsif RUBY_PLATFORM['mingw'] #Windows
40
+ module WLST
41
+ class Runner
42
+ def command file
43
+ "#{@wl_home}/server/bin/setWLSEnv.cmd && java weblogic.WLST #{file}"
44
+ end
45
+ end
46
+ class ScriptResolver
47
+ def includes
48
+ ["include.py", "include_windows.py"]
49
+ end
50
+ end
51
+ end
52
+ else
53
+ raise "Platform #{RUBY_PLATFORM} not supported"
54
+ end
@@ -0,0 +1,112 @@
1
+ import sys
2
+
3
+ class ConsoleTheme:
4
+ def __init__(self,
5
+ title='1;40;33m',
6
+ header='1;40;34m',
7
+ line='1;40;37m',
8
+ good='2;40;32m',
9
+ bad='2;40;31m',
10
+ normal='2;40;37m',
11
+ warning='2;40;36m'):
12
+ self.titleColor = title
13
+ self.headerColor = header
14
+ self.lineColor = line
15
+ self.goodColor = good
16
+ self.badColor = bad
17
+ self.normalColor = normal
18
+ self.warningColor = warning
19
+
20
+ def title(self, obj):
21
+ return colorize(self.titleColor, obj)
22
+
23
+
24
+ def header(self, obj):
25
+ return colorize(self.headerColor, obj)
26
+
27
+
28
+ def normal(self, obj):
29
+ return colorize(self.normalColor, obj)
30
+
31
+
32
+ def good(self, obj):
33
+ return colorize(self.goodColor, obj)
34
+
35
+
36
+ def bad(self, obj):
37
+ return colorize(self.badColor, obj)
38
+
39
+
40
+ def warn(self, obj):
41
+ return colorize(self.warningColor, obj)
42
+
43
+
44
+ def line(self, obj):
45
+ return str(obj)
46
+
47
+
48
+ class TableBuilder:
49
+ def __init__(self, theme=ConsoleTheme()):
50
+ self.data = []
51
+ self.theme = theme
52
+
53
+ def title(self, title):
54
+ self.titleText = self.theme.title(title)
55
+
56
+ def header(self, header):
57
+ self.data.append(self.theme.header(header))
58
+
59
+ def bad(self, row):
60
+ self.data.append(self.theme.bad(row))
61
+
62
+ def good(self, row):
63
+ self.data.append(self.theme.good(row))
64
+
65
+ def warn(self, row):
66
+ self.data.append(self.theme.warn(row))
67
+
68
+ def normal(self, row):
69
+ self.data.append(self.theme.normal(row))
70
+
71
+ def printData(self):
72
+ print self.titleText
73
+ pprint_table(sys.stdout, self.data)
74
+
75
+
76
+ def colorize(color, obj):
77
+ if type(obj) is list:
78
+ result = []
79
+ for o in obj:
80
+ result.append(colorize(color, o))
81
+ return result
82
+ else:
83
+ return '\033[' + color + str(obj) + '\033[0m'
84
+
85
+
86
+ def getRunningServers():
87
+ domainConfig()
88
+ return cmo.getServers()
89
+
90
+
91
+ def format_num(num):
92
+ return str(num)
93
+
94
+
95
+ def get_max_width(table, index):
96
+ return max([len(format_num(row[index])) for row in table])
97
+
98
+
99
+ def pprint_table(out, table):
100
+ col_paddings = []
101
+
102
+ for i in range(len(table[0])):
103
+ col_paddings.append(get_max_width(table, i))
104
+
105
+ for row in table:
106
+ # left col
107
+ print >> out, row[0].ljust(col_paddings[0] + 1),
108
+ # rest of the cols
109
+ for i in range(1, len(row)):
110
+ col = format_num(row[i]).rjust(col_paddings[i] + 2)
111
+ print >> out, col,
112
+ print >> out
File without changes
@@ -0,0 +1,8 @@
1
+ def colorize(color, obj):
2
+ if type(obj) is list:
3
+ result = []
4
+ for o in obj:
5
+ result.append(colorize(color, o))
6
+ return result
7
+ else:
8
+ return str(obj) #make windows terminal colors
@@ -0,0 +1 @@
1
+ Prints information about running servers
@@ -0,0 +1,99 @@
1
+ threshold = args['threshold']
2
+
3
+ def getServerNames():
4
+ if not len(args["servers"]):
5
+ serverNames = []
6
+ servers = getRunningServers()
7
+ for server in servers:
8
+ serverNames.append(server.getName())
9
+ return serverNames
10
+ else:
11
+ return args["servers"]
12
+
13
+
14
+ def monitorConnectionPool():
15
+ table = TableBuilder()
16
+ pools = args['pools']
17
+ poolrtlist = adminHome.getMBeansByType('JDBCConnectionPoolRuntime')
18
+ table.title('JDBC Connection Pools')
19
+ table.header(['Pool', 'Max', 'Active', 'High', 'Wait Time', 'Waiting', 'State'])
20
+ for poolRT in poolrtlist:
21
+ if len(pools) > 0 and not poolRT.getName() in pools:
22
+ continue
23
+ try:
24
+ name = poolRT.getName()
25
+ maxCapacity = int(poolRT.getAttribute("MaxCapacity"))
26
+ activeCurrent = int(poolRT.getAttribute("ActiveConnectionsCurrentCount"))
27
+ activeHighCount = int(poolRT.getAttribute("ActiveConnectionsHighCount"))
28
+ waitSecs = int(poolRT.getAttribute("WaitSecondsHighCount"))
29
+ waitingCount = poolRT.getAttribute("WaitingForConnectionCurrentCount")
30
+ state = poolRT.getAttribute('State')
31
+ row = [name, maxCapacity, activeCurrent, activeHighCount, waitSecs, waitingCount,
32
+ state]
33
+ if (maxCapacity - activeCurrent) / float(maxCapacity) < threshold:
34
+ table.bad(row)
35
+ else:
36
+ table.good(row)
37
+ except:
38
+ continue
39
+ table.printData()
40
+
41
+
42
+ def monitorJVM():
43
+ table = TableBuilder()
44
+ serverNames = getServerNames()
45
+ domainRuntime()
46
+
47
+ table.title('JVM Runtime')
48
+ table.header(["Server", "Total", "Used", "Free"])
49
+ for name in serverNames:
50
+ try:
51
+ cd("/ServerRuntimes/" + name + "/JVMRuntime/" + name)
52
+ freejvm = float(get('HeapFreeCurrent')) / (1024 * 1024)
53
+ totaljvm = float(get('HeapSizeCurrent')) / (1024 * 1024)
54
+ usedjvm = (totaljvm - freejvm)
55
+ row = [name,
56
+ str(int(totaljvm)) + " M",
57
+ str(int(usedjvm)) + " M",
58
+ str(int(freejvm)) + " M"]
59
+ if freejvm / totaljvm < threshold:
60
+ table.bad(row)
61
+ else:
62
+ table.good(row)
63
+ except WLSTException, e:
64
+ continue
65
+ table.printData()
66
+
67
+
68
+ def monitorThreadPool():
69
+ table = TableBuilder()
70
+ serverNames = getServerNames()
71
+ domainRuntime()
72
+ table.title('Thread Pool')
73
+ table.header(['Server', 'Hogging', 'Idle', 'Total', 'Pending Req', 'Throughput'])
74
+ for name in serverNames:
75
+ try:
76
+ cd("/ServerRuntimes/" + name + "/ThreadPoolRuntime/ThreadPoolRuntime")
77
+ hoggingThreads = cmo.getHoggingThreadCount()
78
+ totalThreads = cmo.getExecuteThreadTotalCount()
79
+ idleThreads = cmo.getExecuteThreadIdleCount()
80
+ pendingRequests = cmo.getPendingUserRequestCount()
81
+ throughput = float(cmo.getThroughput())
82
+ data = [name, hoggingThreads, idleThreads, totalThreads, pendingRequests,
83
+ round(throughput,4)]
84
+ if float(idleThreads) / totalThreads < threshold:
85
+ table.bad(data)
86
+ else:
87
+ table.good(data)
88
+ except WLSTException, e:
89
+ continue
90
+ table.printData()
91
+
92
+ if args['jvm'] or args['all']:
93
+ monitorJVM()
94
+ print ''
95
+ if args['pool'] or args['all']:
96
+ monitorConnectionPool()
97
+ print ''
98
+ if args['thread'] or args['all']:
99
+ monitorThreadPool()
@@ -0,0 +1,28 @@
1
+ all:
2
+ description: prints all available status
3
+ type: boolean
4
+ default: false
5
+ jvm:
6
+ description: prints jvm status
7
+ type: boolean
8
+ default: false
9
+ pool:
10
+ description: prints connection pool status
11
+ type: boolean
12
+ default: false
13
+ thread:
14
+ description: prints thread pool status
15
+ type: boolean
16
+ default: false
17
+ pools:
18
+ description: pool names (uses all by default)
19
+ type: array
20
+ default: []
21
+ servers:
22
+ description: servers to list (uses all by default)
23
+ type: array
24
+ default: []
25
+ threshold:
26
+ description: minimun percentage of free resources
27
+ type: float
28
+ default: 0.15