adminix 0.1.49 → 0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -0
  3. data/adminix.gemspec +1 -4
  4. data/app/assets/images/logo.png +0 -0
  5. data/app/assets/javascripts/application.js +50 -0
  6. data/app/assets/javascripts/bootstrap.min.js +7 -0
  7. data/app/assets/javascripts/dataTables.bootstrap4.js +184 -0
  8. data/app/assets/javascripts/jquery.dataTables.js +15243 -0
  9. data/app/assets/javascripts/jquery.min.js +2 -0
  10. data/app/assets/javascripts/sb-admin-2.min.js +6 -0
  11. data/app/assets/stylesheets/bootstrap.min.css +6 -0
  12. data/app/assets/stylesheets/dataTables.bootstrap.css +314 -0
  13. data/app/assets/stylesheets/dataTables.responsive.css +106 -0
  14. data/app/assets/stylesheets/font-awesome.min.css +4 -0
  15. data/app/assets/stylesheets/sb-admin-2.min.css +5 -0
  16. data/app/views/scripts/restart_watcher.sh.erb +9 -0
  17. data/app/views/scripts/run_script.sh.erb +12 -0
  18. data/app/views/scripts/start_process.sh.erb +7 -0
  19. data/app/views/scripts/stop_process.sh.erb +7 -0
  20. data/app/views/scripts/update_process.sh.erb +24 -0
  21. data/app/views/scripts/update_watcher.sh.erb +3 -0
  22. data/app/views/web/dashboard.html.erb +90 -0
  23. data/app/views/web/job.html.erb +46 -0
  24. data/app/views/web/link.html.erb +12 -0
  25. data/app/views/web/loadstamp.html.erb +57 -0
  26. data/app/views/web/log.html.erb +49 -0
  27. data/app/views/web/partials/footer.html.erb +11 -0
  28. data/app/views/web/partials/header.html.erb +50 -0
  29. data/bin/install_adminix +40 -0
  30. data/bin/push +13 -0
  31. data/development.log +0 -0
  32. data/exe/adminix +91 -28
  33. data/lib/adminix.rb +42 -5
  34. data/lib/adminix/config.rb +170 -96
  35. data/lib/adminix/entities.rb +5 -0
  36. data/lib/adminix/entities/job.rb +54 -0
  37. data/lib/adminix/entities/log.rb +21 -0
  38. data/lib/adminix/entities/service.rb +211 -0
  39. data/lib/adminix/entities/sysload_stamp.rb +37 -0
  40. data/lib/adminix/entities/variable.rb +32 -0
  41. data/lib/adminix/helpers.rb +7 -2
  42. data/lib/adminix/helpers/command.rb +73 -0
  43. data/lib/adminix/helpers/files.rb +82 -0
  44. data/lib/adminix/helpers/log_reader.rb +16 -0
  45. data/lib/adminix/helpers/net_http.rb +63 -0
  46. data/lib/adminix/helpers/output.rb +28 -0
  47. data/lib/adminix/helpers/systemctl.rb +54 -0
  48. data/lib/adminix/services.rb +3 -0
  49. data/lib/adminix/services/app_service.rb +143 -0
  50. data/lib/adminix/services/logs_service.rb +13 -0
  51. data/lib/adminix/services/system_load_service.rb +16 -0
  52. data/lib/adminix/version.rb +1 -1
  53. data/lib/adminix/watcher.rb +76 -144
  54. data/lib/adminix/web.rb +4 -0
  55. data/lib/adminix/web/router.rb +98 -0
  56. data/lib/adminix/web/server.rb +60 -0
  57. data/lib/adminix/web/view_helper.rb +14 -0
  58. data/lib/event_machine.rb +2 -0
  59. data/lib/event_machine/http_server.rb +2 -0
  60. data/lib/event_machine/http_server/response.rb +314 -0
  61. data/lib/event_machine/http_server/server.rb +107 -0
  62. data/lib/event_machine/tail.rb +2 -0
  63. data/lib/event_machine/tail/filetail.rb +470 -0
  64. data/lib/event_machine/tail/globwatcher.rb +294 -0
  65. metadata +60 -45
  66. data/lib/adminix/errors.rb +0 -7
  67. data/lib/adminix/helpers/file.rb +0 -13
  68. data/lib/adminix/helpers/http.rb +0 -19
  69. data/lib/adminix/log_watch_handler.rb +0 -23
  70. data/lib/adminix/server_setup.rb +0 -76
  71. data/lib/adminix/service.rb +0 -179
  72. data/lib/adminix/setup.rb +0 -3
  73. data/lib/adminix/setup/routes.rb +0 -113
  74. data/lib/adminix/setup/services.rb +0 -139
  75. data/lib/adminix/setup/views.rb +0 -183
  76. data/lib/adminix/system.rb +0 -106
  77. data/views/daemon_scripts/upstart.conf.erb +0 -23
@@ -0,0 +1,294 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative "filetail"
4
+ require "eventmachine"
5
+ require "logger"
6
+ require "set"
7
+
8
+ EventMachine.epoll if EventMachine.epoll?
9
+ EventMachine.kqueue = true if EventMachine.kqueue?
10
+
11
+ # A file glob pattern watcher for EventMachine.
12
+ #
13
+ # If you are unfamiliar with globs, see Wikipedia:
14
+ # http://en.wikipedia.org/wiki/Glob_(programming)
15
+ #
16
+ # Any glob supported by Dir#glob will work with
17
+ # this class.
18
+ #
19
+ # This class will allow you to get notified whenever a file
20
+ # is created or deleted that matches your glob.
21
+ #
22
+ # If you are subclassing, here are the methods you should implement:
23
+ # file_found(path)
24
+ # file_deleted(path)
25
+ #
26
+ # See alsoe
27
+ # * EventMachine::watch_glob
28
+ # * EventMachine::FileGlobWatch#file_found
29
+ # * EventMachine::FileGlobWatch#file_deleted
30
+ #
31
+ class EventMachine::FileGlobWatch
32
+ # Watch a glob
33
+ #
34
+ # * glob - a string path or glob, such as "/var/log/*.log"
35
+ # * interval - number of seconds between scanning the glob for changes
36
+ def initialize(glob, interval=60)
37
+ @glob = glob
38
+ @files = Hash.new
39
+ @watches = Hash.new
40
+ @logger = Logger.new(STDOUT)
41
+ @logger.level = ($DEBUG and Logger::DEBUG or Logger::WARN)
42
+ @interval = interval
43
+ start
44
+ end # def initialize
45
+
46
+ # This method may be called to stop watching
47
+ # TODO(sissel): make 'stop' stop all active watches, too?
48
+ public
49
+ def stop
50
+ @find_files_interval.cancel if @find_files_interval
51
+ end
52
+
53
+ # This method may be called to start watching
54
+ #
55
+ public
56
+ def start
57
+ # We periodically check here because it is easier than writing our own glob
58
+ # parser (so we can smartly watch globs like /foo/*/bar*/*.log)
59
+ #
60
+ # Reasons to fix this -
61
+ # This will likely perform badly on globs that result in a large number of
62
+ # files.
63
+ EM.next_tick do
64
+ find_files
65
+ @find_files_interval = EM.add_periodic_timer(@interval) do
66
+ find_files
67
+ end
68
+ end # EM.next_tick
69
+ end
70
+
71
+ # This method is called when a new file is found
72
+ #
73
+ # * path - the string path of the file found
74
+ #
75
+ # You must implement this in your subclass or module for it
76
+ # to work with EventMachine::watch_glob
77
+ public
78
+ def file_found(path)
79
+ raise NotImplementedError.new("#{self.class.name}#file_found is not "\
80
+ "implemented. Did you forget to implement this in your subclass or "\
81
+ "module?")
82
+ end # def file_found
83
+
84
+ # This method is called when a file is deleted.
85
+ #
86
+ # * path - the string path of the file deleted
87
+ #
88
+ # You must implement this in your subclass or module for it
89
+ # to work with EventMachine::watch_glob
90
+ public
91
+ def file_deleted(path)
92
+ raise NotImplementedError.new("#{self.class.name}#file_deleted is not "\
93
+ "implemented. Did you forget to implement this in your subclass or "\
94
+ "module?")
95
+ end # def file_found
96
+
97
+ private
98
+ def find_files
99
+ @logger.info("Searching for files in #{@glob}")
100
+ list = Dir.glob(@glob)
101
+
102
+ known_files = @files.clone
103
+ list.each do |path|
104
+ fileinfo = FileInfo.new(path) rescue next
105
+ # Skip files that have the same inode (renamed or hardlinked)
106
+ known_files.delete(fileinfo.stat.ino)
107
+ next if @files.include?(fileinfo.stat.ino)
108
+
109
+ track(fileinfo)
110
+ file_found(path)
111
+ end
112
+
113
+ # Report missing files.
114
+ known_files.each do |inode, fileinfo|
115
+ remove(fileinfo)
116
+ end
117
+ end # def find_files
118
+
119
+ # Remove a file from being watched and notify file_deleted()
120
+ private
121
+ def remove(fileinfo)
122
+ @files.delete(fileinfo.stat.ino)
123
+ @watches.delete(fileinfo.path)
124
+ file_deleted(fileinfo.path)
125
+ end # def remove
126
+
127
+ # Add a file to watch and notify file_found()
128
+ private
129
+ def track(fileinfo)
130
+ @files[fileinfo.stat.ino] = fileinfo
131
+
132
+ # If EventMachine::watch_file fails, that's ok, I guess.
133
+ # We'll still find the file 'missing' from the next glob attempt.
134
+ #begin
135
+ # EM currently has a bug that only the first handler for a watch_file
136
+ # on each file gets events. This causes globtails to never get data
137
+ # since the glob is watching the file already.
138
+ # Until we fix that, let's skip file watching here.
139
+ #@watches[path] = EventMachine::watch_file(path, FileWatcher, self) do |path|
140
+ # remove(path)
141
+ #end
142
+ #rescue Errno::EACCES => e
143
+ #@logger.warn(e)
144
+ #end
145
+ end # def watch
146
+
147
+ private
148
+ class FileWatcher < EventMachine::FileWatch
149
+ def initialize(globwatch, &block)
150
+ @globwatch = globwatch
151
+ @block = block
152
+ end
153
+
154
+ def file_moved
155
+ stop_watching
156
+ block.call path
157
+ end
158
+
159
+ def file_deleted
160
+ block.call path
161
+ end
162
+ end # class EventMachine::FileGlobWatch::FileWatcher < EventMachine::FileWatch
163
+
164
+ private
165
+ class FileInfo
166
+ attr_reader :path
167
+ attr_reader :stat
168
+
169
+ def initialize(path)
170
+ @path = path
171
+ @stat = File.stat(path)
172
+ end
173
+ end # class FileInfo
174
+ end # class EventMachine::FileGlobWatch
175
+
176
+ # A glob tailer for EventMachine
177
+ #
178
+ # This class combines features of EventMachine::file_tail and
179
+ # EventMachine::watch_glob.
180
+ #
181
+ # You won't generally subclass this class (See EventMachine::FileGlobWatch)
182
+ #
183
+ # See also: EventMachine::glob_tail
184
+ #
185
+ class EventMachine::FileGlobWatchTail < EventMachine::FileGlobWatch
186
+ # Initialize a new file glob tail.
187
+ #
188
+ # * path - glob or file path (string)
189
+ # * handler - a module or subclass of EventMachine::FileTail
190
+ # See also EventMachine::file_tail
191
+ # * interval - how often (seconds) the glob path should be scanned
192
+ # * exclude - an array of Regexp (or anything with .match) for
193
+ # excluding from things to tail
194
+ #
195
+ # The remainder of arguments are passed to EventMachine::file_tail as
196
+ # EventMachine::file_tail(path_found, handler, *args, &block)
197
+ public
198
+ def initialize(path, handler=nil, interval=60, exclude=[], *args, &block)
199
+ super(path, interval)
200
+ @handler = handler
201
+ @args = args
202
+ @exclude = exclude
203
+
204
+ if block_given?
205
+ @handler = block
206
+ end
207
+ end # def initialize
208
+
209
+ public
210
+ def file_found(path)
211
+ begin
212
+ @logger.info "#{self.class}: Trying #{path}"
213
+ @exclude.each do |exclude|
214
+ @logger.info "#{self.class}: Testing #{exclude} =~ #{path} == #{exclude.match(path) != nil}"
215
+ if exclude.match(path) != nil
216
+ file_excluded(path)
217
+ return
218
+ end
219
+ end
220
+ @logger.info "#{self.class}: Watching #{path}"
221
+
222
+ if @handler.is_a? Proc
223
+ EventMachine::file_tail(path, nil, *@args, &@handler)
224
+ else
225
+ EventMachine::file_tail(path, @handler, *@args)
226
+ end
227
+ rescue Errno::EACCES => e
228
+ file_error(path, e)
229
+ rescue Errno::EISDIR => e
230
+ file_error(path, e)
231
+ end
232
+ end # def file_found
233
+
234
+ public
235
+ def file_excluded(path)
236
+ @logger.info "#{self.class}: Skipping path #{path} due to exclude rule"
237
+ end # def file_excluded
238
+
239
+ public
240
+ def file_deleted(path)
241
+ # Nothing to do
242
+ end # def file_deleted
243
+
244
+ public
245
+ def file_error(path, e)
246
+ $stderr.puts "#{e.class} while trying to tail #{path}"
247
+ # otherwise, drop the error by default
248
+ end # def file_error
249
+ end # class EventMachine::FileGlobWatchHandler
250
+
251
+ module EventMachine
252
+ # Watch a glob and tail any files found.
253
+ #
254
+ # * glob - a string path or glob, such as /var/log/*.log
255
+ # * handler - a module or subclass of EventMachine::FileGlobWatchTail.
256
+ # handler can be omitted if you give a block.
257
+ #
258
+ # If you give a block and omit the handler parameter, then the behavior
259
+ # is that your block is called for every line read from any file the same
260
+ # way EventMachine::file_tail does when called with a block.
261
+ #
262
+ # See EventMachine::FileGlobWatchTail for the callback methods.
263
+ # See EventMachine::file_tail for more information about block behavior.
264
+ def self.glob_tail(glob, handler=nil, *args, &block)
265
+ handler = EventMachine::FileGlobWatchTail if handler == nil
266
+ args.unshift(glob)
267
+ klass = klass_from_handler(EventMachine::FileGlobWatchTail, handler, *args)
268
+ c = klass.new(*args, &block)
269
+ return c
270
+ end
271
+
272
+ # Watch a glob for any files.
273
+ #
274
+ # * glob - a string path or glob, such as "/var/log/*.log"
275
+ # * handler - must be a module or a subclass of EventMachine::FileGlobWatch
276
+ #
277
+ # The remaining (optional) arguments are passed to your handler like this:
278
+ # If you call this:
279
+ # EventMachine.watch_glob("/var/log/*.log", YourHandler, 1, 2, 3, ...)
280
+ # This will be invoked when new matching files are found:
281
+ # YourHandler.new(path_found, 1, 2, 3, ...)
282
+ # ^ path_found is the new path found by the glob
283
+ #
284
+ # See EventMachine::FileGlobWatch for the callback methods.
285
+ def self.watch_glob(glob, handler=nil, *args)
286
+ # This code mostly styled on what EventMachine does in many of it's other
287
+ # methods.
288
+ args = [glob, *args]
289
+ klass = klass_from_handler(EventMachine::FileGlobWatch, handler, *args);
290
+ c = klass.new(*args)
291
+ yield c if block_given?
292
+ return c
293
+ end # def EventMachine::watch_glob
294
+ end # module EventMachine
metadata CHANGED
@@ -1,43 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: adminix
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.49
4
+ version: '0.2'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Christian Dyl
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-05-16 00:00:00.000000000 Z
11
+ date: 2018-10-15 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: eventmachine
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - '='
18
- - !ruby/object:Gem::Version
19
- version: 1.2.5
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - '='
25
- - !ruby/object:Gem::Version
26
- version: 1.2.5
27
- - !ruby/object:Gem::Dependency
28
- name: action_cable_client
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - '='
32
- - !ruby/object:Gem::Version
33
- version: 2.0.2
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - '='
39
- - !ruby/object:Gem::Version
40
- version: 2.0.2
41
13
  - !ruby/object:Gem::Dependency
42
14
  name: json
43
15
  requirement: !ruby/object:Gem::Requirement
@@ -67,19 +39,19 @@ dependencies:
67
39
  - !ruby/object:Gem::Version
68
40
  version: 2.1.0
69
41
  - !ruby/object:Gem::Dependency
70
- name: sinatra
42
+ name: eventmachine
71
43
  requirement: !ruby/object:Gem::Requirement
72
44
  requirements:
73
45
  - - '='
74
46
  - !ruby/object:Gem::Version
75
- version: 2.0.0
47
+ version: 1.2.7
76
48
  type: :runtime
77
49
  prerelease: false
78
50
  version_requirements: !ruby/object:Gem::Requirement
79
51
  requirements:
80
52
  - - '='
81
53
  - !ruby/object:Gem::Version
82
- version: 2.0.0
54
+ version: 1.2.7
83
55
  - !ruby/object:Gem::Dependency
84
56
  name: bundler
85
57
  requirement: !ruby/object:Gem::Requirement
@@ -179,27 +151,70 @@ files:
179
151
  - README.md
180
152
  - Rakefile
181
153
  - adminix.gemspec
154
+ - app/assets/images/logo.png
155
+ - app/assets/javascripts/application.js
156
+ - app/assets/javascripts/bootstrap.min.js
157
+ - app/assets/javascripts/dataTables.bootstrap4.js
158
+ - app/assets/javascripts/jquery.dataTables.js
159
+ - app/assets/javascripts/jquery.min.js
160
+ - app/assets/javascripts/sb-admin-2.min.js
161
+ - app/assets/stylesheets/bootstrap.min.css
162
+ - app/assets/stylesheets/dataTables.bootstrap.css
163
+ - app/assets/stylesheets/dataTables.responsive.css
164
+ - app/assets/stylesheets/font-awesome.min.css
165
+ - app/assets/stylesheets/sb-admin-2.min.css
166
+ - app/views/scripts/restart_watcher.sh.erb
167
+ - app/views/scripts/run_script.sh.erb
168
+ - app/views/scripts/start_process.sh.erb
169
+ - app/views/scripts/stop_process.sh.erb
170
+ - app/views/scripts/update_process.sh.erb
171
+ - app/views/scripts/update_watcher.sh.erb
172
+ - app/views/web/dashboard.html.erb
173
+ - app/views/web/job.html.erb
174
+ - app/views/web/link.html.erb
175
+ - app/views/web/loadstamp.html.erb
176
+ - app/views/web/log.html.erb
177
+ - app/views/web/partials/footer.html.erb
178
+ - app/views/web/partials/header.html.erb
182
179
  - bin/build
183
180
  - bin/console
181
+ - bin/install_adminix
182
+ - bin/push
184
183
  - bin/setup
184
+ - development.log
185
185
  - exe/adminix
186
186
  - lib/adminix.rb
187
187
  - lib/adminix/config.rb
188
- - lib/adminix/errors.rb
188
+ - lib/adminix/entities.rb
189
+ - lib/adminix/entities/job.rb
190
+ - lib/adminix/entities/log.rb
191
+ - lib/adminix/entities/service.rb
192
+ - lib/adminix/entities/sysload_stamp.rb
193
+ - lib/adminix/entities/variable.rb
189
194
  - lib/adminix/helpers.rb
190
- - lib/adminix/helpers/file.rb
191
- - lib/adminix/helpers/http.rb
192
- - lib/adminix/log_watch_handler.rb
193
- - lib/adminix/server_setup.rb
194
- - lib/adminix/service.rb
195
- - lib/adminix/setup.rb
196
- - lib/adminix/setup/routes.rb
197
- - lib/adminix/setup/services.rb
198
- - lib/adminix/setup/views.rb
199
- - lib/adminix/system.rb
195
+ - lib/adminix/helpers/command.rb
196
+ - lib/adminix/helpers/files.rb
197
+ - lib/adminix/helpers/log_reader.rb
198
+ - lib/adminix/helpers/net_http.rb
199
+ - lib/adminix/helpers/output.rb
200
+ - lib/adminix/helpers/systemctl.rb
201
+ - lib/adminix/services.rb
202
+ - lib/adminix/services/app_service.rb
203
+ - lib/adminix/services/logs_service.rb
204
+ - lib/adminix/services/system_load_service.rb
200
205
  - lib/adminix/version.rb
201
206
  - lib/adminix/watcher.rb
202
- - views/daemon_scripts/upstart.conf.erb
207
+ - lib/adminix/web.rb
208
+ - lib/adminix/web/router.rb
209
+ - lib/adminix/web/server.rb
210
+ - lib/adminix/web/view_helper.rb
211
+ - lib/event_machine.rb
212
+ - lib/event_machine/http_server.rb
213
+ - lib/event_machine/http_server/response.rb
214
+ - lib/event_machine/http_server/server.rb
215
+ - lib/event_machine/tail.rb
216
+ - lib/event_machine/tail/filetail.rb
217
+ - lib/event_machine/tail/globwatcher.rb
203
218
  homepage: https://adminix.io
204
219
  licenses:
205
220
  - MIT
@@ -1,7 +0,0 @@
1
- require 'airbrake-ruby'
2
-
3
- Airbrake.configure do |c|
4
- c.host = 'http://ec2-18-217-189-42.us-east-2.compute.amazonaws.com'
5
- c.project_id = 1 # required, but any positive integer works
6
- c.project_key = 'efb1c025d1abb9c4ccb828ebaf9ea68f'
7
- end