fluent-plugin-event-sniffer 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +26 -0
- data/Gemfile +4 -0
- data/Gruntfile.coffee +59 -0
- data/LICENSE.txt +13 -0
- data/Procfile +2 -0
- data/README.md +29 -0
- data/Rakefile +2 -0
- data/bower.json +17 -0
- data/dummer.conf +13 -0
- data/example.conf +23 -0
- data/fluent-plugin-event-sniffer.gemspec +31 -0
- data/lib/fluent/plugin/eventsniffer/app.rb +74 -0
- data/lib/fluent/plugin/eventsniffer/engine_util.rb +57 -0
- data/lib/fluent/plugin/in_event_sniffer.rb +62 -0
- data/package.json +12 -0
- data/src/coffee/app.coffee +96 -0
- data/src/stylus/app.stylus +29 -0
- data/views/index.slim +59 -0
- data/views/layout.slim +30 -0
- metadata +214 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: ca201c293444240925efea476d1bf9c21a12f1bd
|
4
|
+
data.tar.gz: d65c37ba4b3721cdfb188cd5971ff9cf36f4c571
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d097a271a3541a2ee5fefc00bbb7497c5c590ccb1ccc46d3969fb27a86384425589898c36c851a5053be2181414532a7567a699788a71d02b776a8facb8c902b
|
7
|
+
data.tar.gz: 9b9d096cd1221396b453b4c5374c2778a74bc38b50ad3d94e758bfbcf12ba9d7d15f8e42f1e3f167aa63dfbd859a23d61aee1c0f93ea17857a6a7bfb6673cf25
|
data/.gitignore
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
*.bundle
|
19
|
+
*.so
|
20
|
+
*.o
|
21
|
+
*.a
|
22
|
+
mkmf.log
|
23
|
+
|
24
|
+
node_modules
|
25
|
+
bower_components
|
26
|
+
public
|
data/Gemfile
ADDED
data/Gruntfile.coffee
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
module.exports = (grunt)->
|
2
|
+
grunt.initConfig
|
3
|
+
pkg: grunt.file.readJSON 'package.json'
|
4
|
+
|
5
|
+
bower:
|
6
|
+
install:
|
7
|
+
options:
|
8
|
+
targetDir: './public/vendor'
|
9
|
+
install: true
|
10
|
+
verbose: false
|
11
|
+
cleanTargetDir: true
|
12
|
+
cleanBowerDir: false
|
13
|
+
layout: 'byComponent'
|
14
|
+
|
15
|
+
watch:
|
16
|
+
coffee:
|
17
|
+
files: ['src/coffee/**/*.coffee']
|
18
|
+
tasks: 'coffee'
|
19
|
+
stylus:
|
20
|
+
files: ['src/stylus/**/*.stylus']
|
21
|
+
tasks: 'stylus'
|
22
|
+
views:
|
23
|
+
files: ['views/**/*.slim']
|
24
|
+
ruby:
|
25
|
+
files: ['lib/**/*.rb']
|
26
|
+
|
27
|
+
coffee:
|
28
|
+
compile:
|
29
|
+
options:
|
30
|
+
join: true
|
31
|
+
files:
|
32
|
+
'public/js/app.js': 'src/coffee/*.coffee'
|
33
|
+
|
34
|
+
stylus:
|
35
|
+
compile:
|
36
|
+
files:
|
37
|
+
'public/css/app.css': 'src/stylus/*.stylus'
|
38
|
+
|
39
|
+
clean:
|
40
|
+
build: ['public/js', 'public/css']
|
41
|
+
install: ['public/vendor', 'vendor/bundle']
|
42
|
+
bower: ['bower_components']
|
43
|
+
npm: ['node_modules']
|
44
|
+
|
45
|
+
shell:
|
46
|
+
bundleInstall:
|
47
|
+
command: 'bundle install --path=vendor/bundle'
|
48
|
+
|
49
|
+
grunt.loadNpmTasks 'grunt-bower-task'
|
50
|
+
grunt.loadNpmTasks 'grunt-contrib-coffee'
|
51
|
+
grunt.loadNpmTasks 'grunt-contrib-watch'
|
52
|
+
grunt.loadNpmTasks 'grunt-contrib-stylus'
|
53
|
+
grunt.loadNpmTasks 'grunt-contrib-clean'
|
54
|
+
grunt.loadNpmTasks 'grunt-shell'
|
55
|
+
|
56
|
+
grunt.registerTask 'install', ['bower:install', 'shell:bundleInstall']
|
57
|
+
grunt.registerTask 'build', ['coffee', 'stylus']
|
58
|
+
grunt.registerTask 'init', ['install', 'build']
|
59
|
+
grunt.registerTask 'default', ['watch']
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
Copyright 2014 OKUNO Akihiro
|
2
|
+
|
3
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
you may not use this file except in compliance with the License.
|
5
|
+
You may obtain a copy of the License at
|
6
|
+
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
|
9
|
+
Unless required by applicable law or agreed to in writing, software
|
10
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
See the License for the specific language governing permissions and
|
13
|
+
limitations under the License.
|
data/Procfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# Fluent::Plugin::Event::Sniffer
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'fluent-plugin-event-sniffer'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install fluent-plugin-event-sniffer
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
1. Fork it ( https://github.com/[my-github-username]/fluent-plugin-event-sniffer/fork )
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/bower.json
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
{
|
2
|
+
"name": "fluent-plugin-event-sniffer",
|
3
|
+
"private": true,
|
4
|
+
"dependencies": {
|
5
|
+
"knockoutjs": "~3.1.0",
|
6
|
+
"jquery": "~2.1.1",
|
7
|
+
"bootstrap": "~3.2.0",
|
8
|
+
"underscore": "~1.6.0"
|
9
|
+
},
|
10
|
+
"exportsOverride": {
|
11
|
+
"bootstrap": {
|
12
|
+
"css": "dist/css/bootstrap.css",
|
13
|
+
"js": "dist/js/bootstrap.js",
|
14
|
+
"fonts": "dist/fonts/*"
|
15
|
+
}
|
16
|
+
}
|
17
|
+
}
|
data/dummer.conf
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
configure 'sample' do
|
2
|
+
output "dummy.log"
|
3
|
+
rate 10
|
4
|
+
delimiter "\t"
|
5
|
+
labeled true
|
6
|
+
field :id, type: :integer, countup: true, format: "%04d"
|
7
|
+
field :time, type: :datetime, format: "[%Y-%m-%d %H:%M:%S]", random: false
|
8
|
+
field :level, type: :string, any: %w[DEBUG INFO WARN ERROR]
|
9
|
+
field :method, type: :string, any: %w[GET POST PUT]
|
10
|
+
field :uri, type: :string, any: %w[/api/v1/people /api/v1/textdata]
|
11
|
+
field :reqtime, type: :float, range: 0.1..5.0
|
12
|
+
field :foobar, type: :string, length: 8
|
13
|
+
end
|
data/example.conf
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
<source>
|
2
|
+
type forward
|
3
|
+
</source>
|
4
|
+
|
5
|
+
<source>
|
6
|
+
type tail
|
7
|
+
path dummy.log
|
8
|
+
tag dummy.log
|
9
|
+
format ltsv
|
10
|
+
</source>
|
11
|
+
|
12
|
+
<source>
|
13
|
+
type event_sniffer
|
14
|
+
development true
|
15
|
+
pattern_bookmarks [
|
16
|
+
"test.**",
|
17
|
+
"debug.**"
|
18
|
+
]
|
19
|
+
</source>
|
20
|
+
|
21
|
+
<match **>
|
22
|
+
type null
|
23
|
+
</match>
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "fluent-plugin-event-sniffer"
|
7
|
+
spec.version = "0.0.1"
|
8
|
+
spec.authors = ["OKUNO Akihiro"]
|
9
|
+
spec.email = ["choplin.choplin@gmail.com"]
|
10
|
+
spec.summary = %q{Fluentd Event Sniffer}
|
11
|
+
spec.description = %q{Fluentd plugin which serves web application sniffing streaming events}
|
12
|
+
spec.homepage = "https://github.com/choplin/fluent-plugin-event-sniffer"
|
13
|
+
spec.license = "Apache-2.0"
|
14
|
+
|
15
|
+
spec.files = `git ls-files -z`.split("\x0") + Dir['public/**/*']
|
16
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
|
+
spec.require_paths = ["lib"]
|
19
|
+
|
20
|
+
spec.add_runtime_dependency "fluentd"
|
21
|
+
spec.add_runtime_dependency "sinatra"
|
22
|
+
spec.add_runtime_dependency "sinatra-rocketio"
|
23
|
+
spec.add_runtime_dependency "thin"
|
24
|
+
spec.add_runtime_dependency "slim"
|
25
|
+
|
26
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
27
|
+
spec.add_development_dependency "rake"
|
28
|
+
spec.add_development_dependency "sinatra-contrib"
|
29
|
+
spec.add_development_dependency "foreman"
|
30
|
+
spec.add_development_dependency "dummer"
|
31
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'sinatra/base'
|
2
|
+
require 'sinatra/rocketio'
|
3
|
+
require 'slim'
|
4
|
+
|
5
|
+
require_relative 'engine_util'
|
6
|
+
|
7
|
+
module Fluent
|
8
|
+
module EventSnifferPlugin
|
9
|
+
class App < Sinatra::Base
|
10
|
+
configure :development do
|
11
|
+
require 'sinatra/reloader'
|
12
|
+
register Sinatra::Reloader
|
13
|
+
end
|
14
|
+
|
15
|
+
register Sinatra::RocketIO
|
16
|
+
io = Sinatra::RocketIO
|
17
|
+
|
18
|
+
set :root, File.expand_path('../../../../../', __FILE__)
|
19
|
+
|
20
|
+
current_timer = nil
|
21
|
+
current_session = nil
|
22
|
+
|
23
|
+
get '/' do
|
24
|
+
@pattern_bookmarks = settings.pattern_bookmarks
|
25
|
+
slim :index
|
26
|
+
end
|
27
|
+
|
28
|
+
post '/pattern' do
|
29
|
+
if not current_timer.nil?
|
30
|
+
halt 503
|
31
|
+
end
|
32
|
+
|
33
|
+
EngineUtil.sniff(params[:pattern], settings.max_events)
|
34
|
+
|
35
|
+
current_timer = EM::PeriodicTimer.new(1) do
|
36
|
+
res = EngineUtil.get_sniffed_results
|
37
|
+
$log.debug res
|
38
|
+
io.push(:event, res) if res.size > 0
|
39
|
+
end
|
40
|
+
current_session = params[:rocketio_session]
|
41
|
+
|
42
|
+
status 200
|
43
|
+
body ''
|
44
|
+
end
|
45
|
+
|
46
|
+
delete '/pattern' do
|
47
|
+
if not current_timer.nil?
|
48
|
+
current_timer.cancel
|
49
|
+
current_timer = nil
|
50
|
+
current_session = nil
|
51
|
+
EngineUtil.restore
|
52
|
+
end
|
53
|
+
status 200
|
54
|
+
body ''
|
55
|
+
end
|
56
|
+
|
57
|
+
io.on :connect do |client|
|
58
|
+
$log.debug "new client available - <#{client.session}> type:#{client.type} from:#{client.address}"
|
59
|
+
end
|
60
|
+
|
61
|
+
io.on :disconnect do |client|
|
62
|
+
$log.debug "disconnect client - <#{client.session}> type:#{client.type} from:#{client.address}"
|
63
|
+
if not current_timer.nil? and current_session == client.session
|
64
|
+
current_timer.cancel
|
65
|
+
current_timer = nil
|
66
|
+
current_session = nil
|
67
|
+
p 'restore'
|
68
|
+
EngineUtil.restore
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Fluent
|
2
|
+
module EventSnifferPlugin
|
3
|
+
module EngineUtil
|
4
|
+
def self.sniff(pattern, max_events)
|
5
|
+
$log.info "start to sniff with pattern '#{pattern}'"
|
6
|
+
|
7
|
+
Engine.instance_eval do
|
8
|
+
alias :original_emit_staream :emit_stream
|
9
|
+
@sniff_match_pattern = Fluent::MatchPattern.create(pattern)
|
10
|
+
@sniff_match_cache = {}
|
11
|
+
@sniff_buf = []
|
12
|
+
@sniff_max_events = max_events
|
13
|
+
|
14
|
+
def emit_stream(tag, es)
|
15
|
+
if @sniff_buf.size < @sniff_max_events
|
16
|
+
matched = @sniff_match_cache[tag]
|
17
|
+
|
18
|
+
if matched.nil?
|
19
|
+
matched = @sniff_match_pattern.match(tag)
|
20
|
+
@sniff_match_cache[tag] = matched
|
21
|
+
end
|
22
|
+
|
23
|
+
if matched
|
24
|
+
es.dup.each do |time, record|
|
25
|
+
@sniff_buf.push({tag:tag, time:time, record:record})
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
original_emit_staream(tag, es)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.restore
|
36
|
+
$log.info "restore original Engine"
|
37
|
+
Engine.instance_eval do
|
38
|
+
alias :emit_stream :original_emit_staream
|
39
|
+
undef :original_emit_staream
|
40
|
+
@sniff_match_pattern = nil
|
41
|
+
@sniff_match_cache = nil
|
42
|
+
@sniff_buf = nil
|
43
|
+
@sniff_max_events = nil
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.get_sniffed_results
|
48
|
+
Engine.instance_eval do
|
49
|
+
res = @sniff_buf
|
50
|
+
@sniff_buf = []
|
51
|
+
res
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'thin'
|
2
|
+
|
3
|
+
module Fluent
|
4
|
+
class EventSniffer < Input
|
5
|
+
Plugin.register_input('event_sniffer', self)
|
6
|
+
|
7
|
+
config_param :bind, :string, :default => '0.0.0.0'
|
8
|
+
config_param :port, :integer, :default => 8765
|
9
|
+
config_param :access_log_path, :string, :default => nil
|
10
|
+
|
11
|
+
config_param :pattern_bookmarks, :array, :default => []
|
12
|
+
config_param :max_events, :integer, :default => 10
|
13
|
+
config_param :refresh_interval, :integer, :default => 1
|
14
|
+
|
15
|
+
config_param :development, :bool, :default => false
|
16
|
+
|
17
|
+
def start
|
18
|
+
super
|
19
|
+
|
20
|
+
$log.info "listening http server for event_sniffer on http://#{@bind}:#{@port}"
|
21
|
+
|
22
|
+
@access_log = File.open(@access_log_path, 'a') if @access_log_path
|
23
|
+
|
24
|
+
config = {
|
25
|
+
development: @development,
|
26
|
+
}
|
27
|
+
app = Rack::Builder.new do
|
28
|
+
ENV['RACK_ENV'] = config[:development] ? 'development' : 'production'
|
29
|
+
require_relative 'eventsniffer/app'
|
30
|
+
run EventSnifferPlugin::App.new
|
31
|
+
end
|
32
|
+
|
33
|
+
EventSnifferPlugin::App.set :pattern_bookmarks, @pattern_bookmarks
|
34
|
+
EventSnifferPlugin::App.set :max_events, @max_events
|
35
|
+
EventSnifferPlugin::App.set :refresh_interval, @refresh_interval
|
36
|
+
|
37
|
+
options = {
|
38
|
+
signals: false,
|
39
|
+
}
|
40
|
+
@srv = ::Thin::Server.new(@bind, @port, app, options)
|
41
|
+
@thread = Thread.new { @srv.start }
|
42
|
+
end
|
43
|
+
|
44
|
+
def shutdown
|
45
|
+
super
|
46
|
+
|
47
|
+
if @srv
|
48
|
+
@srv.stop
|
49
|
+
@srv = nil
|
50
|
+
end
|
51
|
+
|
52
|
+
if @access_log and (not @access_log.closed?)
|
53
|
+
@access_log.close
|
54
|
+
end
|
55
|
+
|
56
|
+
if @thread
|
57
|
+
@thread.join
|
58
|
+
@thread = nil
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
data/package.json
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
{
|
2
|
+
"private": true,
|
3
|
+
"devDependencies": {
|
4
|
+
"grunt": "^0.4.5",
|
5
|
+
"grunt-bower-task": "^0.4.0",
|
6
|
+
"grunt-contrib-clean": "^0.5.0",
|
7
|
+
"grunt-contrib-coffee": "^0.10.1",
|
8
|
+
"grunt-contrib-stylus": "^0.18.0",
|
9
|
+
"grunt-contrib-watch": "^0.6.1",
|
10
|
+
"grunt-shell": "^0.7.0"
|
11
|
+
}
|
12
|
+
}
|
@@ -0,0 +1,96 @@
|
|
1
|
+
class ViewModel
|
2
|
+
constructor: (@io, @config) ->
|
3
|
+
@running = ko.observable(false)
|
4
|
+
@pattern = ko.observable("")
|
5
|
+
@events = ko.observableArray([])
|
6
|
+
@unexpectedError = ko.observable(false)
|
7
|
+
@alreadySniffing = ko.observable(false)
|
8
|
+
|
9
|
+
@showTable = ko.computed =>
|
10
|
+
@events().length > 0
|
11
|
+
|
12
|
+
@canStart = ko.computed =>
|
13
|
+
not @running() and @pattern().length > 0
|
14
|
+
|
15
|
+
|
16
|
+
start: () ->
|
17
|
+
this.clearAlert()
|
18
|
+
@events([])
|
19
|
+
$.ajax '/pattern',
|
20
|
+
type: 'POST'
|
21
|
+
data:
|
22
|
+
pattern: @pattern()
|
23
|
+
rocketio_session: @io.session
|
24
|
+
success: () =>
|
25
|
+
@io.on 'event', (events) =>
|
26
|
+
this.rotate(_.map(events, (e) => this.format(e)))
|
27
|
+
@running(true)
|
28
|
+
error: (jqXHR, textStatus, errorThrown) =>
|
29
|
+
if jqXHR.status == 503
|
30
|
+
@alreadySniffing(true)
|
31
|
+
else
|
32
|
+
@unexpectedError(true)
|
33
|
+
|
34
|
+
|
35
|
+
stop: () ->
|
36
|
+
this.clearAlert()
|
37
|
+
$.ajax '/pattern',
|
38
|
+
type: 'DELETE'
|
39
|
+
success: () =>
|
40
|
+
@io.removeListener('event')
|
41
|
+
@running(false)
|
42
|
+
error: (jqXHR, textStatus, errorThrown) =>
|
43
|
+
@unexpectedError(true)
|
44
|
+
|
45
|
+
selectPattern: (data, event) ->
|
46
|
+
this.clearAlert()
|
47
|
+
@pattern(event.toElement.innerText)
|
48
|
+
if @running()
|
49
|
+
this.stopThenStart()
|
50
|
+
else
|
51
|
+
this.start()
|
52
|
+
|
53
|
+
submit: () ->
|
54
|
+
this.clearAlert()
|
55
|
+
if @pattern().length > 0
|
56
|
+
if @running()
|
57
|
+
this.stopThenStart()
|
58
|
+
else
|
59
|
+
this.start()
|
60
|
+
|
61
|
+
# Private Functions
|
62
|
+
|
63
|
+
stopThenStart: () ->
|
64
|
+
$.ajax '/pattern',
|
65
|
+
type: 'DELETE'
|
66
|
+
success: () =>
|
67
|
+
@io.removeListener('event')
|
68
|
+
@running(false)
|
69
|
+
this.start()
|
70
|
+
error: (jqXHR, textStatus, errorThrown) =>
|
71
|
+
@unexpectedError(true)
|
72
|
+
|
73
|
+
clearAlert: () =>
|
74
|
+
@unexpectedError(false)
|
75
|
+
@alreadySniffing(false)
|
76
|
+
|
77
|
+
format: (event) ->
|
78
|
+
tag: event.tag
|
79
|
+
time: (new Date(event.time * 1000)).toLocaleString()
|
80
|
+
record: JSON.stringify(event.record)
|
81
|
+
|
82
|
+
rotate: (events) ->
|
83
|
+
current = @events()
|
84
|
+
tmp = current.concat(events)
|
85
|
+
if tmp.length > @config.max_events
|
86
|
+
@events(tmp.slice(tmp.length - @config.max_events, tmp.length))
|
87
|
+
else
|
88
|
+
@events(tmp)
|
89
|
+
|
90
|
+
$ ->
|
91
|
+
config_elem = $('#config')
|
92
|
+
config =
|
93
|
+
max_events: config_elem.data('max-events')
|
94
|
+
|
95
|
+
io = new RocketIO().connect();
|
96
|
+
ko.applyBindings(new ViewModel(io, config))
|
@@ -0,0 +1,29 @@
|
|
1
|
+
.navbar-inverse
|
2
|
+
.navbar-brand
|
3
|
+
color white
|
4
|
+
|
5
|
+
.sidebar
|
6
|
+
left 0
|
7
|
+
z-index 1000
|
8
|
+
display block
|
9
|
+
padding 20px
|
10
|
+
background-color #f5f5f5
|
11
|
+
border-right 1px solid #eee
|
12
|
+
|
13
|
+
.sidebar-header
|
14
|
+
border-bottom 1px solid #eee
|
15
|
+
font-size 20px
|
16
|
+
|
17
|
+
li
|
18
|
+
a
|
19
|
+
padding 5px
|
20
|
+
:hover
|
21
|
+
cursor: pointer
|
22
|
+
|
23
|
+
.sub-header
|
24
|
+
padding-bottom 10px
|
25
|
+
border-bottom 1px solid #eee
|
26
|
+
|
27
|
+
.alert
|
28
|
+
margin-top 10px
|
29
|
+
font-size 15px
|
data/views/index.slim
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
.row
|
2
|
+
.col-md-3
|
3
|
+
.sidebar
|
4
|
+
.sidebar-header
|
5
|
+
p
|
6
|
+
span class="glyphicon glyphicon-bookmark"
|
7
|
+
|Bookmarks
|
8
|
+
|
9
|
+
ul.nav
|
10
|
+
- for p in @pattern_bookmarks
|
11
|
+
li
|
12
|
+
a data-bind="click: selectPattern" = p
|
13
|
+
|
14
|
+
.col-md-9
|
15
|
+
.row
|
16
|
+
.col-md-8
|
17
|
+
form data-bind="submit: submit"
|
18
|
+
.input-group
|
19
|
+
span.input-group-addon pattern
|
20
|
+
input.form-control type="text" data-bind="value: pattern, valueUpdate: 'input'"
|
21
|
+
.col-md-4
|
22
|
+
.btn-group
|
23
|
+
button type="button" class="btn btn-success" disabled=true data-bind="enable: canStart, click: start"
|
24
|
+
span class="glyphicon glyphicon-play"
|
25
|
+
|Start
|
26
|
+
button type="button" class="btn btn-warning" disabled=true data-bind="enable: running, click: stop"
|
27
|
+
span class="glyphicon glyphicon-stop"
|
28
|
+
|Stop
|
29
|
+
|
30
|
+
.row style="display: none" data-bind="if: unexpectedError, visible: unexpectedError"
|
31
|
+
div class="alert alert-danger alert-dismissible" role="alert"
|
32
|
+
button type="button" class="close" data-dismiss="alert"
|
33
|
+
span aria-hidden="true" ×
|
34
|
+
span class="sr-only" Close
|
35
|
+
|An unexpected error occured.
|
36
|
+
|
37
|
+
.row style="display: none" data-bind="if: alreadySniffing, visible: alreadySniffing"
|
38
|
+
div class="alert alert-warning alert-dismissible" role="alert"
|
39
|
+
button type="button" class="close" data-dismiss="alert"
|
40
|
+
span aria-hidden="true" ×
|
41
|
+
span class="sr-only" Close
|
42
|
+
|Could not start because another client is already sniffing.
|
43
|
+
|
44
|
+
.row
|
45
|
+
h2.sub-header Events
|
46
|
+
table class="table table-striped" data-bind="if: showTable"
|
47
|
+
thead
|
48
|
+
tr
|
49
|
+
th tag
|
50
|
+
th time
|
51
|
+
th record
|
52
|
+
tbody data-bind="foreach: events.slice(0).reverse()"
|
53
|
+
tr
|
54
|
+
td data-bind="text: tag"
|
55
|
+
td data-bind="text: time"
|
56
|
+
td data-bind="text: record"
|
57
|
+
|
58
|
+
.row
|
59
|
+
div id="config" data-max-events=settings.max_events
|
data/views/layout.slim
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
doctype html
|
2
|
+
html
|
3
|
+
head
|
4
|
+
meta charset="utf-8"
|
5
|
+
meta http-equiv="X-UA-Compatible" content="IE=edge"
|
6
|
+
meta name="viewport" content="width=device-width, initial-scale=1"
|
7
|
+
meta name="description" content=""
|
8
|
+
meta name="author" content=""
|
9
|
+
|
10
|
+
title Fluentd Event Sniffer
|
11
|
+
|
12
|
+
link href=url("/vendor/bootstrap/css/bootstrap.css") rel="stylesheet"
|
13
|
+
link href=url("/css/app.css") rel="stylesheet"
|
14
|
+
|
15
|
+
script src=url("/vendor/underscore/underscore.js")
|
16
|
+
script src=url("/vendor/knockoutjs/knockout.js")
|
17
|
+
|
18
|
+
body
|
19
|
+
div class="navbar navbar-inverse" role="navigation"
|
20
|
+
.container
|
21
|
+
.navbar-brand
|
22
|
+
p Fluentd Event Sniffer
|
23
|
+
.container
|
24
|
+
|
25
|
+
== yield
|
26
|
+
|
27
|
+
script src = rocketio_js
|
28
|
+
script src=url("/vendor/jquery/jquery.js")
|
29
|
+
script src=url("/vendor/bootstrap/js/bootstrap.js")
|
30
|
+
script src=url("/js/app.js")
|
metadata
ADDED
@@ -0,0 +1,214 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fluent-plugin-event-sniffer
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- OKUNO Akihiro
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-07-26 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: fluentd
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: sinatra
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: sinatra-rocketio
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: thin
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: slim
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: bundler
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '1.6'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '1.6'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rake
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: sinatra-contrib
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: foreman
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: dummer
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
description: Fluentd plugin which serves web application sniffing streaming events
|
154
|
+
email:
|
155
|
+
- choplin.choplin@gmail.com
|
156
|
+
executables: []
|
157
|
+
extensions: []
|
158
|
+
extra_rdoc_files: []
|
159
|
+
files:
|
160
|
+
- ".gitignore"
|
161
|
+
- Gemfile
|
162
|
+
- Gruntfile.coffee
|
163
|
+
- LICENSE.txt
|
164
|
+
- Procfile
|
165
|
+
- README.md
|
166
|
+
- Rakefile
|
167
|
+
- bower.json
|
168
|
+
- dummer.conf
|
169
|
+
- example.conf
|
170
|
+
- fluent-plugin-event-sniffer.gemspec
|
171
|
+
- lib/fluent/plugin/eventsniffer/app.rb
|
172
|
+
- lib/fluent/plugin/eventsniffer/engine_util.rb
|
173
|
+
- lib/fluent/plugin/in_event_sniffer.rb
|
174
|
+
- package.json
|
175
|
+
- public/css/app.css
|
176
|
+
- public/js/app.js
|
177
|
+
- public/vendor/bootstrap/css/bootstrap.css
|
178
|
+
- public/vendor/bootstrap/fonts/glyphicons-halflings-regular.eot
|
179
|
+
- public/vendor/bootstrap/fonts/glyphicons-halflings-regular.svg
|
180
|
+
- public/vendor/bootstrap/fonts/glyphicons-halflings-regular.ttf
|
181
|
+
- public/vendor/bootstrap/fonts/glyphicons-halflings-regular.woff
|
182
|
+
- public/vendor/bootstrap/js/bootstrap.js
|
183
|
+
- public/vendor/jquery/jquery.js
|
184
|
+
- public/vendor/knockoutjs/knockout.js
|
185
|
+
- public/vendor/underscore/underscore.js
|
186
|
+
- src/coffee/app.coffee
|
187
|
+
- src/stylus/app.stylus
|
188
|
+
- views/index.slim
|
189
|
+
- views/layout.slim
|
190
|
+
homepage: https://github.com/choplin/fluent-plugin-event-sniffer
|
191
|
+
licenses:
|
192
|
+
- Apache-2.0
|
193
|
+
metadata: {}
|
194
|
+
post_install_message:
|
195
|
+
rdoc_options: []
|
196
|
+
require_paths:
|
197
|
+
- lib
|
198
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
199
|
+
requirements:
|
200
|
+
- - ">="
|
201
|
+
- !ruby/object:Gem::Version
|
202
|
+
version: '0'
|
203
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
204
|
+
requirements:
|
205
|
+
- - ">="
|
206
|
+
- !ruby/object:Gem::Version
|
207
|
+
version: '0'
|
208
|
+
requirements: []
|
209
|
+
rubyforge_project:
|
210
|
+
rubygems_version: 2.2.2
|
211
|
+
signing_key:
|
212
|
+
specification_version: 4
|
213
|
+
summary: Fluentd Event Sniffer
|
214
|
+
test_files: []
|