Class: LogStash::Filters::Accesswatch

Inherits:
Base
  • Object
show all
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



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

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



99
100
101
102
103
# File 'lib/logstash/filters/accesswatch.rb', line 99

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

#fetch_identity(ip, user_agent) ⇒ Object



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

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



105
106
107
108
109
# File 'lib/logstash/filters/accesswatch.rb', line 105

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



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

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



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

def get_json(path)
  self.submit {
    @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



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

def post_json(path, data)
  self.submit {
    @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



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

def register
  @client = Manticore::Client.new request_timeout: @timeout, ssl: {:ca_file => "cert.pem"}
  if @cache_size > 0
    @cache = LruRedux::ThreadSafeCache.new(@cache_size)
  end
end

#submit(&block) ⇒ Object



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

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



67
68
69
# File 'lib/logstash/filters/accesswatch.rb', line 67

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

#with_cache(id, &block) ⇒ Object



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

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