fluentd-ui 0.4.0 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of fluentd-ui might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/ChangeLog.md +4 -0
- data/Gemfile.lock +1 -1
- data/app/assets/javascripts/vue/in_tail_format.js +25 -0
- data/app/controllers/api_controller.rb +3 -11
- data/app/models/fluentd/setting/in_tail.rb +17 -3
- data/app/views/fluentd/settings/in_tail/after_file_choose.html.haml +1 -1
- data/app/views/shared/vue/_in_tail_format.html.erb +15 -2
- data/config/application.yml +1 -0
- data/config/locales/translation_en.yml +1 -0
- data/config/locales/translation_ja.yml +1 -0
- data/lib/fluentd-ui/version.rb +1 -1
- data/lib/regexp_preview.rb +7 -38
- data/lib/regexp_preview/multi_line.rb +70 -0
- data/lib/regexp_preview/single_line.rb +65 -0
- data/spec/lib/regexp_preview/multi_line_spec.rb +40 -0
- data/spec/lib/regexp_preview/single_line_spec.rb +183 -0
- data/spec/support/fixtures/error4.log +1 -0
- metadata +10 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2119d4e58a87812ee21f17c4a840d7bdbfdf26f4
|
4
|
+
data.tar.gz: 52d92b5d8cfe2e728180e35db1852c0037621d21
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fdabe5a50be258c8331affa398e8cc29f01d5580c198f39d861d612c99a50675dc34150581bdbc258fbba00b76ef6885cbe600dbfaa21f712fb6896fa93d7e5c
|
7
|
+
data.tar.gz: 560f338fceabd69b8389889e022685269692386f959def3c33b68f4badea21ff3d4970b4accddb31bca32108fd1ade67f563eb9d8b13ea557bedbe6d3ba38fbd
|
data/ChangeLog.md
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
## Release 0.4.1 - 2015/04/24
|
2
|
+
|
3
|
+
* [improved] [#162](https://github.com/fluent/fluentd-ui/pull/162) [#191](https://github.com/fluent/fluentd-ui/pull/191) Support multiline option for [in_tail](http://docs.fluentd.org/articles/in_tail) plugin
|
4
|
+
|
1
5
|
## Release 0.4.0 - 2015/04/15
|
2
6
|
|
3
7
|
* [improved] [#190](https://github.com/fluent/fluentd-ui/pull/190) Use markdown format for ChangeLog.md
|
data/Gemfile.lock
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
(function(){
|
2
2
|
"use strict";
|
3
|
+
var maxFormatCount = 20;
|
3
4
|
|
4
5
|
$(function(){
|
5
6
|
if($('#in_tail_format').length === 0) return;
|
@@ -30,7 +31,20 @@
|
|
30
31
|
highlightedLines: null,
|
31
32
|
},
|
32
33
|
|
34
|
+
computed: {
|
35
|
+
useTextArea: function() {
|
36
|
+
return this.format === "multiline";
|
37
|
+
}
|
38
|
+
},
|
39
|
+
|
33
40
|
compiled: function(){
|
41
|
+
this.$watch('params.setting.formats', function(formats){
|
42
|
+
_.range(1, maxFormatCount + 1).forEach(function(i) {params.setting["format" + String(i)] = "";});
|
43
|
+
|
44
|
+
_.compact(formats.split("\n")).forEach(function(formatLine, index) {
|
45
|
+
params.setting["format" + String(index + 1)] = formatLine;
|
46
|
+
});
|
47
|
+
}),
|
34
48
|
this.$watch('params.setting.regexp', function(){
|
35
49
|
this.preview();
|
36
50
|
});
|
@@ -46,6 +60,10 @@
|
|
46
60
|
if(!params.setting) {
|
47
61
|
params.setting = {};
|
48
62
|
}
|
63
|
+
|
64
|
+
var formats = _.chain(_.range(1, maxFormatCount + 1)).map(function(i) {return params.setting["format" + String(i)];}).compact().value();
|
65
|
+
params.setting.formats = formats.join("\n");
|
66
|
+
|
49
67
|
_.each(this.formatOptions, function(options){
|
50
68
|
_.each(options, function(key){
|
51
69
|
if(!params.setting.hasOwnProperty(key)){
|
@@ -58,6 +76,12 @@
|
|
58
76
|
},
|
59
77
|
|
60
78
|
methods: {
|
79
|
+
onKeyup: function(ev){
|
80
|
+
var el = ev.target;
|
81
|
+
if(el.name.match(/\[format/)){
|
82
|
+
this.preview();
|
83
|
+
}
|
84
|
+
},
|
61
85
|
updateHighlightedLines: function() {
|
62
86
|
if(!this.regexpMatches) {
|
63
87
|
this.highlightedLines = null;
|
@@ -132,6 +156,7 @@
|
|
132
156
|
regexp: self.params.setting.regexp,
|
133
157
|
time_format: self.params.setting.time_format,
|
134
158
|
format: _.isEmpty(self.format) ? "regexp" : self.format,
|
159
|
+
params: self.params.setting,
|
135
160
|
file: self.targetFile
|
136
161
|
}
|
137
162
|
}).done(resolve).fail(reject);
|
@@ -19,17 +19,9 @@ class ApiController < ApplicationController
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def regexp_preview
|
22
|
-
preview = RegexpPreview.
|
23
|
-
|
24
|
-
render json:
|
25
|
-
params: {
|
26
|
-
setting: {
|
27
|
-
regexp: preview.regexp.try(:source),
|
28
|
-
time_format: preview.time_format,
|
29
|
-
}
|
30
|
-
},
|
31
|
-
matches: matches.compact,
|
32
|
-
}
|
22
|
+
preview = RegexpPreview.processor(params[:format]).new(params[:file], params[:format], params)
|
23
|
+
|
24
|
+
render json: preview.matches_json
|
33
25
|
end
|
34
26
|
|
35
27
|
def grok_to_regexp
|
@@ -1,6 +1,8 @@
|
|
1
1
|
class Fluentd
|
2
2
|
module Setting
|
3
3
|
class InTail
|
4
|
+
MULTI_LINE_MAX_FORMAT_COUNT = 20
|
5
|
+
|
4
6
|
include ActiveModel::Model
|
5
7
|
attr_accessor :path, :tag, :format, :regexp, :time_format, :rotate_wait, :pos_file, :read_from_head, :refresh_interval
|
6
8
|
|
@@ -18,12 +20,13 @@ class Fluentd
|
|
18
20
|
:ltsv => [:delimiter, :time_key],
|
19
21
|
:json => [:time_key],
|
20
22
|
:regexp => [:time_format, :regexp],
|
23
|
+
:multiline => [:format_firstline] + (1..MULTI_LINE_MAX_FORMAT_COUNT).map{|n| "format#{n}".to_sym }
|
21
24
|
# TODO: Grok could generate Regexp including \d, \s, etc. fluentd config parser raise error with them for escape sequence check.
|
22
25
|
# TBD How to handle Grok/Regexp later, just comment out for hide
|
23
26
|
# :grok => [:grok_str],
|
24
27
|
}
|
25
28
|
end
|
26
|
-
attr_accessor *known_formats.values.flatten.compact
|
29
|
+
attr_accessor *known_formats.values.flatten.compact.uniq
|
27
30
|
|
28
31
|
def known_formats
|
29
32
|
self.class.known_formats
|
@@ -59,9 +62,20 @@ class Fluentd
|
|
59
62
|
|
60
63
|
indent = " " * 2
|
61
64
|
format_specific_conf = ""
|
62
|
-
|
63
|
-
|
65
|
+
|
66
|
+
if format.to_sym == :multiline
|
67
|
+
known_formats[:multiline].each do |key|
|
68
|
+
value = send(key)
|
69
|
+
if value.present?
|
70
|
+
format_specific_conf << "#{indent}#{key} /#{value}/\n"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
else
|
74
|
+
extra_format_options.each do |key|
|
75
|
+
format_specific_conf << "#{indent}#{key} #{send(key)}\n"
|
76
|
+
end
|
64
77
|
end
|
78
|
+
|
65
79
|
format_specific_conf
|
66
80
|
end
|
67
81
|
|
@@ -12,7 +12,7 @@
|
|
12
12
|
= f.text_field :path, class: "form-control", disabled: true
|
13
13
|
= render partial: "shared/vue/in_tail_format", locals: { file: f.object.path, formats: @setting.known_formats, initialSelected: f.object.format || @setting.guess_format }
|
14
14
|
|
15
|
-
%pre= file_tail(@setting.path).join("\n")
|
15
|
+
%pre= file_tail(@setting.path, Settings.in_tail_preview_line_count).join("\n")
|
16
16
|
|
17
17
|
%p
|
18
18
|
= f.submit t('terms.next'), class: "btn btn-lg btn-primary pull-right"
|
@@ -6,8 +6,21 @@
|
|
6
6
|
</select>
|
7
7
|
</div>
|
8
8
|
<div class="form-inline form-group" v-repeat="options">
|
9
|
-
<label for="in_tail_setting_{{ $value }}">{{ $value }} </label>
|
10
|
-
<input id="in_tail_setting_{{ $value }}" type="text" name="setting[{{ $value }}]" v-model="params.setting[$value]" size="100%" class="form-control" />
|
9
|
+
<label for="in_tail_setting_{{ $value }}" v-if="!useTextArea">{{ $value }} </label>
|
10
|
+
<input id="in_tail_setting_{{ $value }}" type="{{ useTextArea ? 'hidden' : 'text' }}" name="setting[{{ $value }}]" v-model="params.setting[$value]" v-on="keyup: onKeyup" size="100%" class="form-control" />
|
11
|
+
</div>
|
12
|
+
|
13
|
+
<div v-if="useTextArea">
|
14
|
+
<div class="form-inline form-group">
|
15
|
+
<label for="in_tail_setting_format_firstline">format_firstline</label>
|
16
|
+
<input id="in_tail_setting_format_firstline" type="text" name="setting[format_firstline]" v-model="params.setting['format_firstline']" v-on="keyup: onKeyup" size="100%" class="form-control" />
|
17
|
+
</div>
|
18
|
+
|
19
|
+
<div class="form-group">
|
20
|
+
<p class="alert alert-warning"><%= t("fluentd.settings.in_tail.notice_for_multiline_limit") %></p>
|
21
|
+
<label for="in_tail_setting_formats">formats</label>
|
22
|
+
<textarea id="in_tail_setting_formats" type="text" name="setting[formats]" v-model="params.setting['formats']" v-on="keyup: onKeyup" rows='20' size='100%' class="form-control"></textarea>
|
23
|
+
</div>
|
11
24
|
</div>
|
12
25
|
</script>
|
13
26
|
|
data/config/application.yml
CHANGED
@@ -211,6 +211,7 @@ en:
|
|
211
211
|
For each config parameter, please refer to the <a href="http://docs.fluentd.org/articles/in_tail" target="_blank">Tail input plugin</a> documentation page.
|
212
212
|
in_tail:
|
213
213
|
notice_for_permission: "Please check permission or group setting for %{user} user can read it."
|
214
|
+
notice_for_multiline_limit: "Please input Regexp(s) separated by newline. blank lines are ignored. Lines more than 20 are dropped."
|
214
215
|
restart_from_first: Restart from first
|
215
216
|
grok_manual: |
|
216
217
|
<p>
|
@@ -216,6 +216,7 @@ ja:
|
|
216
216
|
<a target="_blank" href="http://docs.fluentd.org/ja/articles/in_tail">in_tailプラグインの解説ページ</a>や
|
217
217
|
<a target="_blank" href="http://fluentular.herokuapp.com/">Fluentular</a>もご参照ください。
|
218
218
|
in_tail:
|
219
|
+
notice_for_multiline_limit: "改行区切りで正規表現を入力してください。空行はカウントされません。21行目以降の入力は無視されます。"
|
219
220
|
notice_for_permission: "※%{user}ユーザーが読み込み可能なようにパーミッションやグループの設定をご確認ください。"
|
220
221
|
restart_from_first: 最初からやり直す
|
221
222
|
grok_manual: |
|
data/lib/fluentd-ui/version.rb
CHANGED
data/lib/regexp_preview.rb
CHANGED
@@ -2,47 +2,16 @@
|
|
2
2
|
require "fluent/registry"
|
3
3
|
require "fluent/configurable"
|
4
4
|
require "fluent/parser"
|
5
|
+
require "regexp_preview/single_line"
|
6
|
+
require "regexp_preview/multi_line"
|
5
7
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
def initialize(file, format, options = {})
|
10
|
-
@file = file
|
11
|
-
@format = format
|
8
|
+
module RegexpPreview
|
9
|
+
def self.processor(format)
|
12
10
|
case format
|
13
|
-
when "
|
14
|
-
|
15
|
-
@time_format = options[:time_format]
|
16
|
-
when "ltsv", "json", "csv", "tsv"
|
11
|
+
when "multiline"
|
12
|
+
RegexpPreview::MultiLine
|
17
13
|
else
|
18
|
-
|
19
|
-
raise "Unknown format '#{format}'" unless definition
|
20
|
-
definition.configure({}) # NOTE: SyslogParser define @regexp in configure method so call it to grab Regexp object
|
21
|
-
@regexp = definition.patterns["format"]
|
22
|
-
@time_format = definition.patterns["time_format"]
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
def matches
|
27
|
-
return [] unless @regexp # such as ltsv, json, etc
|
28
|
-
reader = FileReverseReader.new(File.open(file))
|
29
|
-
matches = reader.tail.map do |line|
|
30
|
-
result = {
|
31
|
-
:whole => line,
|
32
|
-
:matches => [],
|
33
|
-
}
|
34
|
-
m = line.match(regexp)
|
35
|
-
next result unless m
|
36
|
-
|
37
|
-
m.names.each_with_index do |name, index|
|
38
|
-
result[:matches] << {
|
39
|
-
key: name,
|
40
|
-
matched: m[name],
|
41
|
-
pos: m.offset(index + 1),
|
42
|
-
}
|
43
|
-
end
|
44
|
-
result
|
14
|
+
RegexpPreview::SingleLine
|
45
15
|
end
|
46
|
-
matches
|
47
16
|
end
|
48
17
|
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module RegexpPreview
|
2
|
+
class MultiLine
|
3
|
+
attr_reader :file, :format, :params
|
4
|
+
|
5
|
+
def initialize(file, format, params = {})
|
6
|
+
@file = file
|
7
|
+
@format = format
|
8
|
+
@params = params[:params]
|
9
|
+
end
|
10
|
+
|
11
|
+
def matches_json
|
12
|
+
{
|
13
|
+
params: {
|
14
|
+
setting: { # for vue.js
|
15
|
+
regexp: nil,
|
16
|
+
time_format: nil,
|
17
|
+
}
|
18
|
+
},
|
19
|
+
matches: matches.compact,
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def matches
|
26
|
+
return [] if patterns.empty?
|
27
|
+
reader = FileReverseReader.new(File.open(file))
|
28
|
+
result = []
|
29
|
+
target_lines = reader.tail(Settings.in_tail_preview_line_count).map{|line| line << "\n" }
|
30
|
+
target_lines.each_with_index do |line, line_no|
|
31
|
+
if line.match(params[:format_firstline])
|
32
|
+
lines = target_lines[line_no, patterns.length]
|
33
|
+
next if lines.length < patterns.length
|
34
|
+
ret = detect_chunk(lines)
|
35
|
+
next unless ret
|
36
|
+
result << ret
|
37
|
+
end
|
38
|
+
end
|
39
|
+
result
|
40
|
+
end
|
41
|
+
|
42
|
+
def detect_chunk(lines)
|
43
|
+
whole = ""
|
44
|
+
matches = []
|
45
|
+
lines.each_with_index do |line, i|
|
46
|
+
match = line.match(patterns[i])
|
47
|
+
return nil unless match
|
48
|
+
match.names.each_with_index do |name, index|
|
49
|
+
matches << {
|
50
|
+
key: name,
|
51
|
+
matched: match[name],
|
52
|
+
pos: match.offset(index + 1).map{|pos| pos + whole.length},
|
53
|
+
}
|
54
|
+
end
|
55
|
+
whole << line
|
56
|
+
end
|
57
|
+
{
|
58
|
+
whole: whole,
|
59
|
+
matches: matches,
|
60
|
+
}
|
61
|
+
end
|
62
|
+
|
63
|
+
def patterns
|
64
|
+
@patterns ||= (1..20).map do |n|
|
65
|
+
params["format#{n}"].presence
|
66
|
+
end.compact.map {|pattern| Regexp.new(pattern)}
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module RegexpPreview
|
2
|
+
class SingleLine
|
3
|
+
attr_reader :file, :format, :params, :regexp, :time_format
|
4
|
+
|
5
|
+
def initialize(file, format, params = {})
|
6
|
+
@file = file
|
7
|
+
@format = format
|
8
|
+
@time_format = params[:time_format]
|
9
|
+
@params = params
|
10
|
+
|
11
|
+
case format
|
12
|
+
when "regexp"
|
13
|
+
@regexp = Regexp.new(params[:regexp])
|
14
|
+
@time_format = nil
|
15
|
+
when "ltsv", "json", "csv", "tsv"
|
16
|
+
@regexp = nil
|
17
|
+
@time_format = nil
|
18
|
+
else # apache, nginx, etc
|
19
|
+
definition = Fluent::TextParser::TEMPLATE_REGISTRY.lookup(format).call
|
20
|
+
raise "Unknown format '#{format}'" unless definition
|
21
|
+
definition.configure({}) # NOTE: SyslogParser define @regexp in configure method so call it to grab Regexp object
|
22
|
+
@regexp = definition.patterns["format"]
|
23
|
+
@time_format = definition.patterns["time_format"]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def matches_json
|
28
|
+
{
|
29
|
+
params: {
|
30
|
+
setting: {
|
31
|
+
# NOTE: regexp and time_format are used when format == 'apache' || 'nginx' || etc.
|
32
|
+
regexp: regexp.try(:source),
|
33
|
+
time_format: time_format,
|
34
|
+
}
|
35
|
+
},
|
36
|
+
matches: matches.compact,
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def matches
|
43
|
+
return [] unless @regexp # such as ltsv, json, etc
|
44
|
+
reader = FileReverseReader.new(File.open(file))
|
45
|
+
matches = reader.tail(Settings.in_tail_preview_line_count).map do |line|
|
46
|
+
result = {
|
47
|
+
:whole => line,
|
48
|
+
:matches => [],
|
49
|
+
}
|
50
|
+
match = line.match(regexp)
|
51
|
+
next result unless match
|
52
|
+
|
53
|
+
match.names.each_with_index do |name, index|
|
54
|
+
result[:matches] << {
|
55
|
+
key: name,
|
56
|
+
matched: match[name],
|
57
|
+
pos: match.offset(index + 1),
|
58
|
+
}
|
59
|
+
end
|
60
|
+
result
|
61
|
+
end
|
62
|
+
matches
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RegexpPreview::MultiLine do
|
4
|
+
describe "#matches_json" do
|
5
|
+
subject { RegexpPreview::MultiLine.new(File.expand_path("./spec/support/fixtures/error0.log", Rails.root), "multiline", params).matches_json }
|
6
|
+
|
7
|
+
let :params do
|
8
|
+
params = {
|
9
|
+
format_firstline: ".+",
|
10
|
+
time_format: "time_format",
|
11
|
+
}
|
12
|
+
params["format1"] = "(?<foo>foo)"
|
13
|
+
params["format2"] = "(?<bar>bar)"
|
14
|
+
3.upto(Fluentd::Setting::InTail::MULTI_LINE_MAX_FORMAT_COUNT) do |i|
|
15
|
+
params["format#{i}"] = ""
|
16
|
+
end
|
17
|
+
{ params: params }
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'should not have regexp and time_format in [:params][:setting]' do
|
21
|
+
expect(subject[:params][:setting]).to eq({ regexp: nil, time_format: nil })
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should include matches info" do
|
25
|
+
matches_info = {
|
26
|
+
whole: "foo\nbar\n",
|
27
|
+
matches: [
|
28
|
+
{
|
29
|
+
key: "foo", matched: "foo", pos: [0, 3]
|
30
|
+
},
|
31
|
+
{
|
32
|
+
key: "bar", matched: "bar", pos: [4, 7]
|
33
|
+
}
|
34
|
+
]
|
35
|
+
}
|
36
|
+
|
37
|
+
expect(subject[:matches]).to include matches_info
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,183 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RegexpPreview::SingleLine do
|
4
|
+
describe ".initialize" do
|
5
|
+
subject { RegexpPreview::SingleLine.new("log_file.log", format, params) }
|
6
|
+
|
7
|
+
describe "format" do
|
8
|
+
let :params do
|
9
|
+
{
|
10
|
+
regexp: "(?<category>\[.+\])",
|
11
|
+
time_format: "%y/%m/%d",
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
15
|
+
shared_examples "should set regexp and time_format from selected format" do
|
16
|
+
it do
|
17
|
+
expect(subject.regexp).to eq regexp
|
18
|
+
expect(subject.time_format).to eq time_format
|
19
|
+
expect(subject.params).to eq params
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
shared_examples "should set params only" do
|
24
|
+
include_examples "should set regexp and time_format from selected format" do
|
25
|
+
let(:regexp) { nil }
|
26
|
+
let(:time_format) { nil }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context "regexp" do
|
31
|
+
let(:format) { "regexp" }
|
32
|
+
|
33
|
+
it 'should set regexp from params' do
|
34
|
+
expect(subject.regexp).to eq /#{params[:regexp]}/
|
35
|
+
expect(subject.time_format).to be_nil
|
36
|
+
expect(subject.params).to eq params
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context "ltsv" do
|
41
|
+
let(:format) { "ltsv" }
|
42
|
+
|
43
|
+
include_examples "should set params only"
|
44
|
+
end
|
45
|
+
|
46
|
+
context "json" do
|
47
|
+
let(:format) { "json" }
|
48
|
+
|
49
|
+
include_examples "should set params only"
|
50
|
+
end
|
51
|
+
|
52
|
+
context "csv" do
|
53
|
+
let(:format) { "csv" }
|
54
|
+
|
55
|
+
include_examples "should set params only"
|
56
|
+
end
|
57
|
+
|
58
|
+
context "tsv" do
|
59
|
+
let(:format) { "tsv" }
|
60
|
+
|
61
|
+
include_examples "should set params only"
|
62
|
+
end
|
63
|
+
|
64
|
+
context "syslog" do # "apache", "nginx", etc
|
65
|
+
let(:format) { "syslog" }
|
66
|
+
|
67
|
+
include_examples "should set regexp and time_format from selected format" do
|
68
|
+
let(:regexp) do
|
69
|
+
/^(?<time>[^ ]*\s*[^ ]* [^ ]*) (?<host>[^ ]*) (?<ident>[a-zA-Z0-9_\/\.\-]*)(?:\[(?<pid>[0-9]+)\])?(?:[^\:]*\:)? *(?<message>.*)$/
|
70
|
+
end
|
71
|
+
let(:time_format) { "%b %d %H:%M:%S" }
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context "apache" do
|
76
|
+
let(:format) { "apache" }
|
77
|
+
|
78
|
+
include_examples "should set regexp and time_format from selected format" do
|
79
|
+
let(:regexp) do
|
80
|
+
/^(?<host>[^ ]*) [^ ]* (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^ ]*) +\S*)?" (?<code>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)")?$/
|
81
|
+
end
|
82
|
+
let(:time_format) { "%d/%b/%Y:%H:%M:%S %z" }
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
context "nginx" do
|
87
|
+
let(:format) { "nginx" }
|
88
|
+
|
89
|
+
include_examples "should set regexp and time_format from selected format" do
|
90
|
+
let(:regexp) do
|
91
|
+
/^(?<remote>[^ ]*) (?<host>[^ ]*) (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^\"]*?)(?: +\S*)?)?" (?<code>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)")?$/
|
92
|
+
end
|
93
|
+
let(:time_format) { "%d/%b/%Y:%H:%M:%S %z" }
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
describe "#matches_json" do
|
100
|
+
let(:logfile) { File.expand_path(logfile_path, Rails.root) }
|
101
|
+
let :params do
|
102
|
+
{
|
103
|
+
regexp: "(?<regexp>bar)", # bar from error0.log
|
104
|
+
time_format: "time_format",
|
105
|
+
}
|
106
|
+
end
|
107
|
+
|
108
|
+
subject { RegexpPreview::SingleLine.new(logfile, format, params).matches_json }
|
109
|
+
|
110
|
+
describe "format" do
|
111
|
+
context "regexp" do
|
112
|
+
let(:format) { "regexp" }
|
113
|
+
let(:logfile_path) { "./spec/support/fixtures/error0.log" }
|
114
|
+
|
115
|
+
it 'should have regexp only in [:params][:setting]' do
|
116
|
+
setting_json = {
|
117
|
+
regexp: params[:regexp],
|
118
|
+
time_format: nil
|
119
|
+
}
|
120
|
+
|
121
|
+
expect(subject[:params][:setting]).to eq setting_json
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'should include matches info' do
|
125
|
+
matches_info = {
|
126
|
+
whole: "bar",
|
127
|
+
matches: [
|
128
|
+
{ key: "regexp", matched: "bar", pos: [0, 3] }
|
129
|
+
]
|
130
|
+
}
|
131
|
+
expect(subject[:matches]).to include matches_info
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
context "csv" do
|
136
|
+
let(:format) { "csv" }
|
137
|
+
let(:logfile_path) { "./spec/support/fixtures/error0.log" }
|
138
|
+
|
139
|
+
it 'should not have regexp and time_format in [:params][:setting]' do
|
140
|
+
setting_json = {
|
141
|
+
regexp: nil,
|
142
|
+
time_format: nil
|
143
|
+
}
|
144
|
+
|
145
|
+
expect(subject[:params][:setting]).to eq setting_json
|
146
|
+
end
|
147
|
+
|
148
|
+
it 'should not have matches_info' do
|
149
|
+
expect(subject[:matches]).to be_empty
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
context "syslog" do
|
154
|
+
let(:format) { "syslog" }
|
155
|
+
let(:logfile_path) { "./spec/support/fixtures/error4.log" }
|
156
|
+
|
157
|
+
it 'should set regexp and time_format from syslog format' do
|
158
|
+
setting_json = {
|
159
|
+
regexp: "^(?<time>[^ ]*\\s*[^ ]* [^ ]*) (?<host>[^ ]*) (?<ident>[a-zA-Z0-9_/\\.\\-]*)(?:\\[(?<pid>[0-9]+)\\])?(?:[^\\:]*\\:)? *(?<message>.*)$",
|
160
|
+
time_format: "%b %d %H:%M:%S",
|
161
|
+
}
|
162
|
+
|
163
|
+
expect(subject[:params][:setting]).to eq setting_json
|
164
|
+
end
|
165
|
+
|
166
|
+
it 'should include matches info' do
|
167
|
+
matches_info = {
|
168
|
+
whole: "2014-05-27 10:54:37 +0900 [info]: listening fluent socket on 0.0.0.0:24224",
|
169
|
+
matches: [
|
170
|
+
{ key: "time", matched: "2014-05-27 10:54:37 +0900", pos: [0, 25] },
|
171
|
+
{ key: "host", matched: "[info]:", pos: [26, 33] },
|
172
|
+
{ key: "ident", matched: "listening", pos: [34, 43] },
|
173
|
+
{ key: "pid", matched: nil, pos: [nil, nil] },
|
174
|
+
{ key: "message", matched: "24224", pos: [69, 74] }
|
175
|
+
]
|
176
|
+
}
|
177
|
+
|
178
|
+
expect(subject[:matches]).to include matches_info
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
2014-05-27 10:54:37 +0900 [info]: listening fluent socket on 0.0.0.0:24224
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fluentd-ui
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Masahiro Nakagawa
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-04-
|
12
|
+
date: 2015-04-24 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: fluentd
|
@@ -497,6 +497,8 @@ files:
|
|
497
497
|
- lib/fluentd-ui/version.rb
|
498
498
|
- lib/grok_converter.rb
|
499
499
|
- lib/regexp_preview.rb
|
500
|
+
- lib/regexp_preview/multi_line.rb
|
501
|
+
- lib/regexp_preview/single_line.rb
|
500
502
|
- lib/tasks/.keep
|
501
503
|
- lib/tasks/clean.rake
|
502
504
|
- lib/tasks/dep.rake
|
@@ -544,6 +546,8 @@ files:
|
|
544
546
|
- spec/grok_converter_spec.rb
|
545
547
|
- spec/lib/file_reverse_reader_spec.rb
|
546
548
|
- spec/lib/fluentd-ui_spec.rb
|
549
|
+
- spec/lib/regexp_preview/multi_line_spec.rb
|
550
|
+
- spec/lib/regexp_preview/single_line_spec.rb
|
547
551
|
- spec/models/fluent_gem_spec.rb
|
548
552
|
- spec/models/fluentd/agent/common_spec.rb
|
549
553
|
- spec/models/fluentd/agent_spec.rb
|
@@ -560,6 +564,7 @@ files:
|
|
560
564
|
- spec/support/fixtures/error0.log
|
561
565
|
- spec/support/fixtures/error2.log
|
562
566
|
- spec/support/fixtures/error3.log
|
567
|
+
- spec/support/fixtures/error4.log
|
563
568
|
- spec/support/fluentd_agent_common_behavior.rb
|
564
569
|
- spec/support/fluentd_agent_restart_strategy.rb
|
565
570
|
- spec/support/javascript_macro.rb
|
@@ -740,6 +745,8 @@ test_files:
|
|
740
745
|
- spec/grok_converter_spec.rb
|
741
746
|
- spec/lib/file_reverse_reader_spec.rb
|
742
747
|
- spec/lib/fluentd-ui_spec.rb
|
748
|
+
- spec/lib/regexp_preview/multi_line_spec.rb
|
749
|
+
- spec/lib/regexp_preview/single_line_spec.rb
|
743
750
|
- spec/models/fluent_gem_spec.rb
|
744
751
|
- spec/models/fluentd/agent/common_spec.rb
|
745
752
|
- spec/models/fluentd/agent_spec.rb
|
@@ -756,6 +763,7 @@ test_files:
|
|
756
763
|
- spec/support/fixtures/error0.log
|
757
764
|
- spec/support/fixtures/error2.log
|
758
765
|
- spec/support/fixtures/error3.log
|
766
|
+
- spec/support/fixtures/error4.log
|
759
767
|
- spec/support/fluentd_agent_common_behavior.rb
|
760
768
|
- spec/support/fluentd_agent_restart_strategy.rb
|
761
769
|
- spec/support/javascript_macro.rb
|