Class: LogStash::Filters::UserAgent

Inherits:
Base
  • Object
show all
Defined in:
lib/logstash/filters/useragent.rb

Overview

Parse user agent strings into structured data based on BrowserScope data

UserAgent filter, adds information about user agent like family, operating system, version, and device

Logstash releases ship with the regexes.yaml database made available from ua-parser with an Apache 2.0 license. For more details on ua-parser, see <github.com/tobie/ua-parser/>.

Instance Method Summary collapse

Constructor Details

#initialize(*params) ⇒ UserAgent

Returns a new instance of UserAgent.



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/logstash/filters/useragent.rb', line 58

def initialize(*params)
  super

  # make @target in the format [field name] if defined, i.e. surrounded by brackets
  target = @target || ecs_select[disabled: '', v1: '[user_agent]']
  target = "[#{@target}]" if !target.empty? && target !~ /^\[[^\[\]]+\]$/

  @name_field = ecs_select[disabled: "[#{@prefix}name]", v1: '[name]']
  @name_field = "#{target}#{@name_field}"

  @device_name_field = ecs_select[disabled: "[#{@prefix}device]", v1: '[device][name]']
  @device_name_field = "#{target}#{@device_name_field}"

  @version_field = ecs_select[disabled: "[#{@prefix}version]", v1: '[version]']
  @version_field = "#{target}#{@version_field}"
  @major_field = ecs_select[disabled: "#{target}[#{@prefix}major]", v1: "[@metadata][filter][user_agent][version][major]"]
  @minor_field = ecs_select[disabled: "#{target}[#{@prefix}minor]", v1: "[@metadata][filter][user_agent][version][minor]"]
  @patch_field = ecs_select[disabled: "#{target}[#{@prefix}patch]", v1: "[@metadata][filter][user_agent][version][patch]"]

  @os_full_name_field = ecs_select[disabled: "[#{@prefix}os_full]", v1: '[os][full]'] # did not exist in legacy prior to ECS-ification
  @os_full_name_field = "#{target}#{@os_full_name_field}"

  @os_name_field = ecs_select[disabled: "[#{@prefix}os_name]", v1: '[os][name]']
  @os_name_field = "#{target}#{@os_name_field}"
  @legacy_os_field = ecs_select[disabled: "#{target}[#{@prefix}os]", v1: nil] # same as [os_name] in legacy mode

  @os_version_field = ecs_select[disabled: "[#{@prefix}os_version]", v1: '[os][version]']
  @os_version_field = "#{target}#{@os_version_field}"
  @os_major_field = ecs_select[disabled: "#{target}[#{@prefix}os_major]", v1: "[@metadata][filter][user_agent][os][version][major]"]
  @os_minor_field = ecs_select[disabled: "#{target}[#{@prefix}os_minor]", v1: "[@metadata][filter][user_agent][os][version][minor]"]
  @os_patch_field = ecs_select[disabled: "#{target}[#{@prefix}os_patch]", v1: "[@metadata][filter][user_agent][os][version][patch]"]

  # NOTE: unfortunately we can not reliably provide `user_agent.original` since the patterns do not
  # reliably give back the matched group and they support the UA string prefixed and/or suffixed
end

Instance Method Details

#filter(event) ⇒ Object



107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/logstash/filters/useragent.rb', line 107

def filter(event)
  useragent = event.get(@source)
  useragent = useragent.first if useragent.is_a?(Array)

  return if useragent.nil? || useragent.empty?

  begin
    ua_data = lookup_useragent(useragent)
  rescue => e
    @logger.error("Unknown error while parsing user agent data",
                  :exception => e.class, :message => e.message, :backtrace => e.backtrace,
                  :field => @source, :event => event.to_hash)
    return
  end

  return unless ua_data

  event.remove(@source) if @target == @source
  set_fields(event, useragent, ua_data)

  filter_matched(event)
end

#registerObject



94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/logstash/filters/useragent.rb', line 94

def register
  if ecs_compatibility != :disabled && @prefix && !@prefix.empty?
    @logger.warn "Field prefix isn't supported in ECS compatibility mode, please remove `prefix => #{@prefix.inspect}`"
  end

  if @regexes.nil?
    @parser = org.logstash.uaparser.CachingParser.new(lru_cache_size)
  else
    @logger.debug("Using user agent regexes", :regexes => @regexes)
    @parser = org.logstash.uaparser.CachingParser.new(@regexes, lru_cache_size)
  end
end