pmux-logview 0.2.2

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.
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
+