class LogStash::Inputs::Irc

Read events from an IRC Server.

Constants

RPL_ENDOFNAMES
RPL_NAMREPLY

Public Instance Methods

bot() click to toggle source
# File lib/logstash/inputs/irc.rb, line 65
def bot
  @bot
end
handle_response(msg, output_queue) click to toggle source
# File lib/logstash/inputs/irc.rb, line 126
def handle_response (msg, output_queue)
    # Set some constant variables based on https://www.alien.net.au/irc/irc2numerics.html

    if @get_stats and msg.command.to_s == RPL_NAMREPLY
      # Got a names list event
      # Count the users returned in msg.params[3] split by " "
      users = msg.params[3].split(" ")
      @user_stats[msg.channel.to_s] = (@user_stats[msg.channel.to_s] || 0)  + users.length
    end
    if @get_stats and msg.command.to_s == RPL_ENDOFNAMES
      # Got an end of names event, now we can send the info down the pipe.
      event = LogStash::Event.new()
      decorate(event)
      event.set("channel", msg.channel.to_s)
      event.set("users", @user_stats[msg.channel.to_s])
      event.set("server", "#{@host}:#{@port}")
      output_queue << event
    end
    if msg.command and msg.user
      @logger.debug("IRC Message", :data => msg)
      @codec.decode(msg.message) do |event|
        decorate(event)
        event.set("user", msg.prefix.to_s)
        event.set("command", msg.command.to_s)
        event.set("channel", msg.channel.to_s)
        event.set("nick", msg.user.nick)
        event.set("server", "#{@host}:#{@port}")
        # The user's host attribute is an optional part of the message format;
        # when it is not included, `Cinch::User#host` times out waiting for it
        # to be populated, raising an exception; use `Cinch::User#data` to get
        # host, which includes the user attributes as-parsed.
        event.set("host", msg.user.data[:host])
        output_queue << event
      end
    end
end
inject_bot(bot) click to toggle source
# File lib/logstash/inputs/irc.rb, line 60
def inject_bot(bot)
  @bot = bot
  self
end
register() click to toggle source
# File lib/logstash/inputs/irc.rb, line 69
def register
  require "cinch"
  @user_stats = Hash.new
  @irc_queue = java.util.concurrent.LinkedBlockingQueue.new
  @catch_all = true if  @get_stats
  @logger.info("Connecting to irc server", :host => @host, :port => @port, :nick => @nick, :channels => @channels)

  @bot ||= Cinch::Bot.new
  @bot.loggers.clear
  @bot.configure do |c|
    c.server = @host
    c.port = @port
    c.nick = @nick
    c.user = @user
    c.realname = @real
    c.channels = @channels
    c.password = @password.value rescue nil
    c.ssl.use = @secure
  end
  queue = @irc_queue
  if @catch_all
      @bot.on :catchall  do |m|
        queue << m
      end
  else
    @bot.on :channel  do |m|
      queue << m
    end
  end
end
request_names() click to toggle source
# File lib/logstash/inputs/irc.rb, line 163
def request_names
  # Go though list of channels, and request a NAMES for them
  # Note : Logstash channel list can have passwords ie : "channel password"
  # Need to account for that
  @channels.each do |channel|
      channel = channel.split(' ').first if channel.include?(' ')
      @user_stats[channel] = 0
      @bot.irc.send("NAMES #{channel}")
  end
end
run(output_queue) click to toggle source
# File lib/logstash/inputs/irc.rb, line 101
def run(output_queue)
  @bot_thread = Stud::Task.new(@bot) do |bot|
    bot.start
  end
  if @get_stats
    @request_names_thread = Stud::Task.new do
      while !stop?
        Stud.stoppable_sleep (@stats_interval * 60) do
          stop?
        end
        request_names
      end
    end
  end
  while !stop?
    msg = @irc_queue.poll(1, java.util.concurrent.TimeUnit::SECONDS)
    handle_response(msg, output_queue) unless msg.nil?
  end
ensure
  stop rescue logger.warn("irc input failed to shutdown gracefully: #{$!.message}")
end
stop() click to toggle source
# File lib/logstash/inputs/irc.rb, line 174
def stop
  @request_names_thread.stop! if @request_names_thread && !@request_names_thread.stop?
  @bot_thread.stop! if @bot_thread && !@bot_thread.stop?
end