pmux-logview 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. data/Gemfile +4 -0
  2. data/LICENSE.txt +22 -0
  3. data/Makefile +18 -0
  4. data/README.md +113 -0
  5. data/Rakefile +4 -0
  6. data/bin/pmux-logview +4 -0
  7. data/conf/config.ru +15 -0
  8. data/conf/password +5 -0
  9. data/conf/pmux-logview.conf +12 -0
  10. data/lib/pmux-logview.rb +11 -0
  11. data/lib/pmux-logview/application.rb +69 -0
  12. data/lib/pmux-logview/auth_helper.rb +60 -0
  13. data/lib/pmux-logview/controller.rb +141 -0
  14. data/lib/pmux-logview/log_parser.rb +368 -0
  15. data/lib/pmux-logview/logger_wrapper.rb +129 -0
  16. data/lib/pmux-logview/model.rb +21 -0
  17. data/lib/pmux-logview/static/css/images/animated-overlay.gif +0 -0
  18. data/lib/pmux-logview/static/css/images/ui-bg_diagonals-thick_90_eeeeee_40x40.png +0 -0
  19. data/lib/pmux-logview/static/css/images/ui-bg_flat_15_cd0a0a_40x100.png +0 -0
  20. data/lib/pmux-logview/static/css/images/ui-bg_glass_100_e4f1fb_1x400.png +0 -0
  21. data/lib/pmux-logview/static/css/images/ui-bg_glass_50_3baae3_1x400.png +0 -0
  22. data/lib/pmux-logview/static/css/images/ui-bg_glass_80_d7ebf9_1x400.png +0 -0
  23. data/lib/pmux-logview/static/css/images/ui-bg_highlight-hard_100_f2f5f7_1x100.png +0 -0
  24. data/lib/pmux-logview/static/css/images/ui-bg_highlight-hard_70_000000_1x100.png +0 -0
  25. data/lib/pmux-logview/static/css/images/ui-bg_highlight-soft_100_deedf7_1x100.png +0 -0
  26. data/lib/pmux-logview/static/css/images/ui-bg_highlight-soft_25_ffef8f_1x100.png +0 -0
  27. data/lib/pmux-logview/static/css/images/ui-icons_2694e8_256x240.png +0 -0
  28. data/lib/pmux-logview/static/css/images/ui-icons_2e83ff_256x240.png +0 -0
  29. data/lib/pmux-logview/static/css/images/ui-icons_3d80b3_256x240.png +0 -0
  30. data/lib/pmux-logview/static/css/images/ui-icons_72a7cf_256x240.png +0 -0
  31. data/lib/pmux-logview/static/css/images/ui-icons_ffffff_256x240.png +0 -0
  32. data/lib/pmux-logview/static/css/jquery-ui-1.10.0.css +1186 -0
  33. data/lib/pmux-logview/static/css/jquery.dataTables.css +221 -0
  34. data/lib/pmux-logview/static/css/normalize.css +396 -0
  35. data/lib/pmux-logview/static/css/pmux-logview.css +161 -0
  36. data/lib/pmux-logview/static/css/tchart.css +124 -0
  37. data/lib/pmux-logview/static/font/7TssRTXcaLr8beqDiv5lkQ.woff +0 -0
  38. data/lib/pmux-logview/static/images/back_disabled.png +0 -0
  39. data/lib/pmux-logview/static/images/back_enabled.png +0 -0
  40. data/lib/pmux-logview/static/images/back_enabled_hover.png +0 -0
  41. data/lib/pmux-logview/static/images/forward_disabled.png +0 -0
  42. data/lib/pmux-logview/static/images/forward_enabled.png +0 -0
  43. data/lib/pmux-logview/static/images/forward_enabled_hover.png +0 -0
  44. data/lib/pmux-logview/static/images/sort_asc.png +0 -0
  45. data/lib/pmux-logview/static/images/sort_asc_disabled.png +0 -0
  46. data/lib/pmux-logview/static/images/sort_both.png +0 -0
  47. data/lib/pmux-logview/static/images/sort_desc.png +0 -0
  48. data/lib/pmux-logview/static/images/sort_desc_disabled.png +0 -0
  49. data/lib/pmux-logview/static/js/d3.v3.min.js +4 -0
  50. data/lib/pmux-logview/static/js/jquery-1.9.1.js +9597 -0
  51. data/lib/pmux-logview/static/js/jquery-ui-1.10.0.js +14883 -0
  52. data/lib/pmux-logview/static/js/jquery.activity-indicator-1.0.0.min.js +10 -0
  53. data/lib/pmux-logview/static/js/jquery.dataTables.min.js +157 -0
  54. data/lib/pmux-logview/static/js/pmux-logview-base.js +102 -0
  55. data/lib/pmux-logview/static/js/pmux-logview-detail.js +181 -0
  56. data/lib/pmux-logview/static/js/pmux-logview-index.js +324 -0
  57. data/lib/pmux-logview/static/js/tchart.js +2125 -0
  58. data/lib/pmux-logview/version.rb +5 -0
  59. data/lib/pmux-logview/views/detail.erb +58 -0
  60. data/lib/pmux-logview/views/index.erb +97 -0
  61. data/pmux-logview.gemspec +27 -0
  62. data/rpm/Makefile +20 -0
  63. data/rpm/pmux-logview +111 -0
  64. data/rpm/pmux-logview.spec +65 -0
  65. metadata +224 -0
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in pmux-logview.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 kakine
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Makefile ADDED
@@ -0,0 +1,18 @@
1
+ RUBY_VERID?=default
2
+
3
+ default: build
4
+
5
+ build: clean
6
+ rake build
7
+
8
+ install: clean
9
+ rake install
10
+
11
+ rpmbuild: clean
12
+ cd rpm && make clean
13
+ rake build
14
+ cd rpm && make RUBY_VERID=$(RUBY_VERID)
15
+
16
+ clean:
17
+ cd rpm && make clean
18
+ rm -rf pkg
data/README.md ADDED
@@ -0,0 +1,113 @@
1
+ # Pmux::Logview
2
+
3
+ pmux log viwer
4
+
5
+ ## Requirements
6
+
7
+ * ruby
8
+ * pmux
9
+ * gflocator
10
+ * sinatra
11
+ * json
12
+
13
+ ## Installation
14
+
15
+ ### Install dependency programs
16
+
17
+ gem install gflocator
18
+ gem install pmux
19
+ gem install sinatra
20
+ gem install json
21
+
22
+ ### Install pmux-logview
23
+
24
+ $ gem install pmux-logview
25
+
26
+ ## Usage
27
+
28
+ pmux-logview [options]
29
+ -c, --config [config_file_path]
30
+ -F, --foreground
31
+
32
+
33
+ ## configuration
34
+
35
+ ### Stand alone
36
+ * pmux-logview configuration (default path = /etc/pmux-logview/pmux-logview.conf)
37
+ * yaml format file
38
+
39
+ ```lang
40
+ ---
41
+ host: 0.0.0.0
42
+ port: 80
43
+ default_user: "pmux"
44
+ use_basic_auth: true
45
+ password_file_path: "/etc/pmux-logview/password"
46
+ cache_dir_path: "/var/tmp/pmux-logview"
47
+ log_dir_path: "/var/log/pmux-logview"
48
+ log_level: "info"
49
+ use_syslog: false
50
+ syslog_facility: "user"
51
+ ```
52
+
53
+ * basic auth configuration (default path = /etc/pmux-logview/password)
54
+ * yaml format file
55
+
56
+ ```lang
57
+ ---
58
+ user1:
59
+ pass: pass1
60
+ user2:
61
+ pass: pass2
62
+ ```
63
+
64
+ ### Rack appliction
65
+ * config.ru
66
+
67
+ ```lang
68
+ require 'pmux-logview'
69
+ configure do
70
+ # something
71
+ end
72
+ Pmux::LogView::Controller.setup({ "default_user" => "pmux",
73
+ "use_basic_auth" => true,
74
+ "password_file_path" => "/etc/pmux-logview/password",
75
+ "cache_dir_path" => "/var/tmp/pmux-logview",
76
+ "log_dir_path" => "/var/log/pmux-logview",
77
+ "log_level" => "info",
78
+ "use_syslog" => true,
79
+ "syslog_facility" => "user" })
80
+ run Pmux::LogView::Controller
81
+ ```
82
+
83
+ ## Package createting
84
+
85
+ * create gem
86
+
87
+ ```lang
88
+ $ make
89
+ ```
90
+
91
+ * install
92
+
93
+ ```lang
94
+ # make install
95
+ or
96
+ # gem install pkg/pmux-logview-*.gem
97
+ ```
98
+
99
+ * create rpm
100
+
101
+ ```lang
102
+ $ make rpmbuild
103
+ ```
104
+
105
+ * install rpm
106
+
107
+ ```lang
108
+ $ rpm -ivh rpm/RPMS/noarch/rubygems-pmux-logview-*.noarch.rpm
109
+ ```
110
+
111
+ ## Behaiver
112
+ - search log file in home directory of pmux user
113
+ - save cache file in cache directory path
data/Rakefile ADDED
@@ -0,0 +1,4 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new
data/bin/pmux-logview ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require 'pmux-logview'
3
+ app = Pmux::LogView::Application.new()
4
+ app.run()
data/conf/config.ru ADDED
@@ -0,0 +1,15 @@
1
+ require 'pmux-logview'
2
+
3
+ configure do
4
+ # something
5
+ end
6
+
7
+ Pmux::LogView::Controller.setup({ "default_user" => "pmux",
8
+ "use_basic_auth" => true,
9
+ "password_file_path" => "/etc/pmux-logview/password",
10
+ "cache_dir_path" => "/var/tmp/pmux-logview",
11
+ "log_dir_path" => "/var/log/pmux-logview",
12
+ "log_level" => "info",
13
+ "use_syslog" => true,
14
+ "syslog_facility" => "user" })
15
+ run Pmux::LogView::Controller
data/conf/password ADDED
@@ -0,0 +1,5 @@
1
+ ---
2
+ pmux-user1:
3
+ pass: pass1
4
+ pmux-user2:
5
+ pass: pass2
@@ -0,0 +1,12 @@
1
+ ---
2
+ host: 0.0.0.0
3
+ port: 28080
4
+ pidfile: /var/run/pmux-logview.pid
5
+ default_user: pmux
6
+ use_basic_auth: true
7
+ password_file_path: /etc/pmux-logview/password
8
+ cache_dir_path: /var/tmp/pmux-logview
9
+ log_dir_path: /var/log/pmux-logview
10
+ log_level: info
11
+ use_syslog: true
12
+ syslog_facility: user
@@ -0,0 +1,11 @@
1
+ File.umask 0022
2
+ ENV['LC_ALL'] = 'C'
3
+ Encoding.default_external = 'ascii-8bit' if RUBY_VERSION > '1.9'
4
+
5
+ require "pmux-logview/logger_wrapper"
6
+ require "pmux-logview/application"
7
+ require "pmux-logview/auth_helper"
8
+ require "pmux-logview/log_parser"
9
+ require "pmux-logview/model"
10
+ require "pmux-logview/controller"
11
+ require "pmux-logview/version"
@@ -0,0 +1,69 @@
1
+ require 'yaml'
2
+ require 'optparse'
3
+ require 'fileutils'
4
+ require 'sinatra'
5
+
6
+ module Pmux
7
+ module LogView
8
+ class Application
9
+ def initialize
10
+ @config = nil
11
+ @foreground = false
12
+ @config_file_path = "/etc/pmux-logview/pmux-logview.conf"
13
+ @pidfile = "/var/run/pmux-logview.pid"
14
+ @host = "0.0.0.0"
15
+ @port = 28080
16
+ end
17
+
18
+ def parse_args
19
+ OptionParser.new do |opt|
20
+ opt.on('-c [config_file_path]', '--config [config_file_path]') {|v| @config_file_path = v}
21
+ opt.on('-F', '--foreground') {|v| @foreground = true}
22
+ opt.parse!(ARGV)
23
+ end
24
+ end
25
+
26
+ def load_config
27
+ @config = {} if @config.nil?
28
+ return false if @config_file_path.nil? || @config_file_path == ""
29
+ begin
30
+ new_config = YAML.load_file(@config_file_path)
31
+ rescue Errno::ENOENT
32
+ puts "not found password file (#{@config_file_path})"
33
+ rescue Errno::EACCES
34
+ puts "can not access password file (#{@config_file_path})"
35
+ rescue Exception => e
36
+ puts "error occurred in password loading: #{e}"
37
+ puts e.backtrace.join("\n")
38
+ end
39
+ @config = new_config
40
+ end
41
+
42
+ def daemonize
43
+ if !@foreground
44
+ exit!(0) if Process.fork
45
+ Process.setsid
46
+ exit!(0) if Process.fork
47
+ STDIN.reopen("/dev/null", "r")
48
+ STDOUT.reopen("/dev/null", "w")
49
+ STDERR.reopen("/dev/null", "w")
50
+ end
51
+ end
52
+
53
+ def run
54
+ initialize()
55
+ parse_args()
56
+ daemonize()
57
+ load_config()
58
+ @config["foreground"] = @foreground
59
+ @pidfile = @config["pidfile"] if @config["pidfile"]
60
+ open(@pidfile, 'w') {|f| f << Process.pid } if @pidfile
61
+ @host = @config["host"] if @config["host"]
62
+ @port = @config["port"] if @config["port"]
63
+ Controller.setup(@config)
64
+ Controller.run! :host =>@host , :port => @port
65
+ end
66
+ end
67
+ end
68
+ end
69
+
@@ -0,0 +1,60 @@
1
+ require 'sinatra'
2
+ require 'sinatra/base'
3
+ require 'pmux-logview/logger_wrapper'
4
+
5
+ module Pmux
6
+ module LogView
7
+ module AuthHelper
8
+ def self.init password_file_path
9
+ @logger = LoggerWrapper.instance()
10
+ self.load_config(password_file_path) if @auth_db.nil?
11
+ end
12
+
13
+ def self.update password_file_path
14
+ self.load_config(password_file_path)
15
+ end
16
+
17
+ def self.load_config password_file_path
18
+ @auth_db = {} if @auth_db.nil?
19
+ begin
20
+ stat = File.stat(password_file_path)
21
+ mode = "%o" % stat.mode
22
+ if mode[-3, 3] != "600"
23
+ @logger.warn("password file permission is not 600 (#{password_file_path})")
24
+ end
25
+ new_auth_db = YAML.load_file(password_file_path)
26
+ rescue Errno::ENOENT
27
+ @logger.warn("not found password file (#{password_file_path})")
28
+ rescue Errno::EACCES
29
+ @logger.warn("can not access password file (#{password_file_path})")
30
+ rescue Exception => e
31
+ @logger.warn("error occurred in password loading: #{e}")
32
+ @logger.warn(e.backtrace.join("\n"))
33
+ end
34
+ @auth_db = new_auth_db
35
+ end
36
+
37
+ def self.authenticated request, auth
38
+ auth ||= Rack::Auth::Basic::Request.new(request.env)
39
+ if auth.provided? && auth.basic? && auth.credentials
40
+ user, pass = auth.credentials
41
+ if @auth_db && @auth_db[user] && @auth_db[user]["pass"] && @auth_db[user]["pass"] == pass
42
+ return user
43
+ end
44
+ end
45
+ return nil
46
+ end
47
+
48
+ def self.check_auth! request, response, auth, password_file_path
49
+ user = self.authenticated(request, auth)
50
+ if user.nil?
51
+ response['WWW-Authenticate'] = %(Basic realm="Restricted Area")
52
+ throw(:halt, [401, "Unauthorized"])
53
+ end
54
+ return user
55
+ end
56
+ end
57
+
58
+ helpers AuthHelper
59
+ end
60
+ end
@@ -0,0 +1,141 @@
1
+ require 'sinatra'
2
+ require 'sinatra/base'
3
+ require 'json'
4
+ require 'erb'
5
+ require 'fileutils'
6
+ require 'logger'
7
+
8
+ module Pmux
9
+ module LogView
10
+ class Controller < Sinatra::Base
11
+ @@initialized = false
12
+ @@foreground = false
13
+ @@cache_dir_path = "/var/tmp/pmux-logview"
14
+ @@password_file_path = "/etc/pmux-logview/password"
15
+ @@log_dir_path = "/var/log/pmux-logview"
16
+ @@log_filename = "./pmux-logview.log"
17
+ @@log_level = "info"
18
+ @@syslog_facility = "daemon"
19
+ @@use_syslog = false
20
+ @@use_basic_auth = true
21
+ @@default_user = "pmux"
22
+ @@model = nil
23
+ @@logger = nil
24
+ @user = nil
25
+ set :public_folder, File.dirname(__FILE__) + '/static'
26
+ set :views, File.dirname(__FILE__) + "/views"
27
+ enable :logging
28
+ helpers AuthHelper
29
+
30
+ def Controller.setup(args)
31
+ args.each_key{|key|
32
+ case key
33
+ when "foreground"
34
+ @@foreground = args[key]
35
+ when "cache_dir_path"
36
+ @@cache_dir_path = args[key]
37
+ when "use_basic_auth"
38
+ @@use_basic_auth = args[key]
39
+ when "password_file_path"
40
+ @@password_file_path = args[key]
41
+ when "log_dir_path"
42
+ @@log_dir_path = args[key]
43
+ when "log_level"
44
+ @@log_level = args[key]
45
+ when "use_syslog"
46
+ @@use_syslog = args[key]
47
+ when "syslog_facility"
48
+ @@syslog_facility = args[key]
49
+ when "default_user"
50
+ @@default_user = args[key]
51
+ end
52
+ }
53
+ log_file_path = File.expand_path([@@log_dir_path, @@log_filename].join(File::SEPARATOR))
54
+ @@logger.foreground(@@foreground)
55
+ @@logger.open(log_file_path, @@log_level, @@use_syslog, @@syslog_facility)
56
+ AuthHelper.update(@@password_file_path)
57
+ @@model = Model.new(@@cache_dir_path)
58
+ end
59
+
60
+ configure do
61
+ log_file_path = File.expand_path([@@log_dir_path, @@log_filename].join(File::SEPARATOR))
62
+ @@logger = LoggerWrapper.instance()
63
+ @@logger.init()
64
+ @@logger.open(log_file_path, @@log_level, @@use_syslog, @@syslog_facility)
65
+ use Rack::CommonLogger, @@logger
66
+ AuthHelper.init(@@password_file_path)
67
+ @@model = Model.new(@@cache_dir_path)
68
+ end
69
+
70
+ def logger
71
+ return env['user.logger'] || env['rack.logger']
72
+ end
73
+
74
+ get '/' do
75
+ @user = @@default_user if @user.nil?
76
+ @user = AuthHelper.check_auth!(request, response, @auth, @@password_file_path) if @@use_basic_auth
77
+ @@logger.info("access user #{@user}")
78
+ erb :index
79
+ end
80
+
81
+ get '/detail' do
82
+ @user = @@default_user if @user.nil?
83
+ @user = AuthHelper.check_auth!(request, response, @auth, @@password_file_path) if @@use_basic_auth
84
+ @@logger.info("access user #{@user}")
85
+ @job_id = params[:job_id]
86
+ erb :detail
87
+ end
88
+
89
+ get '/log/job' do
90
+ @user = @@default_user if @user.nil?
91
+ @user = AuthHelper.check_auth!(request, response, @auth, @@password_file_path) if @@use_basic_auth
92
+ @@logger.info("access user #{@user}")
93
+ data = {}
94
+ validations = {
95
+ "sort_key" => { "default" => "start_time", "type" => String, "values" => [ "job_id", "mapper", "start_time", "end_time", "elapsed_time"] },
96
+ "sort_order" => { "default" => "desc", "type" => String, "values" => [ "asc", "desc" ] },
97
+ "type" => { "default" => "archive", "type" => String, "values" => [ "archive", "update" ] },
98
+ "nitems" => { "default" => 20, "type" => Integer, "values" => nil },
99
+ "page" => { "default" => 0, "type" => Integer, "values" => nil },
100
+ "jobs_cookie" => { "default" => 0, "type" => Integer, "values" => nil },
101
+ }
102
+ validations.each_key{|key|
103
+ if params.key?(key)
104
+ if (validations[key]["type"] == Integer)
105
+ data[key] = params[key].to_i
106
+ else
107
+ data[key] = params[key]
108
+ end
109
+ if (validations[key]["type"] == Integer)
110
+ data[key] = validations[key]["default"] if data[key] <= 0
111
+ else
112
+ data[key] = validations[key]["default"] if !data[key].kind_of?(validations[key]["type"])
113
+ end
114
+ data[key] = validations[key]["default"] if !validations[key]["values"].nil? && !validations[key]["values"].include?(data[key])
115
+ else
116
+ data[key] = validations[key]["default"]
117
+ end
118
+ }
119
+ content_type :json
120
+ return JSON.generate(@@model.get_log_job(@user, data))
121
+ end
122
+
123
+ get '/log/job/:job_id/detail' do
124
+ @user = @@default_user if @user.nil?
125
+ @user = AuthHelper.check_auth!(request, response, @auth, @@password_file_path) if @@use_basic_auth
126
+ @@logger.info("access user #{@user}")
127
+ content_type :json
128
+ JSON.generate(@@model.get_log_job_detail(@user, params[:job_id]))
129
+ end
130
+
131
+ get '/log/dispatcher' do
132
+ @user = @@default_user if @user.nil?
133
+ @user = AuthHelper.check_auth!(request, response, @auth, @@password_file_path) if @@use_basic_auth
134
+ @@logger.info("access user #{@user}")
135
+ content_type :json
136
+ JSON.generate(@@model.get_log_dispatcher(@user))
137
+ end
138
+ end
139
+ end
140
+ end
141
+