provizioning 0.1.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (223) hide show
  1. data/.gitignore +17 -0
  2. data/Gemfile +4 -0
  3. data/README.md +29 -0
  4. data/Rakefile +2 -0
  5. data/bootstrap/bootstrap.sh +71 -0
  6. data/{lib/templates/sources.list → bootstrap/lucid.sources.list} +2 -1
  7. data/bootstrap/natty.sources.list +14 -0
  8. data/lib/provizioning/puppet.rb +94 -0
  9. data/lib/provizioning/version.rb +3 -0
  10. data/lib/provizioning.rb +1 -3
  11. data/provizioning.gemspec +20 -0
  12. data/puppet/classes/apache/centos.conf +978 -0
  13. data/puppet/classes/apache/ssl.conf +75 -0
  14. data/puppet/classes/apache.pp +152 -0
  15. data/puppet/classes/apt.pp +5 -0
  16. data/puppet/classes/base/ntp/ntpd-sysconfig +13 -0
  17. data/puppet/classes/base.pp +79 -0
  18. data/puppet/classes/freerange.pp +53 -0
  19. data/puppet/classes/gemrc/gemrc +9 -0
  20. data/puppet/classes/gemrc.pp +10 -0
  21. data/puppet/classes/imagemagick.pp +19 -0
  22. data/puppet/classes/iptables/load-iptables +3 -0
  23. data/puppet/classes/iptables/post-iptables +2 -0
  24. data/puppet/classes/iptables/pre-iptables +2 -0
  25. data/puppet/classes/iptables.pp +59 -0
  26. data/puppet/classes/logrotate/logrotate.erb +15 -0
  27. data/puppet/classes/logrotate.pp +37 -0
  28. data/puppet/classes/mongo/mongodb.conf +89 -0
  29. data/puppet/classes/mongo.pp +86 -0
  30. data/puppet/classes/monit/monit.conf +242 -0
  31. data/puppet/classes/monit.pp +39 -0
  32. data/puppet/classes/munin/plugins/passenger_memory_stats +123 -0
  33. data/puppet/classes/munin/plugins/passenger_status +130 -0
  34. data/puppet/classes/munin/plugins/rails_database_time +174 -0
  35. data/puppet/classes/munin/plugins/rails_request_duration +173 -0
  36. data/puppet/classes/munin/plugins/rails_request_error +169 -0
  37. data/puppet/classes/munin/plugins/rails_requests +175 -0
  38. data/puppet/classes/munin/plugins/rails_view_render_time +173 -0
  39. data/puppet/classes/munin/rails-plugin-config +4 -0
  40. data/puppet/classes/munin.pp +60 -0
  41. data/puppet/classes/mysql/password.erb +1 -0
  42. data/puppet/classes/mysql.pp +71 -0
  43. data/puppet/classes/openswan/ipsec.conf +17 -0
  44. data/puppet/classes/openswan/ipsec.secrets +1 -0
  45. data/puppet/classes/openswan/patched_ipsec_initd_script +223 -0
  46. data/puppet/classes/openswan/secret.erb +1 -0
  47. data/puppet/classes/openswan.pp +71 -0
  48. data/puppet/classes/post-flight.pp +17 -0
  49. data/puppet/classes/postfix/main.cf +39 -0
  50. data/puppet/classes/postfix.pp +16 -0
  51. data/puppet/classes/rack/centos/passenger.load.erb +5 -0
  52. data/puppet/classes/rack/ubuntu/passenger.conf.erb +6 -0
  53. data/puppet/classes/rack.pp +66 -0
  54. data/puppet/classes/redis/redis.conf.erb +187 -0
  55. data/puppet/classes/redis.pp +20 -0
  56. data/puppet/classes/sudo/sudoers +6 -0
  57. data/puppet/classes/sudo.pp +24 -0
  58. data/puppet/classes/syslogng/CentOS.cnf +61 -0
  59. data/puppet/classes/syslogng/Ubuntu.cnf +347 -0
  60. data/puppet/classes/syslogng.pp +146 -0
  61. data/puppet/classes/xml.pp +23 -0
  62. data/puppet/classes/yum.pp +6 -0
  63. data/puppet/classes/zsh.pp +5 -0
  64. data/puppet/modules/README +74 -0
  65. data/puppet/modules/cron/README +4 -0
  66. data/puppet/modules/cron/manifests/base.pp +26 -0
  67. data/puppet/modules/cron/manifests/crontabs.pp +11 -0
  68. data/puppet/modules/cron/manifests/init.pp +18 -0
  69. data/puppet/modules/drupal/Modulefile +7 -0
  70. data/puppet/modules/drupal/README +110 -0
  71. data/puppet/modules/drupal/manifests/absent.pp +25 -0
  72. data/puppet/modules/drupal/manifests/backup/absent.pp +23 -0
  73. data/puppet/modules/drupal/manifests/backup.pp +49 -0
  74. data/puppet/modules/drupal/manifests/conf.pp +23 -0
  75. data/puppet/modules/drupal/manifests/debug.pp +26 -0
  76. data/puppet/modules/drupal/manifests/disable.pp +22 -0
  77. data/puppet/modules/drupal/manifests/disableboot.pp +13 -0
  78. data/puppet/modules/drupal/manifests/drush.pp +20 -0
  79. data/puppet/modules/drupal/manifests/example42/backup.pp +8 -0
  80. data/puppet/modules/drupal/manifests/example42/monitor.pp +8 -0
  81. data/puppet/modules/drupal/manifests/example42.pp +25 -0
  82. data/puppet/modules/drupal/manifests/extra.pp +30 -0
  83. data/puppet/modules/drupal/manifests/firewall/absent.pp +19 -0
  84. data/puppet/modules/drupal/manifests/firewall.pp +24 -0
  85. data/puppet/modules/drupal/manifests/init.pp +54 -0
  86. data/puppet/modules/drupal/manifests/install.pp +20 -0
  87. data/puppet/modules/drupal/manifests/module.pp +37 -0
  88. data/puppet/modules/drupal/manifests/monitor/absent.pp +42 -0
  89. data/puppet/modules/drupal/manifests/monitor.pp +77 -0
  90. data/puppet/modules/drupal/manifests/package.pp +20 -0
  91. data/puppet/modules/drupal/manifests/params.pp +277 -0
  92. data/puppet/modules/drupal/manifests/site.pp +63 -0
  93. data/puppet/modules/drupal/manifests/theme.pp +33 -0
  94. data/puppet/modules/drupal/templates/variables_drupal.erb +62 -0
  95. data/puppet/modules/drupal/tests/absent.pp +1 -0
  96. data/puppet/modules/drupal/tests/backup.pp +1 -0
  97. data/puppet/modules/drupal/tests/debug.pp +1 -0
  98. data/puppet/modules/drupal/tests/disable.pp +1 -0
  99. data/puppet/modules/drupal/tests/disableboot.pp +1 -0
  100. data/puppet/modules/drupal/tests/firewall.pp +1 -0
  101. data/puppet/modules/drupal/tests/init.pp +1 -0
  102. data/puppet/modules/drupal/tests/monitor.pp +1 -0
  103. data/puppet/modules/hosts/README +0 -0
  104. data/puppet/modules/hosts/manifests/example42.pp +5 -0
  105. data/puppet/modules/hosts/manifests/init.pp +16 -0
  106. data/puppet/modules/hosts/templates/hosts.erb +11 -0
  107. data/puppet/modules/iptables/README +4 -0
  108. data/puppet/modules/iptables/files/iptables +19 -0
  109. data/puppet/modules/iptables/manifests/disable.pp +15 -0
  110. data/puppet/modules/iptables/manifests/init.pp +9 -0
  111. data/puppet/modules/iptables/manifests/redhat.pp +24 -0
  112. data/puppet/modules/mysql/Modulefile +7 -0
  113. data/puppet/modules/mysql/README +56 -0
  114. data/puppet/modules/mysql/manifests/absent.pp +12 -0
  115. data/puppet/modules/mysql/manifests/backup/example42.pp +8 -0
  116. data/puppet/modules/mysql/manifests/backup.pp +49 -0
  117. data/puppet/modules/mysql/manifests/client.pp +18 -0
  118. data/puppet/modules/mysql/manifests/conf.pp +23 -0
  119. data/puppet/modules/mysql/manifests/debug.pp +25 -0
  120. data/puppet/modules/mysql/manifests/disable.pp +13 -0
  121. data/puppet/modules/mysql/manifests/disableboot.pp +13 -0
  122. data/puppet/modules/mysql/manifests/example42.pp +25 -0
  123. data/puppet/modules/mysql/manifests/firewall.pp +23 -0
  124. data/puppet/modules/mysql/manifests/grant.pp +29 -0
  125. data/puppet/modules/mysql/manifests/init.pp +67 -0
  126. data/puppet/modules/mysql/manifests/monitor/example42.pp +8 -0
  127. data/puppet/modules/mysql/manifests/monitor.pp +77 -0
  128. data/puppet/modules/mysql/manifests/params.pp +240 -0
  129. data/puppet/modules/mysql/manifests/query.pp +30 -0
  130. data/puppet/modules/mysql/templates/grant.erb +6 -0
  131. data/puppet/modules/mysql/templates/query.erb +5 -0
  132. data/puppet/modules/mysql/templates/variables_mysql.erb +42 -0
  133. data/puppet/modules/network/README +4 -0
  134. data/puppet/modules/network/manifests/init.pp +13 -0
  135. data/puppet/modules/nginx/manifests/fcgi.pp +87 -0
  136. data/puppet/modules/nginx/manifests/init.pp +205 -0
  137. data/puppet/modules/nginx/templates/fcgi_site.erb +38 -0
  138. data/puppet/modules/nginx/templates/includes/fastcgi_params.erb +23 -0
  139. data/puppet/modules/nginx/templates/nginx.conf.erb +31 -0
  140. data/puppet/modules/passenger/manifests/init.pp +12 -0
  141. data/puppet/modules/passenger/templates/myapp +39 -0
  142. data/puppet/modules/php/README +26 -0
  143. data/puppet/modules/php/manifests/init.pp +42 -0
  144. data/puppet/modules/php/manifests/module.pp +22 -0
  145. data/puppet/modules/php/manifests/pear/module.pp +21 -0
  146. data/puppet/modules/php/manifests/pear.pp +20 -0
  147. data/puppet/modules/php/manifests/pecl/config.pp +19 -0
  148. data/puppet/modules/php/manifests/pecl/module.pp +44 -0
  149. data/puppet/modules/php/manifests/pecl.pp +8 -0
  150. data/puppet/modules/php/manifests/soap.pp +20 -0
  151. data/puppet/modules/postgres/Copyright +13 -0
  152. data/puppet/modules/postgres/manifests/database.pp +40 -0
  153. data/puppet/modules/postgres/manifests/init.pp +25 -0
  154. data/puppet/modules/postgres/manifests/role.pp +40 -0
  155. data/puppet/modules/ruby/files/install-ruby-stow +43 -0
  156. data/puppet/modules/ruby/manifests/init.pp +18 -0
  157. data/puppet/modules/rvm/files/install-system-rvm +2 -0
  158. data/puppet/modules/rvm/manifests/classes/dependencies.pp +24 -0
  159. data/puppet/modules/rvm/manifests/classes/passenger.pp +166 -0
  160. data/puppet/modules/rvm/manifests/classes/system.pp +33 -0
  161. data/puppet/modules/rvm/manifests/definitions/system_user.pp +13 -0
  162. data/puppet/modules/rvm/manifests/init.pp +2 -0
  163. data/puppet/modules/rvm/templates/passenger-apache.conf.erb +9 -0
  164. data/puppet/modules/ssh/README +4 -0
  165. data/puppet/modules/ssh/manifests/auth.pp +39 -0
  166. data/puppet/modules/ssh/manifests/auth.pp.good +340 -0
  167. data/puppet/modules/ssh/manifests/eal4.pp +69 -0
  168. data/puppet/modules/ssh/manifests/init.pp +74 -0
  169. data/puppet/modules/stow/manifests/init.pp +5 -0
  170. data/puppet/modules/sudo/files/sudoers +25 -0
  171. data/puppet/modules/sudo/manifests/init.pp +1 -0
  172. data/puppet/modules/sudo/manifests/install.pp +5 -0
  173. data/puppet/modules/sudo/manifests/sudoers.pp +14 -0
  174. data/puppet/modules/ufw/manifests/init.pp +12 -0
  175. data/puppet/modules/users/README +28 -0
  176. data/puppet/modules/users/manifests/adduser.pp +16 -0
  177. data/puppet/modules/users/manifests/admin.pp +11 -0
  178. data/puppet/modules/users/manifests/automount.pp +34 -0
  179. data/puppet/modules/users/manifests/deluser.pp +8 -0
  180. data/puppet/modules/users/manifests/example42.pp +16 -0
  181. data/puppet/modules/users/manifests/init.pp +31 -0
  182. data/puppet/modules/users/manifests/ldap.pp +114 -0
  183. data/puppet/modules/users/manifests/params.pp +84 -0
  184. data/puppet/modules/users/templates/ldap/ldap.conf.erb +13 -0
  185. data/puppet/modules/users/templates/ldap/nsswitch.conf.erb +23 -0
  186. data/puppet/modules/users/templates/ldap/openldap-ldap.conf.erb +8 -0
  187. data/puppet/modules/webmin/manifests/init.pp +31 -0
  188. data/puppet/roles/blank.pp +1 -0
  189. data/puppet/site.pp +8 -0
  190. metadata +235 -81
  191. data/README +0 -3
  192. data/bin/provizion +0 -52
  193. data/lib/policies/chef-client.rb +0 -37
  194. data/lib/policies/lamp.rb +0 -42
  195. data/lib/policies/passenger.rb +0 -44
  196. data/lib/recipes/apache.rb +0 -70
  197. data/lib/recipes/apache_conf.rb +0 -3
  198. data/lib/recipes/bundler.rb +0 -4
  199. data/lib/recipes/chef_client.rb +0 -11
  200. data/lib/recipes/curl.rb +0 -8
  201. data/lib/recipes/essential.rb +0 -4
  202. data/lib/recipes/git.rb +0 -15
  203. data/lib/recipes/imagemagick.rb +0 -8
  204. data/lib/recipes/mailserver.rb +0 -9
  205. data/lib/recipes/memcached.rb +0 -16
  206. data/lib/recipes/mysql.rb +0 -21
  207. data/lib/recipes/nginx/init.d +0 -63
  208. data/lib/recipes/nginx.rb +0 -25
  209. data/lib/recipes/passenger.rb +0 -67
  210. data/lib/recipes/php.rb +0 -8
  211. data/lib/recipes/postgresql.rb +0 -21
  212. data/lib/recipes/ruby_enterprise.rb +0 -24
  213. data/lib/recipes/rvm.rb +0 -25
  214. data/lib/recipes/sources.rb +0 -5
  215. data/lib/recipes/subversion.rb +0 -8
  216. data/lib/recipes/syslog.rb +0 -7
  217. data/lib/recipes/ufw.rb +0 -12
  218. data/lib/recipes/vim.rb +0 -8
  219. data/lib/recipes/webmin.rb +0 -17
  220. data/lib/templates/apache.conf.erb +0 -12
  221. data/lib/templates/my.cnf +0 -132
  222. data/lib/templates/passenger.conf +0 -11
  223. data/lib/templates/passenger.load +0 -1
@@ -0,0 +1,174 @@
1
+ #!/usr/bin/env ruby
2
+ pod=<<-POD
3
+
4
+ =head1 NAME
5
+ rails_database_time - Munin plugin to monitor the minimum, average and maximum database times.
6
+
7
+ =head1 APPLICABLE SYSTEMS
8
+ All systems that have a rails application log.
9
+
10
+ =head1 CONFIGURATION
11
+ The request-log-analyzer gem has to be intalled.
12
+ Also the script has to be able to access the rails log file and tail.
13
+ This configuration section shows the defaults of the plugin:
14
+
15
+ [rails_database_time]
16
+ env.log_file '/path/to/production.log'
17
+ user www-data
18
+ command /usr/local/bin/ruby %c
19
+
20
+ Options
21
+ env.lines 50000 # Number of lines to tail
22
+ env.interval 300 # Munin interval in seconds (used for graphs and caching)
23
+ env.request_log_analyzer '/usr/local/bin' # Path to gem. Use this for Debian.
24
+ env.graph_category 'App' # Graph Category. Defaults to App.
25
+
26
+ ln -s /usr/share/munin/plugins/rails_database_time /etc/munin/plugins/rails_database_time
27
+
28
+ =head1 INTERPRETATION
29
+ Three lines are graphed, showing the minimum, average and maximum database times.
30
+
31
+ =head1 MAGIC MARKERS
32
+ #%# family=auto
33
+ #%# capabilities=autoconf
34
+
35
+ =head1 VERSION
36
+ 1.5
37
+
38
+ =head1 BUGS
39
+ None known
40
+
41
+ =head1 AUTHOR
42
+ Bart ten Brinke - railsdoctors.com
43
+
44
+ =head1 LICENSE
45
+ MIT
46
+
47
+ POD
48
+
49
+ # Globals
50
+ GRAPH_CATEGORY = ENV['graph_category'] || 'App'
51
+ INTERVAL = ENV['interval'] ? ENV['interval'].to_i : 300
52
+ NUMBER_OF_LINES = ENV['lines'] || 50000
53
+ LOG_FILE = ENV['log_file']
54
+ AFTER_TIME = (Time.now - INTERVAL).strftime('%Y%m%d%H%M%S')
55
+ FLOOR_TIME = Time.at((Time.now.to_f / INTERVAL).floor * INTERVAL)
56
+
57
+ TEMP_FOLDER = '/tmp'
58
+ TEMP_PREFIX = GRAPH_CATEGORY == 'App' ? 'rla' : GRAPH_CATEGORY.downcase
59
+ TEMP_FILE = "#{TEMP_PREFIX}_#{FLOOR_TIME.to_i}.yml"
60
+ REQUEST_LOG_ANALYZER = ENV['request_log_analyzer'] || '/usr/bin/request-log-analyzer'
61
+
62
+ # Check if we can run this plugin on this system
63
+ def autoconf
64
+ begin
65
+ require 'rubygems'
66
+ gem "request-log-analyzer", ">=1.1.6"
67
+ require "yaml"
68
+ rescue Exception => e
69
+ puts "no (Gem not found: #{e})"
70
+ exit 1
71
+ end
72
+
73
+ unless `echo "test" | tail 2>/dev/null`.include?("test")
74
+ puts "no (tail command not found)"
75
+ exit 1
76
+ end
77
+
78
+ puts "yes"
79
+ exit 0
80
+ end
81
+
82
+ # Uptput the config
83
+ def config
84
+ puts <<-CONFIG
85
+ graph_category #{GRAPH_CATEGORY}
86
+ graph_title Database time
87
+ graph_vlabel Seconds
88
+ graph_args --base 1000 -l 0
89
+ graph_info The minimum, maximum and average database times - railsdoctors.com
90
+
91
+ min.label min
92
+ max.label max
93
+ average.label avg
94
+ CONFIG
95
+ exit 0
96
+ end
97
+
98
+ # Fetch or create yaml cache file using request-log-analyzer
99
+ def fetch_or_create_yaml_file(log_file, debug = false)
100
+ # Clean up any old temp files left in de temp folder
101
+ Dir.new(TEMP_FOLDER).entries.each do |file_name|
102
+ if match = file_name.match(/^#{TEMP_PREFIX}_.*\.yml/)
103
+ if match[0] != TEMP_FILE
104
+ puts "Removing old cache file: #{file_name}" if debug
105
+ File.delete(TEMP_FOLDER + "/" + file_name)
106
+ end
107
+ end
108
+ end
109
+
110
+ temp_file = TEMP_FOLDER + "/" + TEMP_FILE
111
+
112
+ # Create temp file rla if needed
113
+ unless File.exists?(temp_file)
114
+ puts "Processing the last #{NUMBER_OF_LINES} lines of #{log_file} which are less then #{INTERVAL} seconds old." if debug
115
+ p "tail -n #{NUMBER_OF_LINES} #{log_file} | #{REQUEST_LOG_ANALYZER} - --format rails3 --after #{AFTER_TIME} -b --dump #{temp_file} 2>/dev/null"
116
+ status = `tail -n #{NUMBER_OF_LINES} #{log_file} | #{REQUEST_LOG_ANALYZER} - --format rails3 --after #{AFTER_TIME} -b --dump #{temp_file} 2>/dev/null`
117
+
118
+ unless $?.success?
119
+ $stderr.puts "failed executing request-log-analyzer. Is the path to the binary correct?"
120
+ exit 1
121
+ end
122
+ else
123
+ puts "Processing cached YAML result #{temp_file}" if debug
124
+ end
125
+
126
+ return temp_file
127
+ end
128
+
129
+ # Gather information
130
+ def run(log_file, debug = false)
131
+
132
+ if log_file == "" || log_file.nil?
133
+ $stderr.puts "Filepath unspecified. Exiting"
134
+ exit 1
135
+ end
136
+
137
+ # Initialize values
138
+ max_value = 0
139
+ min_value = 1.0/0.0
140
+ cumulative = 0
141
+ hits = 0
142
+
143
+ # Walk through the
144
+ require "yaml"
145
+ rla = YAML::load_file( fetch_or_create_yaml_file(log_file, debug) )
146
+
147
+ if rla && rla["Database time"]
148
+ rla["Database time"].each do |item|
149
+ max_value = item[1][:max] if item[1][:max] > max_value
150
+ min_value = item[1][:min] if item[1][:min] < min_value
151
+ hits += item[1][:hits]
152
+ cumulative += item[1][:sum]
153
+ end
154
+ else
155
+ hits = 1
156
+ min_value = 0
157
+ end
158
+
159
+ # Report in seconds
160
+ puts "max.value #{max_value}"
161
+ puts "min.value #{min_value}"
162
+ puts "average.value #{cumulative / hits.to_f}"
163
+ end
164
+
165
+ # Main
166
+ if ARGV[0] == "config"
167
+ config
168
+ elsif ARGV[0] == "autoconf"
169
+ autoconf
170
+ elsif ARGV[0] == "debug"
171
+ run(LOG_FILE || ARGV[1], true)
172
+ else
173
+ run(LOG_FILE || ARGV[0])
174
+ end
@@ -0,0 +1,173 @@
1
+ #!/usr/bin/env ruby
2
+ pod=<<-POD
3
+
4
+ =head1 NAME
5
+ rails_request_duration - Munin plugin to monitor the minimum, average and maximum request duration.
6
+
7
+ =head1 APPLICABLE SYSTEMS
8
+ All systems that have a rails application log.
9
+
10
+ =head1 CONFIGURATION
11
+ The request-log-analyzer gem has to be intalled.
12
+ Also the script has to be able to access the rails log file and tail.
13
+ This configuration section shows the defaults of the plugin:
14
+
15
+ [rails_request_duration]
16
+ env.log_file '/path/to/production.log'
17
+ user www-data
18
+ command /usr/local/bin/ruby %c
19
+
20
+ Options
21
+ env.lines 50000 # Number of lines to tail
22
+ env.interval 300 # Munin interval in seconds (used for graphs and caching)
23
+ env.request_log_analyzer '/usr/local/bin' # Path to gem. Use this for Debian.
24
+ env.graph_category 'App' # Graph Category. Defaults to App.
25
+
26
+ ln -s /usr/share/munin/plugins/rails_request_duration /etc/munin/plugins/rails_request_duration
27
+
28
+ =head1 INTERPRETATION
29
+ Three lines are graphed, showing the minimum, average and maximum request times.
30
+
31
+ =head1 MAGIC MARKERS
32
+ #%# family=auto
33
+ #%# capabilities=autoconf
34
+
35
+ =head1 VERSION
36
+ 1.5
37
+
38
+ =head1 BUGS
39
+ None known
40
+
41
+ =head1 AUTHOR
42
+ Bart ten Brinke - railsdoctors.com
43
+
44
+ =head1 LICENSE
45
+ MIT
46
+
47
+ POD
48
+
49
+ # Globals
50
+ GRAPH_CATEGORY = ENV['graph_category'] || 'App'
51
+ INTERVAL = ENV['interval'] ? ENV['interval'].to_i : 300
52
+ NUMBER_OF_LINES = ENV['lines'] || 50000
53
+ LOG_FILE = ENV['log_file']
54
+ AFTER_TIME = (Time.now - INTERVAL).strftime('%Y%m%d%H%M%S')
55
+ FLOOR_TIME = Time.at((Time.now.to_f / INTERVAL).floor * INTERVAL)
56
+
57
+ TEMP_FOLDER = '/tmp'
58
+ TEMP_PREFIX = GRAPH_CATEGORY == 'App' ? 'rla' : GRAPH_CATEGORY.downcase
59
+ TEMP_FILE = "#{TEMP_PREFIX}_#{FLOOR_TIME.to_i}.yml"
60
+ REQUEST_LOG_ANALYZER = ENV['request_log_analyzer'] || '/usr/bin/request-log-analyzer'
61
+
62
+ # Check if we can run this plugin on this system
63
+ def autoconf
64
+ begin
65
+ require 'rubygems'
66
+ gem "request-log-analyzer", ">=1.1.6"
67
+ require "yaml"
68
+ rescue Exception => e
69
+ puts "no (Gem not found: #{e})"
70
+ exit 1
71
+ end
72
+
73
+ unless `echo "test" | tail 2>/dev/null`.include?("test")
74
+ puts "no (tail command not found)"
75
+ exit 1
76
+ end
77
+
78
+ puts "yes"
79
+ exit 0
80
+ end
81
+
82
+ # Uptput the config
83
+ def config
84
+ puts <<-CONFIG
85
+ graph_category #{GRAPH_CATEGORY}
86
+ graph_title Request time
87
+ graph_vlabel Seconds
88
+ graph_args --base 1000 -l 0
89
+ graph_info The minimum, maximum and average request times - railsdoctors.com
90
+
91
+ min.label min
92
+ max.label max
93
+ average.label avg
94
+ CONFIG
95
+ exit 0
96
+ end
97
+
98
+ # Fetch or create yaml cache file using request-log-analyzer
99
+ def fetch_or_create_yaml_file(log_file, debug = false)
100
+ # Clean up any old temp files left in de temp folder
101
+ Dir.new(TEMP_FOLDER).entries.each do |file_name|
102
+ if match = file_name.match(/^#{TEMP_PREFIX}_.*\.yml/)
103
+ if match[0] != TEMP_FILE
104
+ puts "Removing old cache file: #{file_name}" if debug
105
+ File.delete(TEMP_FOLDER + "/" + file_name)
106
+ end
107
+ end
108
+ end
109
+
110
+ temp_file = TEMP_FOLDER + "/" + TEMP_FILE
111
+
112
+ # Create temp file rla if needed
113
+ unless File.exists?(temp_file)
114
+ puts "Processing the last #{NUMBER_OF_LINES} lines of #{log_file} which are less then #{INTERVAL} seconds old." if debug
115
+ p "tail -n #{NUMBER_OF_LINES} #{log_file} | #{REQUEST_LOG_ANALYZER} - --format rails3 --after #{AFTER_TIME} -b --dump #{temp_file} 2>/dev/null"
116
+ status = `tail -n #{NUMBER_OF_LINES} #{log_file} | #{REQUEST_LOG_ANALYZER} - --format rails3 --after #{AFTER_TIME} -b --dump #{temp_file} 2>/dev/null`
117
+
118
+ unless $?.success?
119
+ $stderr.puts "failed executing request-log-analyzer. Is the path to the binary correct?"
120
+ exit 1
121
+ end
122
+ else
123
+ puts "Processing cached YAML result #{temp_file}" if debug
124
+ end
125
+
126
+ return temp_file
127
+ end
128
+
129
+ # Gather information
130
+ def run(log_file, debug = false)
131
+
132
+ if log_file == "" || log_file.nil?
133
+ $stderr.puts "Filepath unspecified. Exiting"
134
+ exit 1
135
+ end
136
+
137
+ # Initialize values
138
+ max_value = 0
139
+ min_value = 1.0/0.0
140
+ cumulative = 0
141
+ hits = 0
142
+
143
+ # Walk through the
144
+ require "yaml"
145
+ rla = YAML::load_file( fetch_or_create_yaml_file(log_file, debug) )
146
+
147
+ if rla && rla["Request duration"]
148
+ rla["Request duration"].each do |item|
149
+ max_value = item[1][:max] if item[1][:max] > max_value
150
+ min_value = item[1][:min] if item[1][:min] < min_value
151
+ hits += item[1][:hits]
152
+ cumulative += item[1][:sum]
153
+ end
154
+ else
155
+ hits = 1
156
+ min_value = 0
157
+ end
158
+
159
+ puts "max.value #{max_value}"
160
+ puts "min.value #{min_value}"
161
+ puts "average.value #{cumulative / hits.to_f}"
162
+ end
163
+
164
+ # Main
165
+ if ARGV[0] == "config"
166
+ config
167
+ elsif ARGV[0] == "autoconf"
168
+ autoconf
169
+ elsif ARGV[0] == "debug"
170
+ run(LOG_FILE || ARGV[1], true)
171
+ else
172
+ run(LOG_FILE || ARGV[0])
173
+ end
@@ -0,0 +1,169 @@
1
+ #!/usr/bin/env ruby
2
+ pod=<<-POD
3
+
4
+ =head1 NAME
5
+ rails_request_error - Munin plugin to monitor the amount of errors and process blockers.
6
+
7
+ =head1 APPLICABLE SYSTEMS
8
+ All systems that have a rails application log.
9
+
10
+ =head1 CONFIGURATION
11
+ The request-log-analyzer gem has to be intalled.
12
+ Also the script has to be able to access the rails log file and tail.
13
+ This configuration section shows the defaults of the plugin:
14
+
15
+ [rails_request_error]
16
+ env.log_file '/path/to/production.log'
17
+ user www-data
18
+ command /usr/local/bin/ruby %c
19
+
20
+ Options
21
+ env.lines 50000 # Number of lines to tail
22
+ env.interval 300 # Munin interval in seconds (used for graphs and caching)
23
+ env.request_log_analyzer '/usr/local/bin' # Path to gem. Use this for Debian.
24
+ env.graph_category 'App' # Graph Category. Defaults to App.
25
+
26
+ ln -s /usr/share/munin/plugins/rails_request_error /etc/munin/plugins/rails_request_error
27
+
28
+ =head1 INTERPRETATION
29
+ Two lines are graphed, one showing the amount of errors raised and one showing the amount of process
30
+ blockers. Process blockers are requests that took longer than 1 second to complete.
31
+
32
+ =head1 MAGIC MARKERS
33
+ #%# family=auto
34
+ #%# capabilities=autoconf
35
+
36
+ =head1 VERSION
37
+ 1.5
38
+
39
+ =head1 BUGS
40
+ None known
41
+
42
+ =head1 AUTHOR
43
+ Bart ten Brinke - railsdoctors.com
44
+
45
+ =head1 LICENSE
46
+ MIT
47
+
48
+ POD
49
+
50
+ # Globals
51
+ GRAPH_CATEGORY = ENV['graph_category'] || 'App'
52
+ INTERVAL = ENV['interval'] ? ENV['interval'].to_i : 300
53
+ NUMBER_OF_LINES = ENV['lines'] || 50000
54
+ LOG_FILE = ENV['log_file']
55
+ AFTER_TIME = (Time.now - INTERVAL).strftime('%Y%m%d%H%M%S')
56
+ FLOOR_TIME = Time.at((Time.now.to_f / INTERVAL).floor * INTERVAL)
57
+
58
+ TEMP_FOLDER = '/tmp'
59
+ TEMP_PREFIX = GRAPH_CATEGORY == 'App' ? 'rla' : GRAPH_CATEGORY.downcase
60
+ TEMP_FILE = "#{TEMP_PREFIX}_#{FLOOR_TIME.to_i}.yml"
61
+ REQUEST_LOG_ANALYZER = ENV['request_log_analyzer'] || '/usr/bin/request-log-analyzer'
62
+
63
+ # Check if we can run this plugin on this system
64
+ def autoconf
65
+ begin
66
+ require 'rubygems'
67
+ gem "request-log-analyzer", ">=1.1.6"
68
+ require "yaml"
69
+ rescue Exception => e
70
+ puts "no (Gem not found: #{e})"
71
+ exit 1
72
+ end
73
+
74
+ unless `echo "test" | tail 2>/dev/null`.include?("test")
75
+ puts "no (tail command not found)"
76
+ exit 1
77
+ end
78
+
79
+ puts "yes"
80
+ exit 0
81
+ end
82
+
83
+ # Uptput the config
84
+ def config
85
+ puts <<-CONFIG
86
+ graph_category #{GRAPH_CATEGORY}
87
+ graph_title Request errors
88
+ graph_vlabel Count
89
+ graph_info The amount of request errors - railsdoctors.com
90
+
91
+ error.label error
92
+ blocker.label blocker
93
+ CONFIG
94
+ exit 0
95
+ end
96
+
97
+ # Fetch or create yaml cache file using request-log-analyzer
98
+ def fetch_or_create_yaml_file(log_file, debug = false)
99
+ # Clean up any old temp files left in de temp folder
100
+ Dir.new(TEMP_FOLDER).entries.each do |file_name|
101
+ if match = file_name.match(/^#{TEMP_PREFIX}_.*\.yml/)
102
+ if match[0] != TEMP_FILE
103
+ puts "Removing old cache file: #{file_name}" if debug
104
+ File.delete(TEMP_FOLDER + "/" + file_name)
105
+ end
106
+ end
107
+ end
108
+
109
+ temp_file = TEMP_FOLDER + "/" + TEMP_FILE
110
+
111
+ # Create temp file rla if needed
112
+ unless File.exists?(temp_file)
113
+ puts "Processing the last #{NUMBER_OF_LINES} lines of #{log_file} which are less then #{INTERVAL} seconds old." if debug
114
+ p "tail -n #{NUMBER_OF_LINES} #{log_file} | #{REQUEST_LOG_ANALYZER} - --format rails3 --after #{AFTER_TIME} -b --dump #{temp_file} 2>/dev/null"
115
+ status = `tail -n #{NUMBER_OF_LINES} #{log_file} | #{REQUEST_LOG_ANALYZER} - --format rails3 --after #{AFTER_TIME} -b --dump #{temp_file} 2>/dev/null`
116
+
117
+ unless $?.success?
118
+ $stderr.puts "failed executing request-log-analyzer. Is the path to the binary correct?"
119
+ exit 1
120
+ end
121
+ else
122
+ puts "Processing cached YAML result #{temp_file}" if debug
123
+ end
124
+
125
+ return temp_file
126
+ end
127
+
128
+ # Gather information
129
+ def run(log_file, debug = false)
130
+
131
+ if log_file == "" || log_file.nil?
132
+ $stderr.puts "Filepath unspecified. Exiting"
133
+ exit 1
134
+ end
135
+
136
+ # Initialize values
137
+ error_value = 0
138
+ blocker_value = 0
139
+
140
+ # Walk through the
141
+ require "yaml"
142
+ rla = YAML::load_file( fetch_or_create_yaml_file(log_file, debug) )
143
+
144
+ if rla && rla["Failed requests"]
145
+ rla["Failed requests"].each do |item|
146
+ error_value += item[1]
147
+ end
148
+ end
149
+
150
+ if rla && rla["Process blockers (> 1 sec duration)"]
151
+ rla["Process blockers (> 1 sec duration)"].each do |item|
152
+ blocker_value += item[1]
153
+ end
154
+ end
155
+
156
+ puts "error.value #{error_value}"
157
+ puts "blocker.value #{blocker_value}"
158
+ end
159
+
160
+ # Main
161
+ if ARGV[0] == "config"
162
+ config
163
+ elsif ARGV[0] == "autoconf"
164
+ autoconf
165
+ elsif ARGV[0] == "debug"
166
+ run(LOG_FILE || ARGV[1], true)
167
+ else
168
+ run(LOG_FILE || ARGV[0])
169
+ end
@@ -0,0 +1,175 @@
1
+ #!/usr/bin/env ruby
2
+ pod=<<-POD
3
+
4
+ =head1 NAME
5
+ rails_requests - Munin plugin to monitor the amount of get, put, post and delete requests from a
6
+ rails application log.
7
+
8
+ =head1 APPLICABLE SYSTEMS
9
+ All systems that have a rails application log.
10
+
11
+ =head1 CONFIGURATION
12
+ The request-log-analyzer gem has to be intalled.
13
+ Also the script has to be able to access the rails log file and tail.
14
+ This configuration section shows the defaults of the plugin:
15
+
16
+ [rails_requests]
17
+ env.log_file '/path/to/production.log'
18
+ user www-data
19
+ command /usr/local/bin/ruby %c
20
+
21
+ Options
22
+ env.lines 50000 # Number of lines to tail
23
+ env.interval 300 # Munin interval in seconds (used for graphs and caching)
24
+ env.request_log_analyzer '/usr/local/bin' # Path to gem. Use this for Debian.
25
+ env.graph_category 'App' # Graph Category. Defaults to App.
26
+
27
+ ln -s /usr/share/munin/plugins/rails_requests /etc/munin/plugins/rails_requests
28
+
29
+ =head1 INTERPRETATION
30
+ All HTTP methods are stacked so that the total equals the amount of requests processed per 5 minutes.
31
+
32
+ =head1 MAGIC MARKERS
33
+ #%# family=auto
34
+ #%# capabilities=autoconf
35
+
36
+ =head1 VERSION
37
+ 1.5
38
+
39
+ =head1 BUGS
40
+ None known
41
+
42
+ =head1 AUTHOR
43
+ Bart ten Brinke - railsdoctors.com
44
+
45
+ =head1 LICENSE
46
+ MIT
47
+
48
+ POD
49
+
50
+ # Globals
51
+ GRAPH_CATEGORY = ENV['graph_category'] || 'App'
52
+ INTERVAL = ENV['interval'] ? ENV['interval'].to_i : 300
53
+ NUMBER_OF_LINES = ENV['lines'] || 50000
54
+ LOG_FILE = ENV['log_file']
55
+ AFTER_TIME = (Time.now - INTERVAL).strftime('%Y%m%d%H%M%S')
56
+ FLOOR_TIME = Time.at((Time.now.to_f / INTERVAL).floor * INTERVAL)
57
+
58
+ TEMP_FOLDER = '/tmp'
59
+ TEMP_PREFIX = GRAPH_CATEGORY == 'App' ? 'rla' : GRAPH_CATEGORY.downcase
60
+ TEMP_FILE = "#{TEMP_PREFIX}_#{FLOOR_TIME.to_i}.yml"
61
+ REQUEST_LOG_ANALYZER = ENV['request_log_analyzer'] || '/usr/bin/request-log-analyzer'
62
+
63
+ # Check if we can run this plugin on this system
64
+ def autoconf
65
+ begin
66
+ require 'rubygems'
67
+ gem "request-log-analyzer", ">=1.1.6"
68
+ rescue Exception => e
69
+ puts "no (Gem not found: #{e})"
70
+ exit 1
71
+ end
72
+
73
+ unless `echo "test" | tail 2>/dev/null`.include?("test")
74
+ puts "no (tail command not found)"
75
+ exit 1
76
+ end
77
+
78
+ puts "yes"
79
+ exit 0
80
+ end
81
+
82
+ # Uptput the config
83
+ def config
84
+ puts <<-CONFIG
85
+ graph_category #{GRAPH_CATEGORY}
86
+ graph_title Processed requests
87
+ graph_vlabel Requests per second
88
+ graph_info The amount of requests processed by this application server - railsdoctors.com
89
+
90
+ get.label get
91
+ get.draw AREA
92
+ post.label post
93
+ post.draw STACK
94
+ put.label put
95
+ put.draw STACK
96
+ delete.label delete
97
+ delete.draw STACK
98
+ CONFIG
99
+ exit 0
100
+ end
101
+
102
+ # Fetch or create yaml cache file using request-log-analyzer
103
+ def fetch_or_create_yaml_file(log_file, debug = false)
104
+ # Clean up any old temp files left in de temp folder
105
+ Dir.new(TEMP_FOLDER).entries.each do |file_name|
106
+ if match = file_name.match(/^#{TEMP_PREFIX}_.*\.yml/)
107
+ if match[0] != TEMP_FILE
108
+ puts "Removing old cache file: #{file_name}" if debug
109
+ File.delete(TEMP_FOLDER + "/" + file_name)
110
+ end
111
+ end
112
+ end
113
+
114
+ temp_file = TEMP_FOLDER + "/" + TEMP_FILE
115
+
116
+ # Create temp file rla if needed
117
+ unless File.exists?(temp_file)
118
+ puts "Processing the last #{NUMBER_OF_LINES} lines of #{log_file} which are less then #{INTERVAL} seconds old." if debug
119
+ p "tail -n #{NUMBER_OF_LINES} #{log_file} | #{REQUEST_LOG_ANALYZER} - --format rails3 --after #{AFTER_TIME} -b --dump #{temp_file} 2>/dev/null"
120
+ status = `tail -n #{NUMBER_OF_LINES} #{log_file} | #{REQUEST_LOG_ANALYZER} - --format rails3 --after #{AFTER_TIME} -b --dump #{temp_file} 2>/dev/null`
121
+
122
+ unless $?.success?
123
+ $stderr.puts "failed executing request-log-analyzer. Is the path to the binary correct?"
124
+ exit 1
125
+ end
126
+ else
127
+ puts "Processing cached YAML result #{temp_file}" if debug
128
+ end
129
+
130
+ return temp_file
131
+ end
132
+
133
+ # Gather information
134
+ def run(log_file, debug = false)
135
+
136
+ if log_file == "" || log_file.nil?
137
+ $stderr.puts "Filepath unspecified. Exiting"
138
+ exit 1
139
+ end
140
+
141
+ # Initialize values
142
+ get_value = 0
143
+ post_value = 0
144
+ put_value = 0
145
+ delete_value = 0
146
+
147
+ # Walk through the
148
+ File.open(fetch_or_create_yaml_file(log_file, debug)).each_line{ |line|
149
+ if match = line.match(/^\s+GET\:\s(\d+).*/)
150
+ get_value = match[1].to_i
151
+ elsif match = line.match(/^\s+POST\:\s(\d+).*/)
152
+ post_value = match[1].to_i
153
+ elsif match = line.match(/^\s+PUT\:\s(\d+).*/)
154
+ put_value = match[1].to_i
155
+ elsif match = line.match(/^\s+DELETE\:\s(\d+).*/)
156
+ delete_value = match[1].to_i
157
+ end
158
+ }
159
+
160
+ puts "get.value #{get_value / INTERVAL.to_f}"
161
+ puts "post.value #{post_value / INTERVAL.to_f}"
162
+ puts "put.value #{put_value / INTERVAL.to_f}"
163
+ puts "delete.value #{delete_value / INTERVAL.to_f}"
164
+ end
165
+
166
+ # Main
167
+ if ARGV[0] == "config"
168
+ config
169
+ elsif ARGV[0] == "autoconf"
170
+ autoconf
171
+ elsif ARGV[0] == "debug"
172
+ run(LOG_FILE || ARGV[1], true)
173
+ else
174
+ run(LOG_FILE || ARGV[0])
175
+ end