Class: LogStash::Inputs::Irc

Inherits:
Base
  • Object
show all
Defined in:
lib/logstash/inputs/irc.rb

Overview

Read events from an IRC Server.

Constant Summary collapse

RPL_NAMREPLY =

def run

"353"
RPL_ENDOFNAMES =
"366"

Instance Method Summary collapse

Instance Method Details

#botObject



65
66
67
# File 'lib/logstash/inputs/irc.rb', line 65

def bot
  @bot
end

#handle_response(msg, output_queue) ⇒ Object



126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# 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) ⇒ Object



60
61
62
63
# File 'lib/logstash/inputs/irc.rb', line 60

def inject_bot(bot)
  @bot = bot
  self
end

#registerObject



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# 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_namesObject



163
164
165
166
167
168
169
170
171
172
# 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) ⇒ Object



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# 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

#stopObject



174
175
176
177
# 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