fluentd-ui 0.4.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
|