log-monitor 0.0.8

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 (77) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +5 -0
  4. data/Rakefile +34 -0
  5. data/app/assets/javascripts/log_monitor/application.js +13 -0
  6. data/app/assets/stylesheets/log_monitor/application.css +15 -0
  7. data/app/controllers/log_monitor/application_controller.rb +4 -0
  8. data/app/helpers/log_monitor/application_helper.rb +4 -0
  9. data/app/views/layouts/log_monitor/application.html.erb +14 -0
  10. data/bin/log-monitor.rb +51 -0
  11. data/bin/rails.bak +12 -0
  12. data/config/log-monitor.yml +48 -0
  13. data/config/log-monitor.yml.example +46 -0
  14. data/config/routes.rb +2 -0
  15. data/lib/log_monitor.rb +30 -0
  16. data/lib/log_monitor/alerter.rb +169 -0
  17. data/lib/log_monitor/engine.rb +5 -0
  18. data/lib/log_monitor/version.rb +3 -0
  19. data/lib/tasks/log_monitor_tasks.rake +4 -0
  20. data/test/dummy/Gemfile +42 -0
  21. data/test/dummy/Gemfile.lock +127 -0
  22. data/test/dummy/README.rdoc +28 -0
  23. data/test/dummy/Rakefile +6 -0
  24. data/test/dummy/app/assets/javascripts/application.js +16 -0
  25. data/test/dummy/app/assets/javascripts/monitor.js.coffee +3 -0
  26. data/test/dummy/app/assets/stylesheets/application.css +15 -0
  27. data/test/dummy/app/assets/stylesheets/monitor.css.scss +3 -0
  28. data/test/dummy/app/controllers/application_controller.rb +5 -0
  29. data/test/dummy/app/controllers/monitor_controller.rb +11 -0
  30. data/test/dummy/app/helpers/application_helper.rb +2 -0
  31. data/test/dummy/app/helpers/monitor_helper.rb +2 -0
  32. data/test/dummy/app/log_monitor_test.rb +8 -0
  33. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  34. data/test/dummy/bin/bundle +3 -0
  35. data/test/dummy/bin/rails +4 -0
  36. data/test/dummy/bin/rake +4 -0
  37. data/test/dummy/bin/spring +18 -0
  38. data/test/dummy/config.ru +4 -0
  39. data/test/dummy/config/application.rb +26 -0
  40. data/test/dummy/config/boot.rb +4 -0
  41. data/test/dummy/config/database.yml +25 -0
  42. data/test/dummy/config/environment.rb +5 -0
  43. data/test/dummy/config/environments/development.rb +37 -0
  44. data/test/dummy/config/environments/production.rb +78 -0
  45. data/test/dummy/config/environments/test.rb +39 -0
  46. data/test/dummy/config/initializers/assets.rb +8 -0
  47. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  48. data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  49. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  50. data/test/dummy/config/initializers/inflections.rb +16 -0
  51. data/test/dummy/config/initializers/log_monitor.rb +8 -0
  52. data/test/dummy/config/initializers/mime_types.rb +4 -0
  53. data/test/dummy/config/initializers/session_store.rb +3 -0
  54. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  55. data/test/dummy/config/locales/en.yml +23 -0
  56. data/test/dummy/config/log-monitor.yml +50 -0
  57. data/test/dummy/config/log-monitor.yml.example +49 -0
  58. data/test/dummy/config/routes.rb +5 -0
  59. data/test/dummy/config/secrets.yml +22 -0
  60. data/test/dummy/db/development.sqlite3 +0 -0
  61. data/test/dummy/db/seeds.rb +7 -0
  62. data/test/dummy/lib/log_monitor_runner.rb +13 -0
  63. data/test/dummy/log/development.log +8273 -0
  64. data/test/dummy/log/production.log +0 -0
  65. data/test/dummy/public/404.html +67 -0
  66. data/test/dummy/public/422.html +67 -0
  67. data/test/dummy/public/500.html +66 -0
  68. data/test/dummy/public/favicon.ico +0 -0
  69. data/test/dummy/public/robots.txt +5 -0
  70. data/test/dummy/test/controllers/monitor_controller_test.rb +7 -0
  71. data/test/dummy/test/helpers/monitor_helper_test.rb +4 -0
  72. data/test/dummy/test/test_helper.rb +10 -0
  73. data/test/integration/navigation_test.rb +10 -0
  74. data/test/log_monitor_test.rb +7 -0
  75. data/test/test_helper.rb +17 -0
  76. data/test/test_regexp.rb +7 -0
  77. metadata +204 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5b0073f0ec1bd9256ccec677419ee4b7415c15da
4
+ data.tar.gz: 9d01494850a405caa93c0d1329b4b0a65810e7f8
5
+ SHA512:
6
+ metadata.gz: 0fd7738856473c34f86240c7bed942f1d9dffad600f4f66e3cd196cf91a6158e3306eb4c2302eedbf9b60eef19dcb20390d4634479316db662dee32196ca7803
7
+ data.tar.gz: 4952802dff00177c37e2d936826b6d4689c40931d373fae9bb6d78698f7090b2c3ca69311303e45b0fd4150cf341d44eafb431fb48c646a920a912be6449b154
@@ -0,0 +1,20 @@
1
+ Copyright 2014 YOURNAME
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,5 @@
1
+ = LogMonitor
2
+
3
+ Monitoring web server's log. And raise alert with email, webpost, file, or console.
4
+
5
+ This project rocks and uses MIT-LICENSE.
@@ -0,0 +1,34 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'LogMonitor'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.rdoc')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
18
+ load 'rails/tasks/engine.rake'
19
+
20
+
21
+
22
+ Bundler::GemHelper.install_tasks
23
+
24
+ require 'rake/testtask'
25
+
26
+ Rake::TestTask.new(:test) do |t|
27
+ t.libs << 'lib'
28
+ t.libs << 'test'
29
+ t.pattern = 'test/**/*_test.rb'
30
+ t.verbose = false
31
+ end
32
+
33
+
34
+ task default: :test
@@ -0,0 +1,13 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // compiled file.
9
+ //
10
+ // Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
11
+ // about supported directives.
12
+ //
13
+ //= require_tree .
@@ -0,0 +1,15 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
+ * compiled file so the styles you add here take precedence over styles defined in any styles
10
+ * defined in the other CSS/SCSS files in this directory. It is generally better to create a new
11
+ * file per style scope.
12
+ *
13
+ *= require_tree .
14
+ *= require_self
15
+ */
@@ -0,0 +1,4 @@
1
+ module LogMonitor
2
+ class ApplicationController < ActionController::Base
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module LogMonitor
2
+ module ApplicationHelper
3
+ end
4
+ end
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>LogMonitor</title>
5
+ <%= stylesheet_link_tag "log_monitor/application", media: "all" %>
6
+ <%= javascript_include_tag "log_monitor/application" %>
7
+ <%= csrf_meta_tags %>
8
+ </head>
9
+ <body>
10
+
11
+ <%= yield %>
12
+
13
+ </body>
14
+ </html>
@@ -0,0 +1,51 @@
1
+ #!/usr/bin/env ruby
2
+ require 'log_monitor'
3
+
4
+ if ARGV[0] == '-c'
5
+ puts <<EOF
6
+ monitor:
7
+ target: /tmp/log/development.log
8
+ words:
9
+ - Completed 500 Internal Server Error
10
+ - No route matches
11
+ method: file # or console or email or webpost
12
+ file: /tmp/log-monitor.log
13
+ webpost: http://localhost:3000/monitor/post # ignored which not selected as method
14
+ email: # ignored which not selected as method
15
+ to:
16
+ - *@*.com
17
+ from: *@gmail.com
18
+ subject: Alert! *.com Error occured!
19
+ address: smtp.gmail.com
20
+ port: 587
21
+ user_name: *@gmail.com
22
+ password: [password]
23
+ EOF
24
+
25
+ elsif ARGV[0] == '-i'
26
+ puts <<EOF
27
+ require 'log_monitor'
28
+
29
+ Thread.new do
30
+ config_file = Rails.root.join('config', 'log-monitor.yml')
31
+ config = YAML.load_file(config_file)#[Rails.env]
32
+ alerter = LogMonitor::Factory.get(config)
33
+ alerter.monitor
34
+ end
35
+ EOF
36
+
37
+ elsif !ARGV[0].nil? && File.exist?(ARGV[0])
38
+ config = YAML.load_file(ARGV[0])
39
+ Thread.new(config) do | prm_cfg |
40
+ alerter = LogMonitor::Factory.get(prm_cfg)
41
+ alerter.monitor
42
+ end
43
+ sleep
44
+ else
45
+ puts <<EOF
46
+ (none or other) : show help (this message)
47
+ -c : show example of config file. Please use with rediret.
48
+ -i : show example of initializer of RAILS's file. Please use with rediret.
49
+ [config file] : run monitoring log
50
+ EOF
51
+ end
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+ # This command will automatically be run when you run "rails" with Rails 4 gems installed from the root of your application.
3
+
4
+ ENGINE_ROOT = File.expand_path('../..', __FILE__)
5
+ ENGINE_PATH = File.expand_path('../../lib/log_monitor/engine', __FILE__)
6
+
7
+ # Set up gems listed in the Gemfile.
8
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
9
+ require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
10
+
11
+ require 'rails/all'
12
+ require 'rails/engine/commands'
@@ -0,0 +1,48 @@
1
+ production: &base
2
+ monitor:
3
+ target: ~/work/talk-talk-srv/log/development.log
4
+ words: Completed 500 Internal Server Error
5
+ method: email
6
+ email:
7
+ to: jironbach@gmail.com
8
+ from: shimoda@agilebooster.com
9
+ address: smtp.gmail.com
10
+ port: 587
11
+ user_name: shimoda@agilebooster.com
12
+ password: agilebooster
13
+ subject: [Alert! talktalk.mydns.jp 500 error occured!]
14
+
15
+ development:
16
+ monitor:
17
+ target: ~/work/talk-talk-srv/log/development.log
18
+ words:
19
+ - Completed 500 Internal Server Error
20
+ - Completed 404 Not Found
21
+ method:
22
+ - email
23
+ - webhook
24
+ email:
25
+ to:
26
+ - jironbach@gmail.com
27
+ - admin@agilebooster.com
28
+ - shimoda@agilebooster.com
29
+ from: shimoda@agilebooster.com
30
+ address: smtp.gmail.com
31
+ port: 587
32
+ user_name: shimoda@agilebooster.com
33
+ password: agilebooster
34
+ subject: [Alert! talktalk.mydns.jp Error occured!]
35
+ webhook: http://talktalk.mydns.jp/monitor/post/
36
+
37
+ staging:
38
+ <<: *base
39
+
40
+ test:
41
+ monitor:
42
+ target: ~/work/logmonitor/test/dummy/log/development.log
43
+ words:
44
+ - Completed 500 Internal Server Error
45
+ - Completed 404 Not Found
46
+ method: webhook
47
+ webhook: http://localhost:3000/monitor/post
48
+
@@ -0,0 +1,46 @@
1
+ production: &base
2
+ monitor:
3
+ target: /var/log/production.log
4
+ words: Completed 500 Internal Server Error
5
+ method: email
6
+ email:
7
+ to: admin@*.com
8
+ from: monitor@*.com
9
+ address: smtp.gmail.com
10
+ port: 587
11
+ user_name: *@gmail.com
12
+ password: *****
13
+ subject: [Alert! *.com 500 error occured!]
14
+
15
+ development:
16
+ monitor:
17
+ target: /var/log/development.log
18
+ words:
19
+ - Completed 500 Internal Server Error
20
+ - Completed 404 Not Found
21
+ method:
22
+ - email
23
+ - webhook
24
+ email:
25
+ to:
26
+ - admin@*.com
27
+ - develper@*.com
28
+ - tester@*.com
29
+ from: monitor@*.com
30
+ address: smtp.gmail.com
31
+ port: 587
32
+ user_name: *@gmail.com
33
+ password: *****
34
+ subject: [Alert! *.com Error occured!]
35
+ webhook: http://localhost:3000/monitor/post/
36
+
37
+ staging:
38
+ <<: *base
39
+
40
+ test:
41
+ monitor:
42
+ target: ~/log/test.log
43
+ words: Completed 404 Not Found
44
+ method: webhook
45
+ webhook: http://localhost:3000/monitor/post/
46
+
@@ -0,0 +1,2 @@
1
+ LogMonitor::Engine.routes.draw do
2
+ end
@@ -0,0 +1,30 @@
1
+ require "log_monitor/engine" if defined? Rails
2
+ require "log_monitor/alerter"
3
+
4
+ module LogMonitor
5
+ class Factory
6
+ def self.get(config)
7
+ alerter = self.get_alerter(config)
8
+ alerter.set_in(config['monitor']['target'])
9
+ alerter.set_words(config['monitor']['words'])
10
+ alerter
11
+ end
12
+
13
+ def self.get_alerter(config)
14
+ if config['method'] == 'email'
15
+ alerter = LogMonitor::EmailAlerter.new
16
+ alerter.set_email(config['email'])
17
+ elsif config['method'] == 'webpost'
18
+ alerter = LogMonitor::WebPostAlerter.new
19
+ alerter.set_webpost(config['webpost'])
20
+ elsif config['method'] == 'file'
21
+ alerter = LogMonitor::FileAlerter.new
22
+ alerter.set_out(config['file'])
23
+ else
24
+ alerter = LogMonitor::Alerter.new
25
+ end
26
+ alerter
27
+ end
28
+
29
+ end
30
+ end
@@ -0,0 +1,169 @@
1
+ module LogMonitor
2
+ class Alerter
3
+ def initialize
4
+ clear_alert
5
+ end
6
+
7
+ def set_in(io_in)
8
+ @io_in = io_in
9
+ FileUtils.touch(io_in) unless File.exists?(io_in)
10
+ @in = File.open(io_in, 'r')
11
+ end
12
+
13
+ def set_words(words)
14
+ @words = words
15
+ end
16
+
17
+ def monitor
18
+ @in.seek(0, IO::SEEK_END)
19
+ begin
20
+ revival_monitor
21
+ ensure
22
+ @in.close
23
+ end
24
+ end
25
+
26
+ def check_words
27
+ is_alert = false
28
+ @words.each do | word |
29
+ if @alert_body.match(/#{word}/)
30
+ is_alert = true
31
+ break
32
+ end
33
+ end
34
+ if is_alert
35
+ alert
36
+ end
37
+ clear_alert
38
+ end
39
+
40
+ def clear_alert
41
+ @alert_body = ''
42
+ @blank_line_count = 0
43
+ end
44
+
45
+ def alert
46
+ begin
47
+ $stdout.puts @alert_body
48
+ rescue => e
49
+ $stderr.puts "LogMonitor error"
50
+ $stderr.puts e.message
51
+ 2.times $stderr.puts
52
+ end
53
+ clear_alert
54
+ end
55
+
56
+ protected
57
+
58
+ def revival_monitor
59
+ return if @in.nil?
60
+ while true
61
+ sleep(1) if @in.eof
62
+ line = @in.gets
63
+ @alert_body += "#{line}"
64
+ if line.blank?
65
+ @blank_line_count += 1
66
+ else
67
+ @blank_line_count = 0
68
+ end
69
+ check_words if @blank_line_count >= 2
70
+ end
71
+ end
72
+
73
+ end
74
+
75
+
76
+ class FileAlerter < Alerter
77
+ def set_out(filename)
78
+ @filename = filename
79
+ end
80
+
81
+ def alert
82
+ begin
83
+ File.open(@filename, 'a') do | io_out |
84
+ io_out.puts @alert_body
85
+ end
86
+ rescue => e
87
+ $stderr.puts "LogMonitor error"
88
+ $stderr.puts e.message
89
+ 2.times $stderr.puts
90
+ end
91
+ clear_alert
92
+ end
93
+
94
+ end
95
+
96
+
97
+ require 'mail'
98
+ class EmailAlerter < Alerter
99
+ def set_email(config)
100
+ @config = config
101
+ @smtp_settings = {
102
+ address: config['address'],
103
+ port: config['port'],
104
+ user_name: config['user_name'],
105
+ password: config['password'],
106
+ domain: config['domain'],
107
+ authentication: config['authentication'].nil? ? :plain : config['authentication'],
108
+ enable_starttls_auto: true
109
+ }
110
+ end
111
+
112
+ def alert
113
+ begin
114
+ mail = Mail.new
115
+ mail[:from] = @config['from']
116
+ mail[:to] = @config['to']
117
+ mail.subject = @config['subject']
118
+ smtpserver = Net::SMTP.new(@smtp_settings[:address], @smtp_settings[:port])
119
+ smtpserver.enable_tls(OpenSSL::SSL::VERIFY_NONE)
120
+ smtpserver.start(@smtp_settings[:domain], @smtp_settings[:user_name], @smtp_settings[:password], :login) do |smtp|
121
+ mail.body = @alert_body
122
+ smtp.send_message(mail.encoded, mail.from, mail.to)
123
+ end
124
+ rescue => e
125
+ $stderr.puts "LogMonitor error"
126
+ $stderr.puts e.message
127
+ 2.times $stderr.puts
128
+ end
129
+ clear_alert
130
+ end
131
+
132
+ end
133
+
134
+
135
+ class WebPostAlerter < Alerter
136
+ def set_webpost(config)
137
+ @url = config
138
+ end
139
+
140
+ def alert
141
+ begin
142
+ Net::HTTP.post_form(URI.parse(@url), { checker: 'logmonitor-webpost-log', body: "#{ @alert_body }"})
143
+ rescue => e
144
+ $stderr.puts "LogMonitor error"
145
+ $stderr.puts e.message
146
+ 2.times $stderr.puts
147
+ end
148
+ clear_alert
149
+ end
150
+
151
+ def check_words
152
+ is_alert = false
153
+ @words.each do | word |
154
+ if @alert_body.match(/#{word}/) && !@alert_body.include?('logmonitor-webpost-log')
155
+ is_alert = true
156
+ break
157
+ end
158
+ end
159
+ if is_alert
160
+ alert
161
+ end
162
+ clear_alert
163
+ end
164
+
165
+ end
166
+
167
+
168
+ end
169
+