anschel 0.7.0 → 0.7.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.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/lib/anschel/filter/convert.rb +3 -2
- data/lib/anschel/filter/debug.rb +21 -0
- data/lib/anschel/filter/gsub.rb +3 -2
- data/lib/anschel/filter/index.rb +50 -31
- data/lib/anschel/filter/parse.rb +21 -4
- data/lib/anschel/filter/scan.rb +31 -11
- data/lib/anschel/filter/stamp.rb +36 -8
- data/lib/anschel/filter/tag.rb +31 -0
- data/lib/anschel/filter.rb +2 -0
- data/lib/anschel/input.rb +3 -3
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bde923168a56dffdc4774f30fef3c1d7378321dd
|
4
|
+
data.tar.gz: c86137acfc087e9978f16f3547b43b5556785a98
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 84cc50d7e8ab03a37fc9288b2e66e1d1c3068ac5f44576d91aab3a33855c047335e72ccdc8261b82ae5b4a72c04149274e0cead247a947c5956aac96593cfdcf
|
7
|
+
data.tar.gz: 9998968409c6de797d2cebf4aba524bb74f756442ba9ccf36ee1cd71a09f3cfb10d834c0e93c444545bda81565d9addad395e9dbb4c5fa893ec75fc57e084ed5
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.7.
|
1
|
+
0.7.1
|
@@ -22,13 +22,13 @@ module Anschel
|
|
22
22
|
}
|
23
23
|
|
24
24
|
stats.create 'filter-convert'
|
25
|
-
stats.get 'filter-convert'
|
26
25
|
stats.create 'filter-convert-skipped'
|
27
|
-
stats.get 'filter-convert-skippped'
|
28
26
|
|
29
27
|
log.trace event: 'filter-compiled', kind: 'convert', \
|
30
28
|
field: field, type: type
|
31
29
|
|
30
|
+
|
31
|
+
|
32
32
|
lambda do |event|
|
33
33
|
unless event.has_key? field
|
34
34
|
stats.inc 'filter-convert-skipped'
|
@@ -39,6 +39,7 @@ module Anschel
|
|
39
39
|
stats.inc 'filter-convert'
|
40
40
|
filtered event, conf
|
41
41
|
end
|
42
|
+
|
42
43
|
end
|
43
44
|
end
|
44
45
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# {
|
2
|
+
# "debug": {}
|
3
|
+
# }
|
4
|
+
module Anschel
|
5
|
+
class Filter
|
6
|
+
def debug conf, stats, log
|
7
|
+
log.trace event: 'filter-compiled', kind: 'debug'
|
8
|
+
|
9
|
+
|
10
|
+
|
11
|
+
lambda do |event|
|
12
|
+
log.debug \
|
13
|
+
event: 'debug',
|
14
|
+
event_repr: event.inspect,
|
15
|
+
raw_event: event
|
16
|
+
event
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/anschel/filter/gsub.rb
CHANGED
@@ -19,13 +19,13 @@ module Anschel
|
|
19
19
|
field = field.to_sym
|
20
20
|
|
21
21
|
stats.create 'filter-gsub'
|
22
|
-
stats.get 'filter-gsub'
|
23
22
|
stats.create 'filter-gsub-skipped'
|
24
|
-
stats.get 'filter-gsub-skipped'
|
25
23
|
|
26
24
|
log.trace event: 'filter-compiled', kind: 'gsub', \
|
27
25
|
field: field, match: match, replace: replace
|
28
26
|
|
27
|
+
|
28
|
+
|
29
29
|
lambda do |event|
|
30
30
|
unless event.has_key? field
|
31
31
|
stats.inc 'filter-gsub-skipped'
|
@@ -36,6 +36,7 @@ module Anschel
|
|
36
36
|
stats.inc 'filter-gsub'
|
37
37
|
filtered event, conf
|
38
38
|
end
|
39
|
+
|
39
40
|
end
|
40
41
|
end
|
41
42
|
end
|
data/lib/anschel/filter/index.rb
CHANGED
@@ -12,26 +12,33 @@ module Anschel
|
|
12
12
|
stamp = conf.delete(:stamp) || '@timestamp'
|
13
13
|
prefix = conf.delete(:prefix) || 'logs-%{type}-'
|
14
14
|
suffix = conf.delete(:suffix) || '%Y.%m.%d'
|
15
|
-
format = conf.delete(:format) ||
|
15
|
+
format = conf.delete(:format) || %w[
|
16
|
+
yyyy-MM-dd'T'HH:mm:ss.SSSZZ
|
17
|
+
yyyy-MM-dd'T'HH:mm:ss.SSSZ
|
18
|
+
yyyy-MM-dd'T'HH:mm:ssZZ
|
19
|
+
yyyy-MM-dd'T'HH:mm:ssZ
|
20
|
+
] # ISO8601
|
16
21
|
|
17
22
|
error_tag = conf.has_key?(:error_tag) ? conf[:error_tag] : 'index-error'
|
18
23
|
|
19
24
|
stamp = stamp.to_sym
|
20
25
|
|
21
|
-
|
22
|
-
|
23
|
-
joda =
|
26
|
+
format = [ format ] unless format.is_a? Array
|
27
|
+
|
28
|
+
joda = format.map do |f|
|
29
|
+
j = org.joda.time.format.DateTimeFormat.forPattern f
|
30
|
+
j.withDefaultYear(Time.new.year).withOffsetParsed
|
31
|
+
end
|
24
32
|
|
25
33
|
stats.create 'filter-index'
|
26
|
-
stats.get 'filter-index'
|
27
34
|
stats.create 'filter-index-skipped'
|
28
|
-
stats.get 'filter-index-skipped'
|
29
35
|
stats.create 'filter-index-error'
|
30
|
-
stats.get 'filter-index-error'
|
31
36
|
|
32
37
|
log.trace event: 'filter-compiled', kind: 'index', \
|
33
38
|
stamp: stamp, prefix: prefix, suffix: suffix, format: format
|
34
39
|
|
40
|
+
|
41
|
+
|
35
42
|
lambda do |event|
|
36
43
|
unless event.has_key? stamp
|
37
44
|
stats.inc 'filter-index-skipped'
|
@@ -40,33 +47,45 @@ module Anschel
|
|
40
47
|
|
41
48
|
idx_prefix = prefix % event
|
42
49
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
reason: 'could not parse event',
|
54
|
-
remediation: 'added bogus index',
|
55
|
-
remediation: "sending to best-guess index '#{event[:_index]}'",
|
56
|
-
stamp: stamp,
|
57
|
-
prefix: prefix,
|
58
|
-
suffix: suffix,
|
59
|
-
format: format,
|
60
|
-
raw_event: event
|
61
|
-
if error_tag
|
62
|
-
event[:tags] ||= []
|
63
|
-
event[:tags] << error_tag
|
50
|
+
matched = false
|
51
|
+
|
52
|
+
joda.each do |j|
|
53
|
+
begin
|
54
|
+
millis = j.parseMillis event[stamp]
|
55
|
+
idx_suffix = Time.at(0.001 * millis).utc.strftime(suffix)
|
56
|
+
event[:_index] = idx_prefix + idx_suffix
|
57
|
+
stats.inc 'filter-index'
|
58
|
+
matched = true
|
59
|
+
rescue java.lang.IllegalArgumentException => e
|
64
60
|
end
|
65
|
-
|
66
|
-
|
67
|
-
|
61
|
+
break if matched
|
62
|
+
end
|
63
|
+
|
64
|
+
return filtered(event, conf) if matched
|
65
|
+
|
66
|
+
event[:_index] = idx_prefix + Time.now.utc.strftime(suffix)
|
67
|
+
|
68
|
+
log.warn \
|
69
|
+
event: 'filter-index-warning',
|
70
|
+
reason: 'could not parse event',
|
71
|
+
remediation: 'added bogus index',
|
72
|
+
remediation: "sending to best-guess index '#{event[:_index]}'",
|
73
|
+
stamp: stamp,
|
74
|
+
prefix: prefix,
|
75
|
+
suffix: suffix,
|
76
|
+
format: format,
|
77
|
+
raw_event: event.inspect
|
78
|
+
|
79
|
+
if error_tag
|
80
|
+
event[:tags] ||= []
|
81
|
+
event[:tags] << error_tag
|
68
82
|
end
|
83
|
+
|
84
|
+
stats.inc 'filter-index-error'
|
85
|
+
stats.inc 'filter-index'
|
86
|
+
filtered event, conf
|
69
87
|
end
|
88
|
+
|
70
89
|
end
|
71
90
|
end
|
72
91
|
end
|
data/lib/anschel/filter/parse.rb
CHANGED
@@ -7,30 +7,40 @@
|
|
7
7
|
module Anschel
|
8
8
|
class Filter
|
9
9
|
def parse conf, stats, log
|
10
|
-
field
|
10
|
+
field = conf.delete :field
|
11
11
|
pattern = Regexp.new conf.delete(:pattern)
|
12
|
+
unless_field = conf.delete(:unless_field) || '@timestamp'
|
13
|
+
|
14
|
+
error_tag = conf.has_key?(:error_tag) ? conf[:error_tag] : 'parse-error'
|
12
15
|
|
13
16
|
raise 'Missing required "field" for "parse" filter' if field.nil?
|
14
17
|
raise 'Missing required "pattern" for "parse" filter' if pattern.nil?
|
15
18
|
|
16
19
|
field = field.to_sym
|
20
|
+
unless_field = unless_field.to_sym
|
17
21
|
|
18
22
|
stats.create 'filter-parse'
|
19
|
-
stats.get 'filter-parse'
|
20
23
|
stats.create 'filter-parse-skipped'
|
21
|
-
stats.get 'filter-parse-skipped'
|
22
24
|
stats.create 'filter-parse-error'
|
23
|
-
stats.get 'filter-parse-error'
|
24
25
|
|
25
26
|
log.trace event: 'filter-compiled', kind: 'parse', \
|
26
27
|
field: field, pattern: pattern
|
27
28
|
|
29
|
+
|
30
|
+
|
28
31
|
lambda do |event|
|
29
32
|
unless event.has_key? field
|
30
33
|
stats.inc 'filter-parse-skipped'
|
31
34
|
return event
|
32
35
|
end
|
36
|
+
|
37
|
+
if event.has_key? unless_field
|
38
|
+
stats.inc 'filter-parse-skipped'
|
39
|
+
return event
|
40
|
+
end
|
41
|
+
|
33
42
|
mdata = pattern.match event[field]
|
43
|
+
|
34
44
|
if mdata.nil?
|
35
45
|
log.trace \
|
36
46
|
event: 'parse-filter-error',
|
@@ -39,14 +49,21 @@ module Anschel
|
|
39
49
|
pattern: pattern,
|
40
50
|
raw_event: event
|
41
51
|
stats.inc 'filter-parse-error'
|
52
|
+
if error_tag
|
53
|
+
event[:tags] ||= []
|
54
|
+
event[:tags] << error_tag
|
55
|
+
end
|
42
56
|
return event
|
43
57
|
end
|
58
|
+
|
44
59
|
mdata.names.each do |group|
|
45
60
|
event[group.to_sym] = mdata[group]
|
46
61
|
end
|
62
|
+
|
47
63
|
stats.inc 'filter-parse'
|
48
64
|
filtered event, conf
|
49
65
|
end
|
66
|
+
|
50
67
|
end
|
51
68
|
end
|
52
69
|
end
|
data/lib/anschel/filter/scan.rb
CHANGED
@@ -9,37 +9,52 @@ module Anschel
|
|
9
9
|
class Filter
|
10
10
|
def scan conf, stats, log
|
11
11
|
field = conf.delete :field
|
12
|
-
pattern =
|
12
|
+
pattern = conf.delete :pattern
|
13
13
|
target = conf.delete :target
|
14
14
|
|
15
|
+
error_tag = conf.has_key?(:error_tag) ? conf[:error_tag] : 'scan-error'
|
16
|
+
|
15
17
|
raise 'Missing required "field" for "scan" filter' if field.nil?
|
16
18
|
raise 'Missing required "pattern" for "scan" filter' if pattern.nil?
|
17
19
|
raise 'Missing required "target" for "convert" filter' if target.nil?
|
18
20
|
|
19
21
|
field = field.to_sym
|
20
22
|
target = target.to_sym
|
23
|
+
match = Regexp.new pattern
|
21
24
|
|
22
25
|
stats.create 'filter-scan'
|
23
|
-
stats.get 'filter-scan'
|
24
26
|
stats.create 'filter-scan-skipped'
|
25
|
-
stats.get 'filter-scan-skipped'
|
26
27
|
stats.create 'filter-scan-nomatch'
|
27
|
-
stats.get 'filter-scan-nomatch'
|
28
28
|
stats.create 'filter-scan-error'
|
29
|
-
stats.get 'filter-scan-error'
|
30
29
|
|
31
30
|
log.trace event: 'filter-compiled', kind: 'scan', \
|
32
|
-
field: field, pattern: pattern, target: target
|
31
|
+
field: field, pattern: pattern, match: match, target: target
|
32
|
+
|
33
|
+
|
33
34
|
|
34
35
|
lambda do |event|
|
35
36
|
unless event.has_key? field
|
36
37
|
stats.inc 'filter-scan-skipped'
|
37
38
|
return event
|
38
39
|
end
|
40
|
+
|
41
|
+
error = true
|
39
42
|
begin
|
40
|
-
results = event[field].scan(
|
43
|
+
results = event[field].scan(match).flatten.uniq.map do |s|
|
44
|
+
s.reverse.reverse # N.B. There seems to be some issue with the "scan"
|
45
|
+
# function in JRuby wherein the matches are
|
46
|
+
# shared across threads or somehow mangled.
|
47
|
+
# The reverse.reverse here ensures that we
|
48
|
+
# create a new object with the original
|
49
|
+
# contents still intact. If you have a
|
50
|
+
# better solution, please contact me!
|
51
|
+
end
|
52
|
+
error = false
|
41
53
|
rescue StandardError
|
42
|
-
|
54
|
+
end
|
55
|
+
|
56
|
+
if error
|
57
|
+
log.error \
|
43
58
|
event: 'scan-filter-error',
|
44
59
|
reason: 'could not scan event',
|
45
60
|
field: field,
|
@@ -47,12 +62,16 @@ module Anschel
|
|
47
62
|
target: target,
|
48
63
|
raw_event: event
|
49
64
|
stats.inc 'filter-scan-error'
|
50
|
-
|
51
|
-
|
65
|
+
if error_tag
|
66
|
+
event[:tags] ||= []
|
67
|
+
event[:tags] << error_tag
|
68
|
+
end
|
69
|
+
event
|
52
70
|
|
53
|
-
|
71
|
+
elsif results.empty?
|
54
72
|
stats.inc 'filter-scan-nomatch'
|
55
73
|
event
|
74
|
+
|
56
75
|
else
|
57
76
|
event[target] ||= []
|
58
77
|
event[target] += results
|
@@ -60,6 +79,7 @@ module Anschel
|
|
60
79
|
filtered event, conf
|
61
80
|
end
|
62
81
|
end
|
82
|
+
|
63
83
|
end
|
64
84
|
end
|
65
85
|
end
|
data/lib/anschel/filter/stamp.rb
CHANGED
@@ -6,6 +6,9 @@
|
|
6
6
|
# "target": "@timestamp"
|
7
7
|
# }
|
8
8
|
# }
|
9
|
+
require 'date'
|
10
|
+
require 'time'
|
11
|
+
|
9
12
|
module Anschel
|
10
13
|
class Filter
|
11
14
|
def stamp conf, stats, log
|
@@ -13,6 +16,8 @@ module Anschel
|
|
13
16
|
field = conf.delete :field
|
14
17
|
pattern = conf.delete :pattern
|
15
18
|
target = conf.delete :target
|
19
|
+
precision = conf.delete(:precision) || 3
|
20
|
+
|
16
21
|
error_tag = conf.has_key?(:error_tag) ? conf[:error_tag] : 'stamp-error'
|
17
22
|
|
18
23
|
raise 'Missing required "field" for "stamp" filter' if field.nil?
|
@@ -33,32 +38,52 @@ module Anschel
|
|
33
38
|
offset_s = utc ? Time.zone_offset(Time.now.zone).to_f : 0.0
|
34
39
|
|
35
40
|
stats.create 'filter-stamp'
|
36
|
-
stats.get 'filter-stamp'
|
37
41
|
stats.create 'filter-stamp-skipped'
|
38
|
-
stats.get 'filter-stamp-skipped'
|
39
42
|
stats.create 'filter-stamp-error'
|
40
|
-
stats.get 'filter-stamp-error'
|
41
43
|
|
42
44
|
log.trace event: 'filter-compiled', kind: 'stamp', \
|
43
45
|
utc?: utc, field: field, pattern: pattern, target: target
|
44
46
|
|
47
|
+
|
48
|
+
|
45
49
|
lambda do |event|
|
46
50
|
unless event.has_key? field
|
47
51
|
stats.inc 'filter-stamp-skipped'
|
48
52
|
return event
|
49
53
|
end
|
54
|
+
|
55
|
+
if event.has_key? target
|
56
|
+
log.warn \
|
57
|
+
event: 'stamp-filter-warning',
|
58
|
+
reason: 'event already has target field',
|
59
|
+
utc?: utc,
|
60
|
+
field: field,
|
61
|
+
pattern: pattern,
|
62
|
+
target: target,
|
63
|
+
raw_event: event
|
64
|
+
event[target] = \
|
65
|
+
DateTime.parse(event[target]).to_time.utc.iso8601(precision)
|
66
|
+
return event
|
67
|
+
end
|
68
|
+
|
69
|
+
event_field = event[field].dup
|
70
|
+
|
71
|
+
matched = false
|
50
72
|
parsers.each do |joda|
|
51
73
|
begin
|
52
74
|
millis = joda.parseMillis event[field]
|
53
|
-
event[target] = Time.at(0.001 * millis + offset_s).iso8601(
|
75
|
+
event[target] = Time.at(0.001 * millis + offset_s).utc.iso8601(precision)
|
54
76
|
stats.inc 'filter-stamp'
|
55
|
-
|
77
|
+
matched = true
|
56
78
|
rescue
|
57
79
|
end
|
80
|
+
break if matched
|
58
81
|
end
|
59
82
|
|
60
|
-
|
61
|
-
|
83
|
+
return filtered(event, conf) if matched
|
84
|
+
|
85
|
+
log.warn \
|
86
|
+
event: 'stamp-filter-warning',
|
62
87
|
reason: 'could not parse event',
|
63
88
|
remediation: 'using current time for stamp',
|
64
89
|
utc?: utc,
|
@@ -66,14 +91,17 @@ module Anschel
|
|
66
91
|
pattern: pattern,
|
67
92
|
target: target,
|
68
93
|
raw_event: event
|
94
|
+
|
69
95
|
if error_tag
|
70
96
|
event[:tags] ||= []
|
71
97
|
event[:tags] << error_tag
|
72
98
|
end
|
73
|
-
|
99
|
+
|
100
|
+
event[target] = Time.now.utc.iso8601(precision)
|
74
101
|
stats.inc 'filter-stamp-error'
|
75
102
|
filtered event, conf
|
76
103
|
end
|
104
|
+
|
77
105
|
end
|
78
106
|
end
|
79
107
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# {
|
2
|
+
# "tag": {
|
3
|
+
# "with": [ "" ]
|
4
|
+
# }
|
5
|
+
# }
|
6
|
+
module Anschel
|
7
|
+
class Filter
|
8
|
+
def tag conf, stats, log
|
9
|
+
tags = conf.delete :with
|
10
|
+
|
11
|
+
raise 'Missing required "with" for "tag" filter' if tags.nil?
|
12
|
+
|
13
|
+
tags = tags.is_a?(Array) ? tags : [ tags ]
|
14
|
+
|
15
|
+
stats.create 'filter-tag'
|
16
|
+
|
17
|
+
log.trace event: 'filter-compiled', kind: 'tag', with: tags
|
18
|
+
|
19
|
+
|
20
|
+
|
21
|
+
lambda do |event|
|
22
|
+
event[:tags] ||= []
|
23
|
+
event[:tags] += tags
|
24
|
+
event[:tags].uniq!
|
25
|
+
stats.inc 'filter-tag'
|
26
|
+
filtered event, conf
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/anschel/filter.rb
CHANGED
data/lib/anschel/input.rb
CHANGED
@@ -12,7 +12,7 @@ module Anschel
|
|
12
12
|
|
13
13
|
Thread.new do
|
14
14
|
leftovers ||= []
|
15
|
-
log.
|
15
|
+
log.warn event: 'input-leftovers', leftovers_size: leftovers.size
|
16
16
|
leftovers.each { |l| @queue << l }
|
17
17
|
end
|
18
18
|
|
@@ -25,10 +25,10 @@ module Anschel
|
|
25
25
|
case input.delete(:kind)
|
26
26
|
when 'kafka'
|
27
27
|
@inputs << Input::Kafka.new(@queue, input, stats, log)
|
28
|
-
log.
|
28
|
+
log.debug event: 'input-loaded', kind: 'kafka'
|
29
29
|
when 'rabbitmq'
|
30
30
|
@inputs << Input::RabbitMQ.new(@queue, input, stats, log)
|
31
|
-
log.
|
31
|
+
log.debug event: 'input-loaded', kind: 'rabbitmq'
|
32
32
|
else
|
33
33
|
raise 'Uknown input type'
|
34
34
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: anschel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sean Clemmer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-10-
|
11
|
+
date: 2015-10-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
@@ -122,11 +122,13 @@ files:
|
|
122
122
|
- lib/anschel.rb
|
123
123
|
- lib/anschel/filter.rb
|
124
124
|
- lib/anschel/filter/convert.rb
|
125
|
+
- lib/anschel/filter/debug.rb
|
125
126
|
- lib/anschel/filter/gsub.rb
|
126
127
|
- lib/anschel/filter/index.rb
|
127
128
|
- lib/anschel/filter/parse.rb
|
128
129
|
- lib/anschel/filter/scan.rb
|
129
130
|
- lib/anschel/filter/stamp.rb
|
131
|
+
- lib/anschel/filter/tag.rb
|
130
132
|
- lib/anschel/input.rb
|
131
133
|
- lib/anschel/input/base.rb
|
132
134
|
- lib/anschel/input/kafka.rb
|