update tcp input

This commit is contained in:
Pete Fritchman 2011-02-21 10:40:52 -08:00
parent 7706953586
commit 6d75615697
2 changed files with 51 additions and 42 deletions

View file

@ -3,6 +3,11 @@ input {
path => [ "/var/log/messages", "/var/log/*.log" ] path => [ "/var/log/messages", "/var/log/*.log" ]
type => "linux-syslog" type => "linux-syslog"
} }
tcp {
port => 1234
type => "linux-syslog"
}
} }
filter { filter {

View file

@ -1,60 +1,64 @@
require "eventmachine-tail"
require "logstash/inputs/base" require "logstash/inputs/base"
require "logstash/namespace" require "logstash/namespace"
require "socket" # for Socket.gethostname require "socket"
require "timeout"
class LogStash::Inputs::Tcp < LogStash::Inputs::Base class LogStash::Inputs::Tcp < LogStash::Inputs::Base
config_name "tcp" config_name "tcp"
config :host => :string
config :port => :number
config :data_timeout => :number
public public
def initialize(params) def initialize(params)
super super
raise "issue/17: needs refactor to support configfile"
end # def initialize @host ||= "0.0.0.0"
@data_timeout ||= 5
end
public public
def register def register
if !@url.host or !@url.port @logger.info("Starting tcp listener on #{@host}:#{@port}")
@logger.fatal("No host or port given in #{self.class}: #{@url}") @server = TCPServer.new(@host, @port)
# TODO(sissel): Make this an actual exception class
raise "configuration error"
end
@logger.info("Starting tcp listener for #{@url}")
EventMachine::start_server(@url.host, @url.port, TCPInput, @url, self, @logger)
end # def register end # def register
public public
def receive(host, port, event) def run(output_queue)
url = @url.clone loop do
url.host = host Thread.start(@server.accept) do |s|
url.port = port peer = "#{s.peeraddr[3]}:#{s.peeraddr[1]}"
@logger.debug(["original url", { :originalurl => @url, :newurl => url }]) @logger.debug("Accepted connection from #{peer} on #{@host}:#{@port}")
event = LogStash::Event.new({ begin
"@message" => event, loop do
"@type" => @type, buf = nil
"@tags" => @tags.clone, # NOTE(petef): the timeout only hits after the line is read
}) # or socket dies
event.source = url Timeout::timeout(@data_timeout) do
@logger.debug(["Got event", event]) buf = s.readline
@callback.call(event) end
e = LogStash::Event.new({
"@message" => buf,
"@type" => @type,
"@tags" => [@type],
})
e.source = "tcp://#{@host}:#{@port}/client/#{peer}"
output_queue << e
end # loop do
rescue
@logger.debug("Closing connection with #{peer}")
rescue Timeout::Error
@logger.debug("Closing connection with #{peer} after read timeout")
end # begin
begin
s.close
rescue IOError
pass
end # begin
end # Thread.start
end # loop (outer)
end # def receive end # def receive
private
class TCPInput < EventMachine::Connection
def initialize(url, receiver, logger)
@logger = logger
@receiver = receiver
@url = url;
@buffer = BufferedTokenizer.new # From eventmachine
end # def initialize
def receive_data(data)
@buffer.extract(data).each do |line|
port, host = Socket.unpack_sockaddr_in(self.get_peername)
@receiver.receive(host, port, line)
end
end # def receive_data
end # class TCPInput
end # class LogStash::Inputs::Tcp end # class LogStash::Inputs::Tcp