logstash-lite 0.2.20101222161646 → 0.2.20110112115019
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/logstash +13 -2
- data/bin/logstash-test +1 -3
- data/lib/logstash.rb +1 -1
- data/lib/logstash/agent.rb +37 -40
- data/lib/logstash/event.rb +20 -5
- data/lib/logstash/filters.rb +1 -1
- data/lib/logstash/filters/base.rb +6 -1
- data/lib/logstash/filters/date.rb +4 -0
- data/lib/logstash/filters/field.rb +4 -5
- data/lib/logstash/filters/grep.rb +39 -3
- data/lib/logstash/filters/grok.rb +10 -3
- data/lib/logstash/filters/grokdiscovery.rb +4 -1
- data/lib/logstash/filters/multiline.rb +6 -2
- data/lib/logstash/inputs.rb +6 -2
- data/lib/logstash/inputs/amqp.rb +5 -2
- data/lib/logstash/inputs/base.rb +17 -4
- data/lib/logstash/inputs/beanstalk.rb +5 -2
- data/lib/logstash/inputs/file.rb +7 -2
- data/lib/logstash/inputs/internal.rb +5 -2
- data/lib/logstash/inputs/stdin.rb +38 -0
- data/lib/logstash/inputs/stomp.rb +14 -12
- data/lib/logstash/inputs/syslog.rb +10 -5
- data/lib/logstash/inputs/tcp.rb +8 -3
- data/lib/logstash/inputs/twitter.rb +81 -0
- data/lib/logstash/logging.rb +4 -1
- data/lib/logstash/namespace.rb +0 -1
- data/lib/logstash/outputs.rb +1 -1
- data/lib/logstash/outputs/amqp.rb +9 -2
- data/lib/logstash/outputs/base.rb +7 -3
- data/lib/logstash/outputs/beanstalk.rb +4 -0
- data/lib/logstash/outputs/elasticsearch.rb +86 -18
- data/lib/logstash/outputs/gelf.rb +5 -6
- data/lib/logstash/outputs/internal.rb +7 -1
- data/lib/logstash/outputs/mongodb.rb +10 -10
- data/lib/logstash/outputs/nagios.rb +6 -2
- data/lib/logstash/outputs/stdout.rb +3 -4
- data/lib/logstash/outputs/stomp.rb +4 -0
- data/lib/logstash/outputs/tcp.rb +3 -4
- data/lib/logstash/outputs/websocket.rb +5 -6
- data/lib/logstash/ruby_fixes.rb +1 -3
- data/lib/logstash/stomp/handler.rb +29 -4
- data/lib/logstash/web/lib/elasticsearch.rb +8 -4
- data/lib/logstash/web/public/js/logstash.js +25 -5
- data/lib/logstash/web/public/ws/index.html +9 -7
- data/lib/logstash/web/server.rb +50 -12
- data/lib/logstash/web/views/search/ajax.haml +5 -2
- data/lib/logstash/web/views/search/results.txt.erb +10 -0
- metadata +7 -4
data/bin/logstash
CHANGED
@@ -68,8 +68,19 @@ if settings.daemonize
|
|
68
68
|
end
|
69
69
|
end
|
70
70
|
|
71
|
-
agent = LogStash::Agent.new(config)
|
72
71
|
if settings.logfile
|
73
|
-
|
72
|
+
logfile = File.open(settings.logfile, "w")
|
73
|
+
STDOUT.reopen(logfile)
|
74
|
+
STDERR.reopen(logfile)
|
75
|
+
elsif settings.daemonize
|
76
|
+
# Write to /dev/null if
|
77
|
+
devnull = File.open("/dev/null", "w")
|
78
|
+
STDOUT.reopen(devnull)
|
79
|
+
STDERR.reopen(devnull)
|
74
80
|
end
|
81
|
+
|
82
|
+
agent = LogStash::Agent.new(config)
|
83
|
+
#if settings.logfile
|
84
|
+
#agent.log_to(settings.logfile)
|
85
|
+
#end
|
75
86
|
agent.run
|
data/bin/logstash-test
CHANGED
@@ -60,9 +60,7 @@ def check_libraries
|
|
60
60
|
end
|
61
61
|
|
62
62
|
def run_tests
|
63
|
-
require "
|
64
|
-
require "logstash/filters/test_date"
|
65
|
-
require "logstash/filters/test_multiline"
|
63
|
+
require "#{File.dirname(__FILE__)}/../test/run"
|
66
64
|
return Test::Unit::AutoRunner.run
|
67
65
|
end
|
68
66
|
|
data/lib/logstash.rb
CHANGED
data/lib/logstash/agent.rb
CHANGED
@@ -13,6 +13,7 @@ class LogStash::Agent
|
|
13
13
|
attr_reader :outputs
|
14
14
|
attr_reader :filters
|
15
15
|
|
16
|
+
public
|
16
17
|
def initialize(config)
|
17
18
|
log_to(STDERR)
|
18
19
|
|
@@ -44,28 +45,26 @@ class LogStash::Agent
|
|
44
45
|
end
|
45
46
|
|
46
47
|
# Register input and output stuff
|
47
|
-
|
48
|
-
|
49
|
-
inputs
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
end
|
48
|
+
inputs = @config["inputs"]
|
49
|
+
inputs.each do |value|
|
50
|
+
# If 'url' is an array, then inputs is a hash and the key is the type
|
51
|
+
if inputs.is_a?(Hash)
|
52
|
+
type, urls = value
|
53
|
+
else
|
54
|
+
raise "config error, no type for url #{urls.inspect}"
|
55
|
+
end
|
56
56
|
|
57
|
-
|
58
|
-
|
57
|
+
# url could be a string or an array.
|
58
|
+
urls = [urls] if !urls.is_a?(Array)
|
59
59
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
end
|
60
|
+
urls.each do |url|
|
61
|
+
@logger.debug("Using input #{url} of type #{type}")
|
62
|
+
input = LogStash::Inputs.from_url(url, type) { |event| receive(event) }
|
63
|
+
input.logger = @logger
|
64
|
+
input.register
|
65
|
+
@inputs << input
|
66
|
+
end
|
67
|
+
end # each input
|
69
68
|
|
70
69
|
if @config.include?("filters")
|
71
70
|
filters = @config["filters"]
|
@@ -77,20 +76,18 @@ class LogStash::Agent
|
|
77
76
|
filter.register
|
78
77
|
@filters << filter
|
79
78
|
end # each filter
|
80
|
-
end
|
81
|
-
|
82
|
-
|
83
|
-
@
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
end # each output
|
90
|
-
end
|
79
|
+
end # if we have filters
|
80
|
+
|
81
|
+
@config["outputs"].each do |url|
|
82
|
+
@logger.debug("Using output #{url}")
|
83
|
+
output = LogStash::Outputs.from_url(url)
|
84
|
+
output.logger = @logger
|
85
|
+
output.register
|
86
|
+
@outputs << output
|
87
|
+
end # each output
|
91
88
|
|
92
89
|
# Register any signal handlers
|
93
|
-
|
90
|
+
register_signal_handler
|
94
91
|
end # def register
|
95
92
|
|
96
93
|
public
|
@@ -106,16 +103,16 @@ class LogStash::Agent
|
|
106
103
|
# TODO(sissel): Stop inputs, fluch outputs, wait for finish,
|
107
104
|
# then stop the event loop
|
108
105
|
EventMachine.stop_event_loop
|
109
|
-
|
106
|
+
|
107
|
+
# EventMachine has no default way to indicate a 'stopping' state.
|
108
|
+
$EVENTMACHINE_STOPPING = true
|
109
|
+
end # def stop
|
110
110
|
|
111
111
|
protected
|
112
112
|
def filter(event)
|
113
113
|
@filters.each do |f|
|
114
|
-
# TODO(sissel): Add ability for a filter to cancel/drop a message
|
115
114
|
f.filter(event)
|
116
|
-
if event.cancelled?
|
117
|
-
break
|
118
|
-
end
|
115
|
+
break if event.cancelled?
|
119
116
|
end
|
120
117
|
end # def filter
|
121
118
|
|
@@ -137,7 +134,7 @@ class LogStash::Agent
|
|
137
134
|
end # def input
|
138
135
|
|
139
136
|
public
|
140
|
-
def
|
137
|
+
def register_signal_handler
|
141
138
|
@sigchannel = EventMachine::Channel.new
|
142
139
|
Signal.trap("USR1") do
|
143
140
|
@sigchannel.push(:USR1)
|
@@ -172,5 +169,5 @@ class LogStash::Agent
|
|
172
169
|
# hooks.
|
173
170
|
end # case msg
|
174
171
|
end # @sigchannel.subscribe
|
175
|
-
end # def
|
176
|
-
end # class LogStash::
|
172
|
+
end # def register_signal_handler
|
173
|
+
end # class LogStash::Agent
|
data/lib/logstash/event.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
require "json"
|
2
2
|
require "logstash/time"
|
3
|
+
require "logstash/namespace"
|
3
4
|
require "uri"
|
4
5
|
|
5
6
|
# General event type. Will expand this in the future.
|
6
|
-
|
7
|
+
class LogStash::Event
|
8
|
+
public
|
7
9
|
def initialize(data=Hash.new)
|
8
10
|
@cancelled = false
|
9
11
|
@data = {
|
@@ -18,25 +20,31 @@ module LogStash; class Event
|
|
18
20
|
end
|
19
21
|
end # def initialize
|
20
22
|
|
23
|
+
public
|
21
24
|
def self.from_json(json)
|
22
|
-
return Event.new(JSON.parse(json))
|
25
|
+
return LogStash::Event.new(JSON.parse(json))
|
23
26
|
end # def self.from_json
|
24
27
|
|
28
|
+
public
|
25
29
|
def cancel
|
26
30
|
@cancelled = true
|
27
31
|
end
|
28
32
|
|
33
|
+
public
|
29
34
|
def cancelled?
|
30
35
|
return @cancelled
|
31
36
|
end
|
32
37
|
|
38
|
+
public
|
33
39
|
def to_s
|
34
40
|
return "#{timestamp} #{source}: #{message}"
|
35
41
|
end # def to_s
|
36
42
|
|
43
|
+
public
|
37
44
|
def timestamp; @data["@timestamp"]; end # def timestamp
|
38
45
|
def timestamp=(val); @data["@timestamp"] = val; end # def timestamp=
|
39
46
|
|
47
|
+
public
|
40
48
|
def source; @data["@source"]; end # def source
|
41
49
|
def source=(val)
|
42
50
|
if val.is_a?(URI)
|
@@ -48,31 +56,38 @@ module LogStash; class Event
|
|
48
56
|
end
|
49
57
|
end # def source=
|
50
58
|
|
59
|
+
public
|
51
60
|
def message; @data["@message"]; end # def message
|
52
61
|
def message=(val); @data["@message"] = val; end # def message=
|
53
62
|
|
63
|
+
public
|
54
64
|
def type; @data["@type"]; end # def type
|
55
65
|
def type=(val); @data["@type"] = val; end # def type=
|
56
66
|
|
67
|
+
public
|
57
68
|
def tags; @data["@tags"]; end # def tags
|
58
69
|
def tags=(val); @data["@tags"] = val; end # def tags=
|
59
70
|
|
60
71
|
# field-related access
|
72
|
+
public
|
61
73
|
def [](key); @data["@fields"][key] end # def []
|
62
74
|
def []=(key, value); @data["@fields"][key] = value end # def []=
|
63
75
|
def fields; return @data["@fields"] end # def fields
|
64
76
|
|
77
|
+
public
|
65
78
|
def to_json; return @data.to_json end # def to_json
|
66
|
-
|
67
79
|
def to_hash; return @data end # def to_hash
|
68
80
|
|
81
|
+
public
|
69
82
|
def overwrite(event)
|
70
83
|
@data = event.to_hash
|
71
84
|
end
|
72
85
|
|
86
|
+
public
|
73
87
|
def include?(key); return @data.include?(key) end
|
74
88
|
|
75
89
|
# Append an event to this one.
|
90
|
+
public
|
76
91
|
def append(event)
|
77
92
|
self.message += "\n" + event.message
|
78
93
|
self.tags |= event.tags
|
@@ -87,5 +102,5 @@ module LogStash; class Event
|
|
87
102
|
self.fields[name] = value
|
88
103
|
end
|
89
104
|
end # event.fields.each
|
90
|
-
end
|
91
|
-
end
|
105
|
+
end # def append
|
106
|
+
end # class LogStash::Event
|
data/lib/logstash/filters.rb
CHANGED
@@ -3,24 +3,29 @@ require "logstash/logging"
|
|
3
3
|
|
4
4
|
class LogStash::Filters::Base
|
5
5
|
attr_accessor :logger
|
6
|
+
|
7
|
+
public
|
6
8
|
def initialize(config = {})
|
7
9
|
@logger = LogStash::Logger.new(STDERR)
|
8
10
|
@config = config
|
9
11
|
end # def initialize
|
10
12
|
|
13
|
+
public
|
11
14
|
def register
|
12
15
|
raise "#{self.class}#register must be overidden"
|
13
16
|
end # def register
|
14
17
|
|
18
|
+
public
|
15
19
|
def filter(event)
|
16
20
|
raise "#{self.class}#filter must be overidden"
|
17
21
|
end # def filter
|
18
22
|
|
23
|
+
public
|
19
24
|
def add_config(type, typeconfig)
|
20
25
|
if @config.include?(type)
|
21
26
|
@config[type].merge!(typeconfig)
|
22
27
|
else
|
23
28
|
@config[type] = typeconfig
|
24
29
|
end
|
25
|
-
end
|
30
|
+
end # def add_config
|
26
31
|
end # class LogStash::Filters::Base
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require "logstash/filters/base"
|
2
|
+
require "logstash/namespace"
|
2
3
|
require "logstash/time"
|
3
4
|
|
4
5
|
class LogStash::Filters::Date < LogStash::Filters::Base
|
@@ -16,12 +17,14 @@ class LogStash::Filters::Date < LogStash::Filters::Base
|
|
16
17
|
# <fieldname>: <format>
|
17
18
|
#
|
18
19
|
# The format is whatever is supported by Ruby's DateTime.strptime
|
20
|
+
public
|
19
21
|
def initialize(config = {})
|
20
22
|
super
|
21
23
|
|
22
24
|
@types = Hash.new { |h,k| h[k] = [] }
|
23
25
|
end # def initialize
|
24
26
|
|
27
|
+
public
|
25
28
|
def register
|
26
29
|
@config.each do |type, typeconfig|
|
27
30
|
@logger.debug "Setting type #{type.inspect} to the config #{typeconfig.inspect}"
|
@@ -30,6 +33,7 @@ class LogStash::Filters::Date < LogStash::Filters::Base
|
|
30
33
|
end # @config.each
|
31
34
|
end # def register
|
32
35
|
|
36
|
+
public
|
33
37
|
def filter(event)
|
34
38
|
@logger.debug "DATE FILTER: received event of type #{event.type}"
|
35
39
|
return unless @types.member?(event.type)
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require "logstash/filters/base"
|
2
|
+
require "logstash/namespace"
|
2
3
|
require "ostruct"
|
3
4
|
|
4
5
|
class LogStash::Filters::Field < LogStash::Filters::Base
|
@@ -8,14 +9,12 @@ class LogStash::Filters::Field < LogStash::Filters::Base
|
|
8
9
|
end
|
9
10
|
end
|
10
11
|
|
11
|
-
|
12
|
-
super
|
13
|
-
end # def initialize
|
14
|
-
|
12
|
+
public
|
15
13
|
def register
|
16
14
|
# nothing to do
|
17
15
|
end # def register
|
18
16
|
|
17
|
+
public
|
19
18
|
def filter(event)
|
20
19
|
data = EvalSpace.new(event.to_hash)
|
21
20
|
|
@@ -25,5 +24,5 @@ class LogStash::Filters::Field < LogStash::Filters::Base
|
|
25
24
|
end
|
26
25
|
end
|
27
26
|
event.cancel
|
28
|
-
end
|
27
|
+
end # def filter
|
29
28
|
end # class LogStash::Filters::Field
|
@@ -1,12 +1,37 @@
|
|
1
1
|
require "logstash/filters/base"
|
2
|
+
require "logstash/namespace"
|
2
3
|
|
4
|
+
# Grep filter.
|
5
|
+
#
|
6
|
+
# Useful for:
|
7
|
+
# * Dropping events
|
8
|
+
# * Tagging events
|
9
|
+
# * Adding static fields
|
10
|
+
#
|
11
|
+
# Events not matched ar dropped. If 'negate' is set to true (defaults false), then
|
12
|
+
# matching events are dropped.
|
13
|
+
#
|
14
|
+
# Config:
|
15
|
+
# - grep:
|
16
|
+
# <type>:
|
17
|
+
# - match:
|
18
|
+
# <field>: <regexp>
|
19
|
+
# negate: true/false
|
20
|
+
# add_fields:
|
21
|
+
# <field>: <value>
|
22
|
+
# add_tags:
|
23
|
+
# - tag1
|
24
|
+
# - tag2
|
25
|
+
#
|
3
26
|
class LogStash::Filters::Grep < LogStash::Filters::Base
|
27
|
+
public
|
4
28
|
def initialize(config = {})
|
5
29
|
super
|
6
30
|
|
7
31
|
@config = config
|
8
32
|
end # def initialize
|
9
33
|
|
34
|
+
public
|
10
35
|
def register
|
11
36
|
@config.each do |type, matches|
|
12
37
|
if ! matches.is_a?(Array)
|
@@ -29,6 +54,7 @@ class LogStash::Filters::Grep < LogStash::Filters::Base
|
|
29
54
|
end # @config.each
|
30
55
|
end # def register
|
31
56
|
|
57
|
+
public
|
32
58
|
def filter(event)
|
33
59
|
config = @config[event.type]
|
34
60
|
if not config
|
@@ -37,7 +63,7 @@ class LogStash::Filters::Grep < LogStash::Filters::Base
|
|
37
63
|
return
|
38
64
|
end
|
39
65
|
|
40
|
-
@logger.debug(["Running grep filter", event, config])
|
66
|
+
@logger.debug(["Running grep filter", event.to_hash, config])
|
41
67
|
matched = false
|
42
68
|
config.each do |match|
|
43
69
|
if ! match["match"]
|
@@ -51,9 +77,18 @@ class LogStash::Filters::Grep < LogStash::Filters::Base
|
|
51
77
|
match["match"].each do |field, re|
|
52
78
|
next unless event[field]
|
53
79
|
|
80
|
+
if event[field].empty? and match["negate"] == true
|
81
|
+
match_count += 1
|
82
|
+
end
|
54
83
|
event[field].each do |value|
|
55
|
-
|
56
|
-
|
84
|
+
if match["negate"] == true
|
85
|
+
@logger.debug("want negate match")
|
86
|
+
next if re.match(value)
|
87
|
+
@logger.debug(["grep not-matched (negate requsted)", { field => value }])
|
88
|
+
else
|
89
|
+
next unless re.match(value)
|
90
|
+
@logger.debug(["grep matched", { field => value }])
|
91
|
+
end
|
57
92
|
match_count += 1
|
58
93
|
break
|
59
94
|
end
|
@@ -77,6 +112,7 @@ class LogStash::Filters::Grep < LogStash::Filters::Base
|
|
77
112
|
@logger.debug("grep: adding tag #{tag}")
|
78
113
|
end
|
79
114
|
end # if match["add_tags"]
|
115
|
+
|
80
116
|
else
|
81
117
|
@logger.debug("match block failed " \
|
82
118
|
"(#{match_count}/#{match["match"].length} matches)")
|
@@ -1,15 +1,18 @@
|
|
1
1
|
require "logstash/filters/base"
|
2
|
+
require "logstash/namespace"
|
2
3
|
|
3
4
|
gem "jls-grok", ">=0.2.3071"
|
4
5
|
require "grok" # rubygem 'jls-grok'
|
5
6
|
|
6
7
|
class LogStash::Filters::Grok < LogStash::Filters::Base
|
8
|
+
public
|
7
9
|
def initialize(config = {})
|
8
10
|
super
|
9
11
|
|
10
12
|
@grokpiles = {}
|
11
13
|
end # def initialize
|
12
14
|
|
15
|
+
public
|
13
16
|
def register
|
14
17
|
# TODO(sissel): Make patterns files come from the config
|
15
18
|
@config.each do |type, typeconfig|
|
@@ -27,6 +30,7 @@ class LogStash::Filters::Grok < LogStash::Filters::Base
|
|
27
30
|
end # @config.each
|
28
31
|
end # def register
|
29
32
|
|
33
|
+
public
|
30
34
|
def filter(event)
|
31
35
|
# parse it with grok
|
32
36
|
message = event.message
|
@@ -38,9 +42,10 @@ class LogStash::Filters::Grok < LogStash::Filters::Base
|
|
38
42
|
pile = @grokpiles[event.type]
|
39
43
|
grok, match = pile.match(message)
|
40
44
|
end # @grokpiles.include?(event.type)
|
41
|
-
|
42
|
-
|
45
|
+
# TODO(2.0): support grok pattern discovery
|
46
|
+
else
|
43
47
|
@logger.info("Unknown type for #{event.source} (type: #{event.type})")
|
48
|
+
@logger.debug(event.to_hash)
|
44
49
|
end
|
45
50
|
|
46
51
|
if match
|
@@ -60,7 +65,9 @@ class LogStash::Filters::Grok < LogStash::Filters::Base
|
|
60
65
|
event.fields[key] = []
|
61
66
|
end
|
62
67
|
|
63
|
-
|
68
|
+
if value && !value.empty?
|
69
|
+
event.fields[key] << value
|
70
|
+
end
|
64
71
|
end
|
65
72
|
else
|
66
73
|
# Tag this event if we can't parse it. We can use this later to
|