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 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
@@ -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
@@ -12,6 +12,7 @@ class LogStash::Inputs::File < LogStash::Inputs::Base
12
12
  end
13
13
 
14
14
  def register
15
+ @logger.info("Registering #{@url}")
15
16
  EventMachine::FileGlobWatchTail.new(@url.path, Reader, interval=60,
16
17
  exclude=[], receiver=self)
17
18
  end # def register
@@ -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)
@@ -88,7 +88,7 @@
88
88
  var a = params[p].split("=");
89
89
  var key = a[0]
90
90
  var value = a[1]
91
- logstash.params[key] = value
91
+ logstash.params[key] = unescape(value)
92
92
  }
93
93
  logstash.search(logstash.params.q)
94
94
  return false;
@@ -35,4 +35,5 @@
35
35
  - @hits.reverse.each do |hit|
36
36
  %tr.event
37
37
  %td.timestamp&= hit["_source"]["@timestamp"]
38
- %td.message{ :"data-full" => hit.to_json }&= hit["_source"]["@message"]
38
+ %td.message{ :"data-full" => hit.to_json }
39
+ %pre&= hit["_source"]["@message"]
@@ -22,13 +22,18 @@ body
22
22
  margin-top: 1em
23
23
  #content table.results
24
24
  font-family: monospace
25
- #content td.event
25
+ #content td.message
26
+ vertical-align: top
27
+ padding: 1px
26
28
  padding-bottom: 3px
27
- white-space: pre-wrap
29
+ pre
30
+ white-space: pre-wrap
31
+ margin: 0
28
32
  #content td.timestamp
29
33
  white-space: nowrap
30
- font-size: 85%
31
- text-align: top
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
@@ -0,0 +1,3 @@
1
+ JAVACLASS (?:[a-zA-Z0-9-]+\.)+[A-Za-z0-9]+
2
+ JAVAFILE (?:[A-Za-z0-9_.-]+)
3
+ JAVASTACKTRACEPART at %{JAVACLASS:class}\.%{WORD:method}\(%{JAVAFILE:file}:%{NUMBER:line}\)
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: 40202238366243
4
+ hash: 40202240043587
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 2
9
- - 20101119183130
10
- version: 0.2.20101119183130
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-19 00:00:00 -08:00
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