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
@@ -1,15 +1,17 @@
|
|
1
1
|
require "logstash/filters/base"
|
2
|
-
|
2
|
+
require "logstash/namespace"
|
3
3
|
gem "jls-grok", ">=0.2.3071"
|
4
4
|
require "grok" # rubygem 'jls-grok'
|
5
5
|
|
6
6
|
class LogStash::Filters::Grokdiscovery < LogStash::Filters::Base
|
7
|
+
public
|
7
8
|
def initialize(config = {})
|
8
9
|
super
|
9
10
|
|
10
11
|
@discover_fields = {}
|
11
12
|
end # def initialize
|
12
13
|
|
14
|
+
public
|
13
15
|
def register
|
14
16
|
# TODO(sissel): Make patterns files come from the config
|
15
17
|
@config.each do |type, typeconfig|
|
@@ -24,6 +26,7 @@ class LogStash::Filters::Grokdiscovery < LogStash::Filters::Base
|
|
24
26
|
end # @config.each
|
25
27
|
end # def register
|
26
28
|
|
29
|
+
public
|
27
30
|
def filter(event)
|
28
31
|
# parse it with grok
|
29
32
|
message = event.message
|
@@ -4,6 +4,7 @@
|
|
4
4
|
#
|
5
5
|
|
6
6
|
require "logstash/filters/base"
|
7
|
+
require "logstash/namespace"
|
7
8
|
|
8
9
|
class LogStash::Filters::Multiline < LogStash::Filters::Base
|
9
10
|
# The 'date' filter will take a value from your event and use it as the
|
@@ -46,6 +47,7 @@ class LogStash::Filters::Multiline < LogStash::Filters::Base
|
|
46
47
|
# pattern: /\\$/
|
47
48
|
# what: next
|
48
49
|
#
|
50
|
+
public
|
49
51
|
def initialize(config = {})
|
50
52
|
super
|
51
53
|
|
@@ -53,6 +55,7 @@ class LogStash::Filters::Multiline < LogStash::Filters::Base
|
|
53
55
|
@pending = Hash.new
|
54
56
|
end # def initialize
|
55
57
|
|
58
|
+
public
|
56
59
|
def register
|
57
60
|
@config.each do |type, typeconfig|
|
58
61
|
# typeconfig will be a hash containing 'pattern' and 'what'
|
@@ -82,10 +85,10 @@ class LogStash::Filters::Multiline < LogStash::Filters::Base
|
|
82
85
|
@logger.fatal(["Invalid pattern for multiline filter on type '#{type}'",
|
83
86
|
typeconfig, e])
|
84
87
|
end
|
85
|
-
|
86
88
|
end # @config.each
|
87
89
|
end # def register
|
88
90
|
|
91
|
+
public
|
89
92
|
def filter(event)
|
90
93
|
return unless @types.member?(event.type)
|
91
94
|
typeconfig = @types[event.type]
|
@@ -147,6 +150,7 @@ class LogStash::Filters::Multiline < LogStash::Filters::Base
|
|
147
150
|
end # def filter
|
148
151
|
|
149
152
|
# flush any pending messages
|
153
|
+
public
|
150
154
|
def flush(source, type)
|
151
155
|
key = [source, type]
|
152
156
|
if @pending[key]
|
@@ -154,5 +158,5 @@ class LogStash::Filters::Multiline < LogStash::Filters::Base
|
|
154
158
|
@pending.delete(key)
|
155
159
|
end
|
156
160
|
return event
|
157
|
-
end
|
161
|
+
end # def flush
|
158
162
|
end # class LogStash::Filters::Date
|
data/lib/logstash/inputs.rb
CHANGED
@@ -1,9 +1,13 @@
|
|
1
|
-
|
2
1
|
require "logstash/namespace"
|
3
2
|
require "logstash/ruby_fixes"
|
4
3
|
require "uri"
|
5
4
|
|
6
5
|
module LogStash::Inputs
|
6
|
+
# Given a URL, try to load the class that supports it.
|
7
|
+
# That is, if we have an input of "foo://blah/" then
|
8
|
+
# we will try to load logstash/inputs/foo and will
|
9
|
+
# expect a class LogStash::Inputs::Foo
|
10
|
+
public
|
7
11
|
def self.from_url(url, type, &block)
|
8
12
|
# Assume file paths if we start with "/"
|
9
13
|
url = "file://#{url}" if url.start_with?("/")
|
@@ -12,7 +16,7 @@ module LogStash::Inputs
|
|
12
16
|
# TODO(sissel): Add error handling
|
13
17
|
# TODO(sissel): Allow plugin paths
|
14
18
|
klass = uri.scheme.capitalize
|
15
|
-
file = uri.scheme
|
19
|
+
file = uri.scheme.downcase
|
16
20
|
require "logstash/inputs/#{file}"
|
17
21
|
LogStash::Inputs.const_get(klass).new(uri, type, &block)
|
18
22
|
end # def from_url
|
data/lib/logstash/inputs/amqp.rb
CHANGED
@@ -1,11 +1,13 @@
|
|
1
|
-
require "logstash/inputs/base"
|
2
1
|
require "amqp" # rubygem 'amqp'
|
2
|
+
require "logstash/inputs/base"
|
3
|
+
require "logstash/namespace"
|
3
4
|
require "mq" # rubygem 'amqp'
|
4
5
|
require "uuidtools" # rubygem 'uuidtools'
|
5
6
|
|
6
7
|
class LogStash::Inputs::Amqp < LogStash::Inputs::Base
|
7
8
|
MQTYPES = [ "fanout", "queue", "topic" ]
|
8
9
|
|
10
|
+
public
|
9
11
|
def initialize(url, type, config={}, &block)
|
10
12
|
super
|
11
13
|
|
@@ -20,8 +22,9 @@ class LogStash::Inputs::Amqp < LogStash::Inputs::Base
|
|
20
22
|
if !MQTYPES.include?(@mqtype)
|
21
23
|
raise "Invalid type '#{@mqtype}' must be one of #{MQTYPES.JOIN(", ")}"
|
22
24
|
end
|
23
|
-
end
|
25
|
+
end # def initialize
|
24
26
|
|
27
|
+
public
|
25
28
|
def register
|
26
29
|
@logger.info("Registering input #{@url}")
|
27
30
|
@amqp = AMQP.connect(:host => @url.host)
|
data/lib/logstash/inputs/base.rb
CHANGED
@@ -5,6 +5,8 @@ require "uri"
|
|
5
5
|
|
6
6
|
class LogStash::Inputs::Base
|
7
7
|
attr_accessor :logger
|
8
|
+
|
9
|
+
public
|
8
10
|
def initialize(url, type, config={}, &block)
|
9
11
|
@logger = LogStash::Logger.new(STDERR)
|
10
12
|
@url = url
|
@@ -13,21 +15,32 @@ class LogStash::Inputs::Base
|
|
13
15
|
@callback = block
|
14
16
|
@type = type
|
15
17
|
@tags = []
|
16
|
-
end
|
17
18
|
|
19
|
+
@urlopts = {}
|
20
|
+
if @url.query
|
21
|
+
@urlopts = CGI.parse(@url.query)
|
22
|
+
@urlopts.each do |k, v|
|
23
|
+
@urlopts[k] = v.last if v.is_a?(Array)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end # def initialize
|
27
|
+
|
28
|
+
public
|
18
29
|
def register
|
19
30
|
raise "#{self.class}#register must be overidden"
|
20
|
-
end
|
31
|
+
end # def register
|
21
32
|
|
33
|
+
public
|
22
34
|
def tag(newtag)
|
23
35
|
@tags << newtag
|
24
|
-
end
|
36
|
+
end # def tag
|
25
37
|
|
38
|
+
public
|
26
39
|
def receive(event)
|
27
40
|
@logger.debug(["Got event", { :url => @url, :event => event }])
|
28
41
|
# Only override the type if it doesn't have one
|
29
42
|
event.type = @type if !event.type
|
30
43
|
event.tags |= @tags # set union
|
31
44
|
@callback.call(event)
|
32
|
-
end
|
45
|
+
end # def receive
|
33
46
|
end # class LogStash::Inputs::Base
|
@@ -1,15 +1,18 @@
|
|
1
|
-
require "logstash/inputs/base"
|
2
1
|
require "em-jack"
|
2
|
+
require "logstash/inputs/base"
|
3
|
+
require "logstash/namespace"
|
3
4
|
|
4
5
|
class LogStash::Inputs::Beanstalk < LogStash::Inputs::Base
|
6
|
+
public
|
5
7
|
def initialize(url, type, config={}, &block)
|
6
8
|
super
|
7
9
|
|
8
10
|
if @url.path == "" or @url.path == "/"
|
9
11
|
raise "must specify a tube for beanstalk output"
|
10
12
|
end
|
11
|
-
end
|
13
|
+
end # def initialize
|
12
14
|
|
15
|
+
public
|
13
16
|
def register
|
14
17
|
tube = @url.path[1..-1] # Skip leading '/'
|
15
18
|
port = @url.port || 11300
|
data/lib/logstash/inputs/file.rb
CHANGED
@@ -1,22 +1,26 @@
|
|
1
|
-
require "logstash/inputs/base"
|
2
1
|
require "eventmachine-tail"
|
2
|
+
require "logstash/inputs/base"
|
3
|
+
require "logstash/namespace"
|
3
4
|
require "socket" # for Socket.gethostname
|
4
5
|
|
5
6
|
class LogStash::Inputs::File < LogStash::Inputs::Base
|
7
|
+
public
|
6
8
|
def initialize(url, type, config={}, &block)
|
7
9
|
super
|
8
10
|
|
9
11
|
# Hack the hostname into the url.
|
10
12
|
# This works since file:// urls don't generally have a host in it.
|
11
13
|
@url.host = Socket.gethostname
|
12
|
-
end
|
14
|
+
end # def initialize
|
13
15
|
|
16
|
+
public
|
14
17
|
def register
|
15
18
|
@logger.info("Registering #{@url}")
|
16
19
|
EventMachine::FileGlobWatchTail.new(@url.path, Reader, interval=60,
|
17
20
|
exclude=[], receiver=self)
|
18
21
|
end # def register
|
19
22
|
|
23
|
+
public
|
20
24
|
def receive(filetail, event)
|
21
25
|
url = @url.clone
|
22
26
|
url.path = filetail.path
|
@@ -31,6 +35,7 @@ class LogStash::Inputs::File < LogStash::Inputs::Base
|
|
31
35
|
@callback.call(event)
|
32
36
|
end # def receive
|
33
37
|
|
38
|
+
private
|
34
39
|
class Reader < EventMachine::FileTail
|
35
40
|
def initialize(path, receiver)
|
36
41
|
super(path)
|
@@ -1,11 +1,12 @@
|
|
1
|
-
|
2
|
-
require "logstash/inputs/base"
|
3
1
|
require "eventmachine-tail"
|
2
|
+
require "logstash/inputs/base"
|
3
|
+
require "logstash/namespace"
|
4
4
|
require "socket" # for Socket.gethostname
|
5
5
|
|
6
6
|
class LogStash::Inputs::Internal < LogStash::Inputs::Base
|
7
7
|
attr_reader :channel
|
8
8
|
|
9
|
+
public
|
9
10
|
def initialize(url, type, config={}, &block)
|
10
11
|
super
|
11
12
|
|
@@ -14,6 +15,7 @@ class LogStash::Inputs::Internal < LogStash::Inputs::Base
|
|
14
15
|
@channel = EventMachine::Channel.new
|
15
16
|
end
|
16
17
|
|
18
|
+
public
|
17
19
|
def register
|
18
20
|
@logger.info("Registering input #{@url}")
|
19
21
|
@channel.subscribe do |event|
|
@@ -21,6 +23,7 @@ class LogStash::Inputs::Internal < LogStash::Inputs::Base
|
|
21
23
|
end
|
22
24
|
end # def register
|
23
25
|
|
26
|
+
public
|
24
27
|
def receive(event)
|
25
28
|
if !event.is_a?(LogStash::Event)
|
26
29
|
event = LogStash::Event.new({
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require "eventmachine-tail"
|
2
|
+
require "logstash/inputs/base"
|
3
|
+
require "logstash/namespace"
|
4
|
+
require "socket" # for Socket.gethostname
|
5
|
+
|
6
|
+
class LogStash::Inputs::Stdin < LogStash::Inputs::Base
|
7
|
+
public
|
8
|
+
def register
|
9
|
+
EventMachine::attach($stdin, InputHandler, self)
|
10
|
+
@url.host = Socket.gethostname
|
11
|
+
end # def register
|
12
|
+
|
13
|
+
public
|
14
|
+
def receive(event)
|
15
|
+
event = LogStash::Event.new({
|
16
|
+
"@message" => event,
|
17
|
+
"@type" => @type,
|
18
|
+
"@tags" => @tags.clone,
|
19
|
+
})
|
20
|
+
event.source = @url
|
21
|
+
@logger.debug(["Got event", event])
|
22
|
+
@callback.call(event)
|
23
|
+
end # def receive
|
24
|
+
|
25
|
+
class InputHandler < EventMachine::Connection
|
26
|
+
def initialize(obj)
|
27
|
+
@receiver = obj
|
28
|
+
end # def initialize
|
29
|
+
|
30
|
+
def receive_data(data)
|
31
|
+
@buffer ||= BufferedTokenizer.new
|
32
|
+
@buffer.extract(data).each do |line|
|
33
|
+
@receiver.receive(line)
|
34
|
+
end
|
35
|
+
end # def receive_data
|
36
|
+
end # class InputHandler
|
37
|
+
|
38
|
+
end # class LogStash::Inputs::Stdin
|
@@ -1,8 +1,21 @@
|
|
1
1
|
require "logstash/inputs/base"
|
2
|
+
require "logstash/namespace"
|
2
3
|
require "logstash/stomp/handler"
|
3
4
|
|
4
5
|
class LogStash::Inputs::Stomp < LogStash::Inputs::Base
|
6
|
+
public
|
7
|
+
def initialize(url, config={}, &block)
|
8
|
+
super
|
9
|
+
@logger.debug(["Connecting", { :url => @url }])
|
10
|
+
end # def initialize
|
11
|
+
|
12
|
+
public
|
13
|
+
def register
|
14
|
+
@logger.info(["Registering input", { :url => @url}])
|
15
|
+
EventMachine::connect(@url.host, @url.port, InputHandler, self, @logger, @url)
|
16
|
+
end # def register
|
5
17
|
|
18
|
+
private
|
6
19
|
class InputHandler < LogStash::Stomp::Handler
|
7
20
|
def receive_msg(message)
|
8
21
|
super
|
@@ -13,15 +26,4 @@ class LogStash::Inputs::Stomp < LogStash::Inputs::Base
|
|
13
26
|
end
|
14
27
|
end # def receive_msg
|
15
28
|
end # class StompHandler
|
16
|
-
|
17
|
-
def initialize(url, config={}, &block)
|
18
|
-
super
|
19
|
-
|
20
|
-
@logger.debug(["Connecting", { :url => @url }])
|
21
|
-
end # def initialize
|
22
|
-
|
23
|
-
def register
|
24
|
-
@logger.info(["Registering input", { :url => @url}])
|
25
|
-
EventMachine::connect(@url.host, @url.port, InputHandler, self, @logger, @url)
|
26
|
-
end # def register
|
27
|
-
end # class LogStash::Inputs::Amqp
|
29
|
+
end # class LogStash::Inputs::Stomp
|
@@ -1,11 +1,12 @@
|
|
1
|
-
require "logstash/inputs/base"
|
2
|
-
require "eventmachine-tail"
|
3
|
-
require "socket" # for Socket.gethostname
|
4
1
|
require "date"
|
2
|
+
require "eventmachine-tail"
|
3
|
+
require "logstash/inputs/base"
|
4
|
+
require "logstash/namespace"
|
5
5
|
require "logstash/time" # should really use the filters/date.rb bits
|
6
|
-
|
6
|
+
require "socket" # for Socket.gethostname
|
7
7
|
|
8
8
|
class LogStash::Inputs::Syslog < LogStash::Inputs::Base
|
9
|
+
public
|
9
10
|
def register
|
10
11
|
if !@url.host or !@url.port
|
11
12
|
@logger.fatal("No host or port given in #{self.class}: #{@url}")
|
@@ -26,6 +27,7 @@ class LogStash::Inputs::Syslog < LogStash::Inputs::Base
|
|
26
27
|
#<priority timestamp Mmm dd hh:mm:ss host msg
|
27
28
|
end # def register
|
28
29
|
|
30
|
+
public
|
29
31
|
def receive(host, port, message)
|
30
32
|
url = @url.clone
|
31
33
|
url.host = host
|
@@ -48,6 +50,7 @@ class LogStash::Inputs::Syslog < LogStash::Inputs::Base
|
|
48
50
|
# If the message cannot be recognized (see @@syslog_re), we'll
|
49
51
|
# treat it like the whole event.message is correct and try to fill
|
50
52
|
# the missing pieces (host, priority, etc)
|
53
|
+
public
|
51
54
|
def syslog_relay(event, url)
|
52
55
|
match = @@syslog_re.match(event.message)
|
53
56
|
if match
|
@@ -90,6 +93,7 @@ class LogStash::Inputs::Syslog < LogStash::Inputs::Base
|
|
90
93
|
end
|
91
94
|
end # def syslog_relay
|
92
95
|
|
96
|
+
private
|
93
97
|
class TCPInput < EventMachine::Connection
|
94
98
|
def initialize(receiver, logger)
|
95
99
|
@logger = logger
|
@@ -107,6 +111,7 @@ class LogStash::Inputs::Syslog < LogStash::Inputs::Base
|
|
107
111
|
end # def receive_data
|
108
112
|
end # class TCPInput
|
109
113
|
|
114
|
+
private
|
110
115
|
class UDPInput < EventMachine::Connection
|
111
116
|
def initialize(receiver, logger)
|
112
117
|
@logger = logger
|
@@ -120,4 +125,4 @@ class LogStash::Inputs::Syslog < LogStash::Inputs::Base
|
|
120
125
|
@receiver.receive(host, port, data.chomp)
|
121
126
|
end # def receive_data
|
122
127
|
end # class UDPInput
|
123
|
-
end # class LogStash::Inputs::
|
128
|
+
end # class LogStash::Inputs::Syslog
|
data/lib/logstash/inputs/tcp.rb
CHANGED
@@ -1,12 +1,15 @@
|
|
1
|
-
require "logstash/inputs/base"
|
2
1
|
require "eventmachine-tail"
|
2
|
+
require "logstash/inputs/base"
|
3
|
+
require "logstash/namespace"
|
3
4
|
require "socket" # for Socket.gethostname
|
4
5
|
|
5
6
|
class LogStash::Inputs::Tcp < LogStash::Inputs::Base
|
7
|
+
public
|
6
8
|
def initialize(url, type, config={}, &block)
|
7
9
|
super
|
8
|
-
end
|
10
|
+
end # def initialize
|
9
11
|
|
12
|
+
public
|
10
13
|
def register
|
11
14
|
if !@url.host or !@url.port
|
12
15
|
@logger.fatal("No host or port given in #{self.class}: #{@url}")
|
@@ -16,8 +19,9 @@ class LogStash::Inputs::Tcp < LogStash::Inputs::Base
|
|
16
19
|
|
17
20
|
@logger.info("Starting tcp listener for #{@url}")
|
18
21
|
EventMachine::start_server(@url.host, @url.port, TCPInput, @url, self, @logger)
|
19
|
-
end
|
22
|
+
end # def register
|
20
23
|
|
24
|
+
public
|
21
25
|
def receive(host, port, event)
|
22
26
|
url = @url.clone
|
23
27
|
url.host = host
|
@@ -33,6 +37,7 @@ class LogStash::Inputs::Tcp < LogStash::Inputs::Base
|
|
33
37
|
@callback.call(event)
|
34
38
|
end # def receive
|
35
39
|
|
40
|
+
private
|
36
41
|
class TCPInput < EventMachine::Connection
|
37
42
|
def initialize(url, receiver, logger)
|
38
43
|
@logger = logger
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require "cgi"
|
2
|
+
require "em-http-request"
|
3
|
+
require "logstash/inputs/base"
|
4
|
+
require "logstash/namespace"
|
5
|
+
|
6
|
+
# TODO(sissel): This could use some refactoring.
|
7
|
+
class LogStash::Inputs::Twitter < LogStash::Inputs::Base
|
8
|
+
public
|
9
|
+
def register
|
10
|
+
api_url = "https://stream.twitter.com/1/statuses/filter.json"
|
11
|
+
@http = EventMachine::HttpRequest.new(api_url)
|
12
|
+
@logger.info(["Registering input", { :url => @url, :api_url => api_url, :params => @urlopts }])
|
13
|
+
source = "twitter://...#{@url.path}?#{@url.query}"
|
14
|
+
|
15
|
+
if @url.user.nil? or @user.password.nil?
|
16
|
+
message = "User and password missing for twitter input #{@url.to_s}")
|
17
|
+
@logger.error(message)
|
18
|
+
raise message
|
19
|
+
end
|
20
|
+
|
21
|
+
req = nil
|
22
|
+
connect = proc do
|
23
|
+
@logger.info(["Connecting", { :url => @url, :api_url => api_url, :params => @urlopts}])
|
24
|
+
req = @http.post :body => @urlopts,
|
25
|
+
:head => { "Authorization" => [ @url.user, @url.password ] }
|
26
|
+
buffer = BufferedTokenizer.new
|
27
|
+
|
28
|
+
req.stream do |chunk|
|
29
|
+
buffer.extract(chunk).each do |line|
|
30
|
+
begin
|
31
|
+
tweet = JSON.parse(line)
|
32
|
+
rescue JSON::ParserError => e
|
33
|
+
@logger.warn("Invalid JSON, aborting connection: #{line}")
|
34
|
+
req.errback
|
35
|
+
next
|
36
|
+
end
|
37
|
+
next if !tweet
|
38
|
+
|
39
|
+
event = LogStash::Event.new({
|
40
|
+
"@message" => tweet["text"],
|
41
|
+
"@type" => @type,
|
42
|
+
"@tags" => @tags.clone,
|
43
|
+
})
|
44
|
+
|
45
|
+
event.fields.merge!(
|
46
|
+
"user" => (tweet["user"]["screen_name"] rescue nil),
|
47
|
+
"client" => (tweet["user"]["source"] rescue nil),
|
48
|
+
"retweeted" => (tweet["retweeted"] rescue nil)
|
49
|
+
)
|
50
|
+
|
51
|
+
event.fields["in-reply-to"] = tweet["in_reply_to_status_id"] if tweet["in_reply_to_status_id"]
|
52
|
+
|
53
|
+
urls = tweet["entities"]["urls"] rescue []
|
54
|
+
if urls.size > 0
|
55
|
+
event.fields["urls"] = urls.collect { |u| u["url"] }
|
56
|
+
end
|
57
|
+
|
58
|
+
event.source = source
|
59
|
+
@logger.debug(["Got event", event])
|
60
|
+
@callback.call(event)
|
61
|
+
end # buffer.extract
|
62
|
+
end # req.stream
|
63
|
+
|
64
|
+
req.errback do
|
65
|
+
@logger.warn(["Error occurred, not sure what, seriously. Reconnecting!", { :url => @url }])
|
66
|
+
|
67
|
+
req.close_connection() rescue nil
|
68
|
+
|
69
|
+
EventMachine::Timer.new(60) do
|
70
|
+
connect.call
|
71
|
+
end
|
72
|
+
end # req.errback
|
73
|
+
|
74
|
+
req.callback do
|
75
|
+
@logger.warn(["Request completed. Unexpected!", { :url => @url }])
|
76
|
+
end
|
77
|
+
end # connect = proc do
|
78
|
+
|
79
|
+
connect.call
|
80
|
+
end # def register
|
81
|
+
end # class LogStash::Inputs::Twitter
|