Class: LogStash::Filters::Accesswatch

Inherits:
Base
  • Object
show all
Includes:
PluginMixins::HttpClient
Defined in:
lib/logstash/filters/accesswatch.rb

Overview

The Access Watch filter adds information about robots visiting your website based on data from our robots database.

Constant Summary collapse

@@address_keys =
["value", "hostname", "country_code", "flags"]
@@robot_keys =
["id", "name", "url"]
@@identity_keys =
["type"]

Instance Method Summary collapse

Instance Method Details

#augment(event, destination, data, keys = nil) ⇒ Object



117
118
119
120
121
122
123
124
# File 'lib/logstash/filters/accesswatch.rb', line 117

def augment(event, destination, data, keys=nil)
  if destination && data
    event.set(destination,
              data.select {|k, v|
                (keys.nil? or keys.include?(k)) && !(v.nil? || v.empty?)
              })
  end
end

#fetch_address(ip) ⇒ Object



97
98
99
100
101
# File 'lib/logstash/filters/accesswatch.rb', line 97

def fetch_address(ip)
  self.with_cache("ip-#{ip}") {
    self.get_json("/1.1/address/#{ip}")
  }
end

#fetch_identity(ip, user_agent) ⇒ Object



109
110
111
112
113
114
115
# File 'lib/logstash/filters/accesswatch.rb', line 109

def fetch_identity(ip, user_agent)
  ip = ip || ""
  user_agent = user_agent || ""
  self.with_cache("identity-#{Digest::MD5.hexdigest(ip)}-#{Digest::MD5.hexdigest(user_agent)}") {
    self.post_json("/1.1/identity", {:address => ip, :user_agent => user_agent})
  }
end

#fetch_user_agent(user_agent) ⇒ Object



103
104
105
106
107
# File 'lib/logstash/filters/accesswatch.rb', line 103

def fetch_user_agent(user_agent)
  self.with_cache("ua-#{Digest::MD5.hexdigest(user_agent)}") {
    self.post_json("/1.1/user-agent", {:value => user_agent})
  }
end

#filter(event) ⇒ Object



127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/logstash/filters/accesswatch.rb', line 127

def filter(event)
  begin
    ip = event.get(@ip_source)
    user_agent = event.get(@user_agent_source)
    if @ip_source and @user_agent_source
      data = self.fetch_identity(ip, user_agent)
      self.augment(event, @address_destination, data["address"], @@address_keys)
      self.augment(event, @robot_destination, data["robot"], @@robot_keys)
      self.augment(event, @reputation_destination, data["reputation"])
      self.augment(event, @identity_destination, data, @@identity_keys)
    elsif @ip_source
      data = self.fetch_address(ip)
      self.augment(event, @address_destination, data, @@address_keys)
    else
      data = self.fetch_user_agent(user_agent)
      self.augment(event, @user_agent_destination, data)
    end
  rescue => e
    @logger.error("Error augmenting the data.", error: e)
  end
  filter_matched(event)
end

#get_json(path) ⇒ Object



69
70
71
72
73
74
75
76
# File 'lib/logstash/filters/accesswatch.rb', line 69

def get_json(path)
  self.submit {
    self.client.get(self.url(path),
                    headers: {"Api-Key"    => @api_key,
                              "Accept"     => "application/json",
                              "User-Agent" => "Access Watch Logstash Plugin/0.2.0"})
  }
end

#post_json(path, data) ⇒ Object



78
79
80
81
82
83
84
85
86
87
# File 'lib/logstash/filters/accesswatch.rb', line 78

def post_json(path, data)
  self.submit {
    self.client.post(self.url(path),
                     headers: {"Api-Key"      => @api_key,
                               "Accept"       => "application/json",
                               "Content-Type" => "application/json",
                               "User-Agent"   => "Access Watch Logstash Plugin/0.2.0"},
                     body: JSON.generate(data))
  }
end

#registerObject



50
51
52
53
54
# File 'lib/logstash/filters/accesswatch.rb', line 50

def register
  if @cache_size > 0
    @cache = LruRedux::ThreadSafeCache.new(@cache_size)
  end
end

#submit(&block) ⇒ Object



56
57
58
59
60
61
62
63
# File 'lib/logstash/filters/accesswatch.rb', line 56

def submit(&block)
  http_response = block.call
  data = JSON.parse(http_response.body)
  if http_response.code != 200
    raise "Access Watch (#{data["code"]}): #{data["message"]}"
  end
  data
end

#url(path) ⇒ Object



65
66
67
# File 'lib/logstash/filters/accesswatch.rb', line 65

def url(path)
  "http://api.access.watch#{path}"
end

#with_cache(id, &block) ⇒ Object



89
90
91
92
93
94
95
# File 'lib/logstash/filters/accesswatch.rb', line 89

def with_cache(id, &block)
  if @cache
    @cache.getset(id) { block.call }
  else
    block.call
  end
end