Skip to content

Commit 981e46c

Browse files
committed
Added device model and brand to the java output
1 parent e443ac5 commit 981e46c

File tree

5 files changed

+107
-19
lines changed

5 files changed

+107
-19
lines changed

lib/logstash/filters/useragent.rb

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,12 @@ def initialize(*params)
6767

6868
@device_name_field = ecs_select[disabled: "[#{@prefix}device]", v1: '[device][name]']
6969
@device_name_field = "#{target}#{@device_name_field}"
70+
@device_family_field = ecs_select[disabled: "[#{@prefix}device]", v1: '[device][family]']
71+
@device_family_field = "#{target}#{@device_family_field}"
72+
@device_brand_field = ecs_select[disabled: "[#{@prefix}device]", v1: '[device][brand]']
73+
@device_brand_field = "#{target}#{@device_brand_field}"
74+
@device_model_field = ecs_select[disabled: "[#{@prefix}device]", v1: '[device][model]']
75+
@device_model_field = "#{target}#{@device_model_field}"
7076

7177
@version_field = ecs_select[disabled: "[#{@prefix}version]", v1: '[version]']
7278
@version_field = "#{target}#{@version_field}"
@@ -138,8 +144,14 @@ def set_fields(event, ua_source, ua_data)
138144

139145
ua = ua_data.userAgent
140146
event.set(@name_field, duped_string(ua.family))
141-
event.set(@device_name_field, duped_string(ua_data.device)) if ua_data.device
142147

148+
dev = ua_data.device
149+
if dev
150+
event.set(@device_name_field, duped_string(ua_data.device)) if dev.family
151+
event.set(@device_family_field, duped_string(ua_data.device)) if dev.family
152+
event.set(@device_brand_field, duped_string(ua_data.device)) if dev.brand
153+
event.set(@device_model_field, duped_string(ua_data.device)) if dev.model
154+
end
143155
event.set(@major_field, duped_string(ua.major)) if ua.major
144156
event.set(@minor_field, duped_string(ua.minor)) if ua.minor
145157
event.set(@patch_field, duped_string(ua.patch)) if ua.patch

src/main/java/org/logstash/uaparser/Client.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ public final class Client {
2828

2929
public final OS os;
3030

31-
public final String device;
31+
public final Device device;
3232

33-
public Client(final UserAgent userAgent, final OS os, final String device) {
33+
public Client(final UserAgent userAgent, final OS os, final Device device) {
3434
this.userAgent = userAgent;
3535
this.os = os;
3636
this.device = device;

src/main/java/org/logstash/uaparser/Device.java

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
package org.logstash.uaparser;
2020

2121
import java.util.Map;
22+
import java.util.Objects;
2223

2324
/**
2425
* Device parsed data class
@@ -27,7 +28,44 @@
2728
*/
2829
final class Device {
2930

30-
public static String fromMap(Map<String, String> m) {
31-
return m.get("family");
31+
public final String family;
32+
public final String brand;
33+
public final String model;
34+
35+
Device(String family, String brand, String model) {
36+
this.family = family;
37+
this.brand = brand;
38+
this.model = model;
39+
}
40+
41+
public static Device fromMap(Map<String, String> m) {
42+
return new Device(m.get("family"), m.get("brand"), m.get("model"));
43+
}
44+
45+
@Override
46+
public boolean equals(Object other) {
47+
if (other == this) return true;
48+
if (!(other instanceof Device)) return false;
49+
Device o = (Device) other;
50+
return ((this.family != null && this.family.equals(o.family)) || Objects.equals(this.family, o.family)) &&
51+
((this.brand != null && this.brand.equals(o.brand)) || Objects.equals(this.brand, o.brand)) &&
52+
((this.model != null && this.model.equals(o.model)) || Objects.equals(this.model, o.model)) ;
53+
}
54+
55+
@Override
56+
public int hashCode() {
57+
int h = family == null ? 0 : family.hashCode();
58+
h += brand == null ? 0 : brand.hashCode();
59+
h += model == null ? 0 : model.hashCode();
60+
return h;
61+
}
62+
63+
@Override
64+
public String toString() {
65+
return String.format("{\"family\": %s, \"brand\": %s, \"model\": %s}",
66+
family == null ? "" : family,
67+
brand == null ? "" : brand,
68+
model == null ? "" : model
69+
);
3270
}
3371
}

src/main/java/org/logstash/uaparser/DeviceParser.java

Lines changed: 51 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -48,17 +48,17 @@ private DeviceParser(List<DeviceParser.DevicePattern> patterns) {
4848
this.patterns = patterns;
4949
}
5050

51-
public String parse(String agentString) {
51+
public Device parse(String agentString) {
5252
if (agentString == null) {
5353
return null;
5454
}
55-
String device = null;
55+
Device device = null;
5656
for (final DeviceParser.DevicePattern p : this.patterns) {
5757
if ((device = p.match(agentString)) != null) {
5858
break;
5959
}
6060
}
61-
if (device == null) device = "Other";
61+
if (device == null) device = new Device("Other", null, null);
6262
return device;
6363
}
6464

@@ -69,7 +69,7 @@ private static DeviceParser.DevicePattern patternFromMap(Map<String, String> con
6969
}
7070
Pattern pattern = "i".equals(configMap.get("regex_flag")) // no other flags used (by now)
7171
? Pattern.compile(regex, Pattern.CASE_INSENSITIVE) : Pattern.compile(regex);
72-
return new DeviceParser.DevicePattern(pattern, configMap.get("device_replacement"));
72+
return new DeviceParser.DevicePattern(pattern, configMap.get("device_replacement"), configMap.get("brand_replacement"), configMap.get("model_replacement"));
7373
}
7474

7575
private static final class DevicePattern {
@@ -79,37 +79,75 @@ private static final class DevicePattern {
7979
private final Matcher matcher;
8080

8181
private final String deviceReplacement;
82+
private final String brandReplacement;
83+
private final String modelReplacement;
8284

83-
DevicePattern(Pattern pattern, String deviceReplacement) {
85+
DevicePattern(Pattern pattern, String deviceReplacement, String brandReplacement, String modelReplacement) {
8486
this.matcher = pattern.matcher("");
8587
this.deviceReplacement = deviceReplacement;
88+
this.brandReplacement = brandReplacement;
89+
this.modelReplacement = modelReplacement;
8690
}
8791

88-
public synchronized String match(final CharSequence agentString) {
92+
public synchronized Device match(final CharSequence agentString) {
8993
this.matcher.reset(agentString);
9094
if (!this.matcher.find()) {
9195
return null;
9296
}
93-
String device = null;
97+
String family = null;
98+
String brand = null;
99+
String model = null;
94100
if (this.deviceReplacement != null) {
95101
if (this.deviceReplacement.contains("$")) {
96-
device = this.deviceReplacement;
102+
family = this.deviceReplacement;
97103
for (String substitution : DevicePattern
98104
.getSubstitutions(this.deviceReplacement)) {
99105
int i = Integer.parseInt(substitution.substring(1));
100106
final String replacement = this.matcher.groupCount() >= i &&
101107
this.matcher.group(i) != null
102108
? Matcher.quoteReplacement(this.matcher.group(i)) : "";
103-
device = device.replaceFirst('\\' + substitution, replacement);
109+
family = family.replaceFirst('\\' + substitution, replacement);
104110
}
105-
device = device.trim();
111+
family = family.trim();
106112
} else {
107-
device = this.deviceReplacement;
113+
family = this.deviceReplacement;
108114
}
109115
} else if (this.matcher.groupCount() >= 1) {
110-
device = this.matcher.group(1);
116+
family = this.matcher.group(1);
111117
}
112-
return device;
118+
if (this.brandReplacement != null) {
119+
if (this.brandReplacement.contains("$")) {
120+
brand = this.brandReplacement;
121+
for (String substitution : DevicePattern
122+
.getSubstitutions(this.brandReplacement)) {
123+
int i = Integer.parseInt(substitution.substring(1));
124+
final String replacement = this.matcher.groupCount() >= i &&
125+
this.matcher.group(i) != null
126+
? Matcher.quoteReplacement(this.matcher.group(i)) : "";
127+
brand = brand.replaceFirst('\\' + substitution, replacement);
128+
}
129+
brand = brand.trim();
130+
} else {
131+
brand = this.brandReplacement;
132+
}
133+
}
134+
if (this.modelReplacement != null) {
135+
if (this.modelReplacement.contains("$")) {
136+
model = this.modelReplacement;
137+
for (String substitution : DevicePattern
138+
.getSubstitutions(this.modelReplacement)) {
139+
int i = Integer.parseInt(substitution.substring(1));
140+
final String replacement = this.matcher.groupCount() >= i &&
141+
this.matcher.group(i) != null
142+
? Matcher.quoteReplacement(this.matcher.group(i)) : "";
143+
model = model.replaceFirst('\\' + substitution, replacement);
144+
}
145+
model = model.trim();
146+
} else {
147+
model = this.modelReplacement;
148+
}
149+
}
150+
return new Device(family, brand, model);
113151
}
114152

115153
private static Iterable<String> getSubstitutions(String deviceReplacement) {

src/main/java/org/logstash/uaparser/Parser.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ public UserAgent parseUserAgent(String agentString) {
5353
return this.uaParser.parse(agentString);
5454
}
5555

56-
public String parseDevice(String agentString) {
56+
public Device parseDevice(String agentString) {
5757
return this.deviceParser.parse(agentString);
5858
}
5959

0 commit comments

Comments
 (0)