logstash-lite 0.2.20101119183130 → 0.2.20101120021802
Sign up to get free protection for your applications and to get access to all the features.
- data/etc/prod.yaml +15 -0
- data/lib/logstash/event.rb +19 -0
- data/lib/logstash/filters/multiline.rb +158 -0
- data/lib/logstash/inputs/file.rb +1 -0
- data/lib/logstash/web/lib/elasticsearch.rb +3 -2
- data/lib/logstash/web/public/js/logstash.js +1 -1
- data/lib/logstash/web/views/search/ajax.haml +2 -1
- data/lib/logstash/web/views/style.sass +9 -4
- data/patterns/java +3 -0
- metadata +6 -4
data/etc/prod.yaml
CHANGED
@@ -11,6 +11,8 @@ inputs:
|
|
11
11
|
- /var/log/apache2/access.log
|
12
12
|
apache-error:
|
13
13
|
- /var/log/apache2/error.log
|
14
|
+
testing:
|
15
|
+
- /tmp/logstashtest.log
|
14
16
|
filters:
|
15
17
|
- grok:
|
16
18
|
linux-syslog: # for logs of type 'linux-syslog'
|
@@ -22,6 +24,12 @@ filters:
|
|
22
24
|
nagios:
|
23
25
|
patterns:
|
24
26
|
- %{NAGIOSLOGLINE}
|
27
|
+
loggly:
|
28
|
+
patterns:
|
29
|
+
- %{JAVASTACKTRACEPART}
|
30
|
+
testing:
|
31
|
+
patterns:
|
32
|
+
- %{JAVASTACKTRACEPART}
|
25
33
|
- date:
|
26
34
|
linux-syslog: # for logs of type 'linux-syslog'
|
27
35
|
# Look for a field 'timestamp' with this format, parse and it for the timestamp
|
@@ -32,6 +40,13 @@ filters:
|
|
32
40
|
timestamp: "%d/%b/%Y:%H:%M:%S %Z"
|
33
41
|
nagios:
|
34
42
|
epochtime: %s
|
43
|
+
- multiline:
|
44
|
+
supervisorlogs:
|
45
|
+
pattern: ^\s
|
46
|
+
what: previous
|
47
|
+
testing:
|
48
|
+
pattern: ^\s
|
49
|
+
what: previous
|
35
50
|
outputs:
|
36
51
|
- stdout:///
|
37
52
|
#- elasticsearch://localhost:9200/logstash/all
|
data/lib/logstash/event.rb
CHANGED
@@ -66,5 +66,24 @@ module LogStash; class Event
|
|
66
66
|
|
67
67
|
def to_hash; return @data end # def to_hash
|
68
68
|
|
69
|
+
def overwrite(event)
|
70
|
+
@data = event.to_hash
|
71
|
+
end
|
72
|
+
|
69
73
|
def include?(key); return @data.include?(key) end
|
74
|
+
|
75
|
+
# Append an event to this one.
|
76
|
+
def append(event)
|
77
|
+
self.message += "\n" + event.message
|
78
|
+
self.tags |= event.tags
|
79
|
+
|
80
|
+
# Append all fields
|
81
|
+
event.fields.each do |name, value|
|
82
|
+
if event.fields.include?(name)
|
83
|
+
event.fields[name] |= value
|
84
|
+
else
|
85
|
+
event.fields[name] = value
|
86
|
+
end
|
87
|
+
end # event.fields.each
|
88
|
+
end
|
70
89
|
end; end # class LogStash::Event
|
@@ -0,0 +1,158 @@
|
|
1
|
+
# multiline filter
|
2
|
+
#
|
3
|
+
# This filter will collapse multiline messages into a single event.
|
4
|
+
#
|
5
|
+
|
6
|
+
require "logstash/filters/base"
|
7
|
+
|
8
|
+
class LogStash::Filters::Multiline < LogStash::Filters::Base
|
9
|
+
# The 'date' filter will take a value from your event and use it as the
|
10
|
+
# event timestamp. This is useful for parsing logs generated on remote
|
11
|
+
# servers or for importing old logs.
|
12
|
+
#
|
13
|
+
# The config looks like this:
|
14
|
+
#
|
15
|
+
# filters:
|
16
|
+
# - multiline:
|
17
|
+
# <type>:
|
18
|
+
# pattern: <regexp>
|
19
|
+
# what: next
|
20
|
+
# <type>
|
21
|
+
# pattern: <regexp>
|
22
|
+
# what: previous
|
23
|
+
#
|
24
|
+
# The 'regexp' should match what you believe to be an indicator that
|
25
|
+
# the field is part of a multi-line event
|
26
|
+
#
|
27
|
+
# The 'what' must be "previous" or "next" and indicates the relation
|
28
|
+
# to the multi-line event.
|
29
|
+
#
|
30
|
+
# For example, java stack traces are multiline and usually have the message
|
31
|
+
# starting at the far-left, then each subsequent line indented. Do this:
|
32
|
+
#
|
33
|
+
# filters:
|
34
|
+
# - multiline:
|
35
|
+
# somefiletype:
|
36
|
+
# pattern: /^\s/
|
37
|
+
# what: previous
|
38
|
+
#
|
39
|
+
# This says that any line starting with whitespace belongs to the previous line.
|
40
|
+
#
|
41
|
+
# Another example is C line continuations (backslash). Here's how to do that:
|
42
|
+
#
|
43
|
+
# filters:
|
44
|
+
# - multiline:
|
45
|
+
# somefiletype:
|
46
|
+
# pattern: /\\$/
|
47
|
+
# what: next
|
48
|
+
#
|
49
|
+
def initialize(config = {})
|
50
|
+
super
|
51
|
+
|
52
|
+
@types = Hash.new { |h,k| h[k] = [] }
|
53
|
+
@pending = Hash.new
|
54
|
+
end # def initialize
|
55
|
+
|
56
|
+
def register
|
57
|
+
@config.each do |type, typeconfig|
|
58
|
+
# typeconfig will be a hash containing 'pattern' and 'what'
|
59
|
+
@logger.debug "Setting type #{type.inspect} to the config #{typeconfig.inspect}"
|
60
|
+
raise "type \"#{type}\" defined more than once" unless @types[type].empty?
|
61
|
+
@types[type] = typeconfig
|
62
|
+
|
63
|
+
if !typeconfig.include?("pattern")
|
64
|
+
@logger.fatal(["'multiline' filter config for type #{type} is missing" \
|
65
|
+
" 'pattern' setting", typeconfig])
|
66
|
+
end
|
67
|
+
|
68
|
+
if !typeconfig.include?("what")
|
69
|
+
@logger.fatal(["'multiline' filter config for type #{type} is missing" \
|
70
|
+
" 'what' setting", typeconfig])
|
71
|
+
end
|
72
|
+
|
73
|
+
if !["next", "previous"].include?(typeconfig["what"])
|
74
|
+
@logger.fatal(["'multiline' filter config for type #{type} has " \
|
75
|
+
"invalid 'what' value. Must be 'next' or 'previous'",
|
76
|
+
typeconfig])
|
77
|
+
end
|
78
|
+
|
79
|
+
begin
|
80
|
+
typeconfig["pattern"] = Regexp.new(typeconfig["pattern"])
|
81
|
+
rescue RegexpError => e
|
82
|
+
@logger.fatal(["Invalid pattern for multiline filter on type '#{type}'",
|
83
|
+
typeconfig, e])
|
84
|
+
end
|
85
|
+
|
86
|
+
end # @config.each
|
87
|
+
end # def register
|
88
|
+
|
89
|
+
def filter(event)
|
90
|
+
return unless @types.member?(event.type)
|
91
|
+
typeconfig = @types[event.type]
|
92
|
+
match = typeconfig["pattern"].match(event.message)
|
93
|
+
key = [event.source, event.type]
|
94
|
+
pending = @pending[key]
|
95
|
+
|
96
|
+
@logger.info(["Reg: ", typeconfig["pattern"], event.message, match])
|
97
|
+
case typeconfig["what"]
|
98
|
+
when "previous"
|
99
|
+
if match
|
100
|
+
event.tags |= ["multiline"]
|
101
|
+
# previous previous line is part of this event.
|
102
|
+
# append it to the event and cancel it
|
103
|
+
if pending
|
104
|
+
pending.append(event)
|
105
|
+
else
|
106
|
+
@pending[key] = event
|
107
|
+
end
|
108
|
+
event.cancel
|
109
|
+
else
|
110
|
+
# this line is not part of the previous event
|
111
|
+
# if we have a pending event, it's done, send it.
|
112
|
+
# put the current event into pending
|
113
|
+
if pending
|
114
|
+
tmp = event.to_hash
|
115
|
+
event.overwrite(pending)
|
116
|
+
@pending[key] = LogStash::Event.new(tmp)
|
117
|
+
else
|
118
|
+
@pending[key] = event
|
119
|
+
event.cancel
|
120
|
+
end # if/else pending
|
121
|
+
end # if/else match
|
122
|
+
when "next"
|
123
|
+
if match
|
124
|
+
event.tags |= ["multiline"]
|
125
|
+
# this line is part of a multiline event, the next
|
126
|
+
# line will be part, too, put it into pending.
|
127
|
+
if pending
|
128
|
+
pending.append(event)
|
129
|
+
else
|
130
|
+
@pending[key] = event
|
131
|
+
end
|
132
|
+
event.cancel
|
133
|
+
else
|
134
|
+
# if we have something in pending, join it with this message
|
135
|
+
# and send it. otherwise, this is a new message and not part of
|
136
|
+
# multiline, send it.
|
137
|
+
if pending
|
138
|
+
pending.append(event)
|
139
|
+
event.overwrite(pending.to_hash)
|
140
|
+
@pending.delete(key)
|
141
|
+
end
|
142
|
+
end # if/else match
|
143
|
+
else
|
144
|
+
@logger.warn(["Unknown multiline 'what' value.", typeconfig])
|
145
|
+
end # case typeconfig["what"]
|
146
|
+
#end # @types[event.type].each
|
147
|
+
end # def filter
|
148
|
+
|
149
|
+
# flush any pending messages
|
150
|
+
def flush(source, type)
|
151
|
+
key = [source, type]
|
152
|
+
if @pending[key]
|
153
|
+
event = @pending[key]
|
154
|
+
@pending.delete(key)
|
155
|
+
end
|
156
|
+
return event
|
157
|
+
end
|
158
|
+
end # class LogStash::Filters::Date
|
data/lib/logstash/inputs/file.rb
CHANGED
@@ -46,8 +46,9 @@ class LogStash::Web::ElasticSearch
|
|
46
46
|
data["duration"] = Time.now - start_time
|
47
47
|
|
48
48
|
# TODO(sissel): Plugin-ify this (Search filters!)
|
49
|
-
require "digest/md5"
|
50
|
-
data["hits"]["hits"].each do |hit|
|
49
|
+
#require "digest/md5"
|
50
|
+
#data["hits"]["hits"].each do |hit|
|
51
|
+
[].each do |hit|
|
51
52
|
event = LogStash::Event.new(hit["_source"])
|
52
53
|
event.to_hash.each do |key, value|
|
53
54
|
next unless value.is_a?(String)
|
@@ -22,13 +22,18 @@ body
|
|
22
22
|
margin-top: 1em
|
23
23
|
#content table.results
|
24
24
|
font-family: monospace
|
25
|
-
#content td.
|
25
|
+
#content td.message
|
26
|
+
vertical-align: top
|
27
|
+
padding: 1px
|
26
28
|
padding-bottom: 3px
|
27
|
-
|
29
|
+
pre
|
30
|
+
white-space: pre-wrap
|
31
|
+
margin: 0
|
28
32
|
#content td.timestamp
|
29
33
|
white-space: nowrap
|
30
|
-
|
31
|
-
|
34
|
+
padding: 1px
|
35
|
+
//font-size: 85%
|
36
|
+
vertical-align: top
|
32
37
|
#content tr.selected
|
33
38
|
background-color: #FCE69D !important
|
34
39
|
#content tr.event:nth-child(2n)
|
data/patterns/java
ADDED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: logstash-lite
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 40202240043587
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 2
|
9
|
-
-
|
10
|
-
version: 0.2.
|
9
|
+
- 20101120021802
|
10
|
+
version: 0.2.20101120021802
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Jordan Sissel
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-11-
|
18
|
+
date: 2010-11-20 00:00:00 -08:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -76,6 +76,7 @@ files:
|
|
76
76
|
- lib/logstash/filters.rb
|
77
77
|
- lib/logstash/outputs.rb
|
78
78
|
- lib/logstash/filters/grokdiscovery.rb
|
79
|
+
- lib/logstash/filters/multiline.rb
|
79
80
|
- lib/logstash/filters/grok.rb
|
80
81
|
- lib/logstash/filters/base.rb
|
81
82
|
- lib/logstash/filters/field.rb
|
@@ -183,6 +184,7 @@ files:
|
|
183
184
|
- etc/logstash-shipper.yaml
|
184
185
|
- patterns/linux-syslog
|
185
186
|
- patterns/haproxy
|
187
|
+
- patterns/java
|
186
188
|
- patterns/grok-patterns
|
187
189
|
- patterns/ruby
|
188
190
|
- patterns/firewalls
|