logstash-filter-mutate 3.5.8 → 3.5.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +3 -0
- data/lib/logstash/filters/mutate.rb +65 -4
- data/logstash-filter-mutate.gemspec +1 -1
- data/spec/filters/mutate_spec.rb +448 -1
- metadata +13 -16
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9fd4fb3b414af0266ba7a62e6ef72b00ad1b109200d8da6b54ee7910a1ba561b
|
|
4
|
+
data.tar.gz: 6368b980d3d5c1b32f139bfc007341cafff738a2db055df8c3534436c836b729
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6ba63632430477006fc77d5d27e3ee14c72f4e1bc5bd9557ba886c31b95b34636fd1ed7869dfc77c3a95d02355b04f0afa1e4a4c6053b715d8769c7c5fc1895b
|
|
7
|
+
data.tar.gz: b971f7880a0a98ee89545b5775fcde5c67adb48b624c5b6885b6a70476352950c246d1577d9e133b82b1979b89f7f1500b156a27ed5f6ca3a4fa016e327767e0
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
## 3.5.9
|
|
2
|
+
- Fix `convert` to covert hexadecimal float notation and scientific notation string to float and integer [#175](https://github.com/logstash-plugins/logstash-filter-mutate/pull/175)
|
|
3
|
+
|
|
1
4
|
## 3.5.8
|
|
2
5
|
- Fix "Can't modify frozen string" error when converting boolean to `string` [#171](https://github.com/logstash-plugins/logstash-filter-mutate/pull/171)
|
|
3
6
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
2
|
require "logstash/filters/base"
|
|
3
3
|
require "logstash/namespace"
|
|
4
|
+
require "bigdecimal"
|
|
4
5
|
|
|
5
6
|
# The mutate filter allows you to perform general mutations on fields. You
|
|
6
7
|
# can rename, replace, and modify fields in your events.
|
|
@@ -227,6 +228,10 @@ class LogStash::Filters::Mutate < LogStash::Filters::Base
|
|
|
227
228
|
)
|
|
228
229
|
end
|
|
229
230
|
end
|
|
231
|
+
# fallback to old type conversion behavior prior to Logstash 8.14.0
|
|
232
|
+
@lenient_conversion = self.class.is_lenient_version?
|
|
233
|
+
# signed hex parsing support in jruby 10
|
|
234
|
+
@support_signed_hex = self.class.can_parse_signed_hex?
|
|
230
235
|
|
|
231
236
|
@gsub_parsed = []
|
|
232
237
|
@gsub.nil? or @gsub.each_slice(3) do |field, needle, replacement|
|
|
@@ -342,17 +347,44 @@ class LogStash::Filters::Mutate < LogStash::Filters::Base
|
|
|
342
347
|
end
|
|
343
348
|
|
|
344
349
|
def convert_integer(value)
|
|
350
|
+
value = value.strip.delete(',').downcase if value.is_a?(String)
|
|
351
|
+
|
|
345
352
|
return 1 if value == true
|
|
346
353
|
return 0 if value == false
|
|
347
|
-
return value
|
|
348
|
-
value.
|
|
354
|
+
return value if value.is_a?(Integer)
|
|
355
|
+
return value.to_i if @lenient_conversion
|
|
356
|
+
|
|
357
|
+
if value.is_a?(String)
|
|
358
|
+
signed_float = parse_signed_hex_str(value)
|
|
359
|
+
# hex number
|
|
360
|
+
if signed_float
|
|
361
|
+
return Integer(value) if value.count(".").zero?
|
|
362
|
+
return Integer(signed_float)
|
|
363
|
+
end
|
|
364
|
+
|
|
365
|
+
# scientific notation. BigDecimal() can't parse hex string
|
|
366
|
+
return BigDecimal(value).to_i if value.include?("e")
|
|
367
|
+
# maybe a float string
|
|
368
|
+
return value.to_i
|
|
369
|
+
end
|
|
370
|
+
|
|
371
|
+
Integer(value)
|
|
349
372
|
end
|
|
350
373
|
|
|
351
374
|
def convert_float(value)
|
|
375
|
+
value = value.strip.delete(',').downcase if value.is_a?(String)
|
|
376
|
+
|
|
352
377
|
return 1.0 if value == true
|
|
353
378
|
return 0.0 if value == false
|
|
354
|
-
|
|
355
|
-
value.to_f
|
|
379
|
+
return value if value.is_a?(Float)
|
|
380
|
+
return value.to_f if @lenient_conversion
|
|
381
|
+
|
|
382
|
+
if value.is_a?(String)
|
|
383
|
+
signed_float = parse_signed_hex_str(value)
|
|
384
|
+
return signed_float if signed_float
|
|
385
|
+
end
|
|
386
|
+
|
|
387
|
+
Float(value)
|
|
356
388
|
end
|
|
357
389
|
|
|
358
390
|
def convert_integer_eu(value)
|
|
@@ -374,6 +406,25 @@ class LogStash::Filters::Mutate < LogStash::Filters::Base
|
|
|
374
406
|
value.tr(",.", ".,")
|
|
375
407
|
end
|
|
376
408
|
|
|
409
|
+
# Parses a string to determine if it represents a signed hexadecimal number.
|
|
410
|
+
# If the string matches a signed hex format (eg "-0x1A"), returns the signed float value.
|
|
411
|
+
# JRuby Float() can parse signed hex string and uppercase hex string in version 10+,
|
|
412
|
+
# but not in earlier versions.
|
|
413
|
+
#
|
|
414
|
+
# @param value [String] the string to parse
|
|
415
|
+
# @return [Float, nil] the signed float value if hex, or nil if not a hex string
|
|
416
|
+
def parse_signed_hex_str(value)
|
|
417
|
+
return Float(value) if @support_signed_hex
|
|
418
|
+
|
|
419
|
+
if value.match?(/^[+-]?0x/i)
|
|
420
|
+
sign = value.start_with?('-') ? -1 : 1
|
|
421
|
+
unsigned = value.sub(/^[+-]/, '')
|
|
422
|
+
return sign * Float(unsigned)
|
|
423
|
+
end
|
|
424
|
+
|
|
425
|
+
nil
|
|
426
|
+
end
|
|
427
|
+
|
|
377
428
|
def gsub(event)
|
|
378
429
|
@gsub_parsed.each do |config|
|
|
379
430
|
field = config[:field]
|
|
@@ -542,4 +593,14 @@ class LogStash::Filters::Mutate < LogStash::Filters::Base
|
|
|
542
593
|
event.set(dest_field,LogStash::Util.deep_clone(original))
|
|
543
594
|
end
|
|
544
595
|
end
|
|
596
|
+
|
|
597
|
+
def self.is_lenient_version?
|
|
598
|
+
Gem::Version.new(LOGSTASH_VERSION) < Gem::Version.new("8.14.0")
|
|
599
|
+
end
|
|
600
|
+
|
|
601
|
+
def self.can_parse_signed_hex?
|
|
602
|
+
Float("-0x1A") == -26.0
|
|
603
|
+
rescue ArgumentError
|
|
604
|
+
false
|
|
605
|
+
end
|
|
545
606
|
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Gem::Specification.new do |s|
|
|
2
2
|
|
|
3
3
|
s.name = 'logstash-filter-mutate'
|
|
4
|
-
s.version = '3.5.
|
|
4
|
+
s.version = '3.5.9'
|
|
5
5
|
s.licenses = ['Apache License (2.0)']
|
|
6
6
|
s.summary = "Performs mutations on fields"
|
|
7
7
|
s.description = "This gem is a Logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/logstash-plugin install gemname. This gem is not a stand-alone program"
|
data/spec/filters/mutate_spec.rb
CHANGED
|
@@ -318,7 +318,7 @@ describe LogStash::Filters::Mutate do
|
|
|
318
318
|
convert => [ "message", "int"] #should be integer
|
|
319
319
|
}
|
|
320
320
|
}
|
|
321
|
-
|
|
321
|
+
CONFIG
|
|
322
322
|
|
|
323
323
|
sample "not_really_important" do
|
|
324
324
|
expect {subject}.to raise_error(LogStash::ConfigurationError, /Invalid conversion type/)
|
|
@@ -1122,4 +1122,451 @@ describe LogStash::Filters::Mutate do
|
|
|
1122
1122
|
end
|
|
1123
1123
|
end
|
|
1124
1124
|
|
|
1125
|
+
describe "convert makes type conversions" do
|
|
1126
|
+
context "to string" do
|
|
1127
|
+
config <<-CONFIG
|
|
1128
|
+
filter {
|
|
1129
|
+
mutate { convert => { "a" => "string" } }
|
|
1130
|
+
}
|
|
1131
|
+
CONFIG
|
|
1132
|
+
|
|
1133
|
+
context "123" do
|
|
1134
|
+
# Integer
|
|
1135
|
+
sample({ "a" => 123 }) do
|
|
1136
|
+
expect(subject.get("a")).to be_a(String).and eq("123")
|
|
1137
|
+
end
|
|
1138
|
+
# Float
|
|
1139
|
+
sample({ "a" => Float(123.0) }) do
|
|
1140
|
+
expect(subject.get("a")).to be_a(String).and eq("123.0")
|
|
1141
|
+
end
|
|
1142
|
+
# String
|
|
1143
|
+
sample({ "a" => "123" }) do
|
|
1144
|
+
expect(subject.get("a")).to be_a(String).and eq("123")
|
|
1145
|
+
end
|
|
1146
|
+
sample({ "a" => "0x7b" }) do
|
|
1147
|
+
expect(subject.get("a")).to be_a(String).and eq("0x7b")
|
|
1148
|
+
end
|
|
1149
|
+
sample({ "a" => "123.0" }) do
|
|
1150
|
+
expect(subject.get("a")).to be_a(String).and eq("123.0")
|
|
1151
|
+
end
|
|
1152
|
+
sample({ "a" => "1.230000e+02" }) do
|
|
1153
|
+
expect(subject.get("a")).to be_a(String).and eq("1.230000e+02")
|
|
1154
|
+
end
|
|
1155
|
+
end
|
|
1156
|
+
|
|
1157
|
+
context "123.45" do
|
|
1158
|
+
# Float
|
|
1159
|
+
sample({ "a" => Float(123.45) }) do
|
|
1160
|
+
expect(subject.get("a")).to be_a(String).and eq("123.45")
|
|
1161
|
+
end
|
|
1162
|
+
# String
|
|
1163
|
+
sample({ "a" => "123.45" }) do
|
|
1164
|
+
expect(subject.get("a")).to be_a(String).and eq("123.45")
|
|
1165
|
+
end
|
|
1166
|
+
sample({ "a" => "1.234500e+02" }) do
|
|
1167
|
+
expect(subject.get("a")).to be_a(String).and eq("1.234500e+02")
|
|
1168
|
+
end
|
|
1169
|
+
sample({ "a" => "0x1.edcdp6" }) do
|
|
1170
|
+
expect(subject.get("a")).to be_a(String).and eq( "0x1.edcdp6" )
|
|
1171
|
+
end
|
|
1172
|
+
end
|
|
1173
|
+
|
|
1174
|
+
context "16777217" do
|
|
1175
|
+
# Integer
|
|
1176
|
+
sample({ "a" => 16777217 }) do
|
|
1177
|
+
expect(subject.get("a")).to be_a(String).and eq("16777217")
|
|
1178
|
+
end
|
|
1179
|
+
# Float
|
|
1180
|
+
sample({ "a" => 1.6777217E7 }) do
|
|
1181
|
+
expect(subject.get("a")).to be_a(String).and eq("16777217.0")
|
|
1182
|
+
end
|
|
1183
|
+
# String
|
|
1184
|
+
sample({ "a" => "16777217" }) do
|
|
1185
|
+
expect(subject.get("a")).to be_a(String).and eq("16777217")
|
|
1186
|
+
end
|
|
1187
|
+
sample({ "a" => "16777217.0" }) do
|
|
1188
|
+
expect(subject.get("a")).to be_a(String).and eq("16777217.0")
|
|
1189
|
+
end
|
|
1190
|
+
end
|
|
1191
|
+
|
|
1192
|
+
context "2147483648" do
|
|
1193
|
+
# Long
|
|
1194
|
+
sample({ "a" => 2147483648 }) do
|
|
1195
|
+
expect(subject.get("a")).to be_a(String).and eq("2147483648")
|
|
1196
|
+
end
|
|
1197
|
+
# Double
|
|
1198
|
+
sample({ "a" => 2.147483648E9 }) do
|
|
1199
|
+
expect(subject.get("a")).to be_a(String).and eq("2147483648.0")
|
|
1200
|
+
end
|
|
1201
|
+
# String
|
|
1202
|
+
sample({ "a" => "2147483648" }) do
|
|
1203
|
+
expect(subject.get("a")).to be_a(String).and eq("2147483648")
|
|
1204
|
+
end
|
|
1205
|
+
sample({ "a" => "2147483648.0" }) do
|
|
1206
|
+
expect(subject.get("a")).to be_a(String).and eq("2147483648.0")
|
|
1207
|
+
end
|
|
1208
|
+
end
|
|
1209
|
+
|
|
1210
|
+
context "9007199254740993" do
|
|
1211
|
+
# Long
|
|
1212
|
+
sample({ "a" => 9007199254740993 }) do
|
|
1213
|
+
expect(subject.get("a")).to be_a(String).and eq("9007199254740993")
|
|
1214
|
+
end
|
|
1215
|
+
# String
|
|
1216
|
+
sample({ "a" => "9007199254740993" }) do
|
|
1217
|
+
expect(subject.get("a")).to be_a(String).and eq("9007199254740993")
|
|
1218
|
+
end
|
|
1219
|
+
sample({ "a" => "9007199254740993.0" }) do
|
|
1220
|
+
expect(subject.get("a")).to be_a(String).and eq("9007199254740993.0")
|
|
1221
|
+
end
|
|
1222
|
+
end
|
|
1223
|
+
|
|
1224
|
+
|
|
1225
|
+
context "9223372036854775808" do
|
|
1226
|
+
# String
|
|
1227
|
+
sample({ "a" => "9223372036854775808" }) do
|
|
1228
|
+
expect(subject.get("a")).to be_a(String).and eq("9223372036854775808")
|
|
1229
|
+
end
|
|
1230
|
+
sample({ "a" => "9223372036854775808.0" }) do
|
|
1231
|
+
expect(subject.get("a")).to be_a(String).and eq("9223372036854775808.0")
|
|
1232
|
+
end
|
|
1233
|
+
end
|
|
1234
|
+
|
|
1235
|
+
context "680564693277057720000000000000000000000" do
|
|
1236
|
+
# String
|
|
1237
|
+
sample({ "a" => "680564693277057720000000000000000000000" }) do
|
|
1238
|
+
expect(subject.get("a")).to be_a(String).and eq("680564693277057720000000000000000000000")
|
|
1239
|
+
end
|
|
1240
|
+
sample({ "a" => "680564693277057720000000000000000000000.0" }) do
|
|
1241
|
+
expect(subject.get("a")).to be_a(String).and eq("680564693277057720000000000000000000000.0")
|
|
1242
|
+
end
|
|
1243
|
+
end
|
|
1244
|
+
end
|
|
1245
|
+
|
|
1246
|
+
context "to integer" do
|
|
1247
|
+
config <<-CONFIG
|
|
1248
|
+
filter {
|
|
1249
|
+
mutate { convert => { "a" => "integer" } }
|
|
1250
|
+
}
|
|
1251
|
+
CONFIG
|
|
1252
|
+
|
|
1253
|
+
context "123" do
|
|
1254
|
+
# Integer
|
|
1255
|
+
sample({ "a" => 123 }) do
|
|
1256
|
+
expect(subject.get("a")).to be_a(Integer).and eq(123)
|
|
1257
|
+
end
|
|
1258
|
+
# Float
|
|
1259
|
+
sample({ "a" => Float(123.0) }) do
|
|
1260
|
+
expect(subject.get("a")).to be_a(Integer).and eq(123)
|
|
1261
|
+
end
|
|
1262
|
+
# String
|
|
1263
|
+
sample({ "a" => "123" }) do
|
|
1264
|
+
expect(subject.get("a")).to be_a(Integer).and eq(123)
|
|
1265
|
+
end
|
|
1266
|
+
sample({ "a" => "0x7b" }) do
|
|
1267
|
+
expect(subject.get("a")).to be_a(Integer).and eq(123)
|
|
1268
|
+
end
|
|
1269
|
+
sample({ "a" => "123.0" }) do
|
|
1270
|
+
expect(subject.get("a")).to be_a(Integer).and eq(123)
|
|
1271
|
+
end
|
|
1272
|
+
sample({ "a" => "1.230000e+02" }) do
|
|
1273
|
+
expect(subject.get("a")).to be_a(Integer).and eq(123)
|
|
1274
|
+
end
|
|
1275
|
+
end
|
|
1276
|
+
|
|
1277
|
+
context "123.45" do
|
|
1278
|
+
# Float
|
|
1279
|
+
sample({ "a" => Float(123.45) }) do
|
|
1280
|
+
expect(subject.get("a")).to be_a(Integer).and eq(123)
|
|
1281
|
+
end
|
|
1282
|
+
# String
|
|
1283
|
+
sample({ "a" => "123.45" }) do
|
|
1284
|
+
expect(subject.get("a")).to be_a(Integer).and eq(123)
|
|
1285
|
+
end
|
|
1286
|
+
sample({ "a" => "1.234500e+02" }) do
|
|
1287
|
+
expect(subject.get("a")).to be_a(Integer).and eq(123)
|
|
1288
|
+
end
|
|
1289
|
+
sample({ "a" => "0x1.edcdp6" }) do
|
|
1290
|
+
expect(subject.get("a")).to be_a(Integer).and eq(123)
|
|
1291
|
+
end
|
|
1292
|
+
end
|
|
1293
|
+
|
|
1294
|
+
context "-123.45" do
|
|
1295
|
+
# Float
|
|
1296
|
+
sample({ "a" => Float(-123.45) }) do
|
|
1297
|
+
expect(subject.get("a")).to be_a(Integer).and eq(-123)
|
|
1298
|
+
end
|
|
1299
|
+
# String
|
|
1300
|
+
sample({ "a" => "-123.45" }) do
|
|
1301
|
+
expect(subject.get("a")).to be_a(Integer).and eq(-123)
|
|
1302
|
+
end
|
|
1303
|
+
sample({ "a" => "-1.234500e+02" }) do
|
|
1304
|
+
expect(subject.get("a")).to be_a(Integer).and eq(-123)
|
|
1305
|
+
end
|
|
1306
|
+
sample({ "a" => "-0x1.edcdp6" }) do
|
|
1307
|
+
expect(subject.get("a")).to be_a(Integer).and eq(-123)
|
|
1308
|
+
end
|
|
1309
|
+
end
|
|
1310
|
+
|
|
1311
|
+
context "16777217" do
|
|
1312
|
+
# Integer
|
|
1313
|
+
sample({ "a" => 16777217 }) do
|
|
1314
|
+
expect(subject.get("a")).to be_a(Integer).and eq(16777217)
|
|
1315
|
+
end
|
|
1316
|
+
# Double
|
|
1317
|
+
sample({ "a" => 1.6777217E7 }) do
|
|
1318
|
+
expect(subject.get("a")).to be_a(Integer).and eq(16777217)
|
|
1319
|
+
end
|
|
1320
|
+
# String
|
|
1321
|
+
sample({ "a" => "16777217" }) do
|
|
1322
|
+
expect(subject.get("a")).to be_a(Integer).and eq(16777217)
|
|
1323
|
+
end
|
|
1324
|
+
sample({ "a" => "16777217.0" }) do
|
|
1325
|
+
expect(subject.get("a")).to be_a(Integer).and eq(16777217)
|
|
1326
|
+
end
|
|
1327
|
+
end
|
|
1328
|
+
|
|
1329
|
+
context "2147483648" do
|
|
1330
|
+
# Long
|
|
1331
|
+
sample({ "a" => 2147483648 }) do
|
|
1332
|
+
expect(subject.get("a")).to be_a(Integer).and eq(2147483648)
|
|
1333
|
+
end
|
|
1334
|
+
# Double
|
|
1335
|
+
sample({ "a" => 2.147483648E9 }) do
|
|
1336
|
+
expect(subject.get("a")).to be_a(Integer).and eq(2147483648)
|
|
1337
|
+
end
|
|
1338
|
+
# String
|
|
1339
|
+
sample({ "a" => "2147483648" }) do
|
|
1340
|
+
expect(subject.get("a")).to be_a(Integer).and eq(2147483648)
|
|
1341
|
+
end
|
|
1342
|
+
sample({ "a" => "2147483648.0" }) do
|
|
1343
|
+
expect(subject.get("a")).to be_a(Integer).and eq(2147483648)
|
|
1344
|
+
end
|
|
1345
|
+
end
|
|
1346
|
+
|
|
1347
|
+
context "9007199254740993" do
|
|
1348
|
+
# Long
|
|
1349
|
+
sample({ "a" => 9007199254740993 }) do
|
|
1350
|
+
expect(subject.get("a")).to be_a(Integer).and eq(9007199254740993)
|
|
1351
|
+
end
|
|
1352
|
+
# String
|
|
1353
|
+
sample({ "a" => "9007199254740993" }) do
|
|
1354
|
+
expect(subject.get("a")).to be_a(Integer).and eq(9007199254740993)
|
|
1355
|
+
end
|
|
1356
|
+
sample({ "a" => "9007199254740993.0" }) do
|
|
1357
|
+
expect(subject.get("a")).to be_a(Integer).and eq(9007199254740993)
|
|
1358
|
+
end
|
|
1359
|
+
sample({ "a" => "9.007199254740993e+15" }) do
|
|
1360
|
+
expect(subject.get("a")).to be_a(Integer).and eq(9007199254740993)
|
|
1361
|
+
end
|
|
1362
|
+
end
|
|
1363
|
+
|
|
1364
|
+
context "9223372036854775808" do
|
|
1365
|
+
# String
|
|
1366
|
+
sample({ "a" => "9223372036854775808" }) do
|
|
1367
|
+
expect(subject.get("a")).to be_a(Integer).and eq(9223372036854775808)
|
|
1368
|
+
end
|
|
1369
|
+
sample({ "a" => "9223372036854775808.0" }) do
|
|
1370
|
+
expect(subject.get("a")).to be_a(Integer).and eq(9223372036854775808)
|
|
1371
|
+
end
|
|
1372
|
+
end
|
|
1373
|
+
|
|
1374
|
+
context "680564693277057720000000000000000000000" do
|
|
1375
|
+
# String
|
|
1376
|
+
sample({ "a" => "680564693277057720000000000000000000000" }) do
|
|
1377
|
+
expect(subject.get("a")).to be_a(Integer).and eq(680564693277057720000000000000000000000)
|
|
1378
|
+
end
|
|
1379
|
+
sample({ "a" => "680564693277057720000000000000000000000.0" }) do
|
|
1380
|
+
expect(subject.get("a")).to be_a(Integer).and eq(680564693277057720000000000000000000000)
|
|
1381
|
+
end
|
|
1382
|
+
end
|
|
1383
|
+
|
|
1384
|
+
end
|
|
1385
|
+
|
|
1386
|
+
context "to float" do
|
|
1387
|
+
config <<-CONFIG
|
|
1388
|
+
filter {
|
|
1389
|
+
mutate { convert => { "a" => "float" } }
|
|
1390
|
+
}
|
|
1391
|
+
CONFIG
|
|
1392
|
+
|
|
1393
|
+
context "123" do
|
|
1394
|
+
# Integer
|
|
1395
|
+
sample({ "a" => 123 }) do
|
|
1396
|
+
expect(subject.get("a")).to be_a(Float).and eq(123.0)
|
|
1397
|
+
end
|
|
1398
|
+
# Float
|
|
1399
|
+
sample({ "a" => Float(123) }) do
|
|
1400
|
+
expect(subject.get("a")).to be_a(Float).and eq(123.0)
|
|
1401
|
+
end
|
|
1402
|
+
# String
|
|
1403
|
+
sample({ "a" => "123" }) do
|
|
1404
|
+
expect(subject.get("a")).to be_a(Float).and eq(123.0)
|
|
1405
|
+
end
|
|
1406
|
+
sample({ "a" => "0x7b" }) do
|
|
1407
|
+
expect(subject.get("a")).to be_a(Float).and eq(123.0)
|
|
1408
|
+
end
|
|
1409
|
+
sample({ "a" => "123.0" }) do
|
|
1410
|
+
expect(subject.get("a")).to be_a(Float).and eq(123.0)
|
|
1411
|
+
end
|
|
1412
|
+
sample({ "a" => "1.230000e+02" }) do
|
|
1413
|
+
expect(subject.get("a")).to be_a(Float).and eq(123.0)
|
|
1414
|
+
end
|
|
1415
|
+
end
|
|
1416
|
+
|
|
1417
|
+
context "123.45" do
|
|
1418
|
+
# Float
|
|
1419
|
+
sample({ "a" => Float(123.45) }) do
|
|
1420
|
+
expect(subject.get("a")).to be_a(Float).and eq(123.45)
|
|
1421
|
+
end
|
|
1422
|
+
# String
|
|
1423
|
+
sample({ "a" => "123.45" }) do
|
|
1424
|
+
expect(subject.get("a")).to be_a(Float).and eq(123.45)
|
|
1425
|
+
end
|
|
1426
|
+
sample({ "a" => "1.234500e+02" }) do
|
|
1427
|
+
expect(subject.get("a")).to be_a(Float).and eq(123.45)
|
|
1428
|
+
end
|
|
1429
|
+
sample({ "a" => "0x1.edcdp6" }) do
|
|
1430
|
+
expect(subject.get("a")).to be_a(Float).and eq(123.4501953125)
|
|
1431
|
+
end
|
|
1432
|
+
end
|
|
1433
|
+
|
|
1434
|
+
context "-123.45" do
|
|
1435
|
+
# Float
|
|
1436
|
+
sample({ "a" => Float(-123.45) }) do
|
|
1437
|
+
expect(subject.get("a")).to be_a(Float).and eq(-123.45)
|
|
1438
|
+
end
|
|
1439
|
+
# String
|
|
1440
|
+
sample({ "a" => "-123.45" }) do
|
|
1441
|
+
expect(subject.get("a")).to be_a(Float).and eq(-123.45)
|
|
1442
|
+
end
|
|
1443
|
+
sample({ "a" => "-1.234500e+02" }) do
|
|
1444
|
+
expect(subject.get("a")).to be_a(Float).and eq(-123.45)
|
|
1445
|
+
end
|
|
1446
|
+
sample({ "a" => "-0x1.edcdp6" }) do
|
|
1447
|
+
expect(subject.get("a")).to be_a(Float).and eq(-123.4501953125)
|
|
1448
|
+
end
|
|
1449
|
+
end
|
|
1450
|
+
|
|
1451
|
+
context "16777217" do
|
|
1452
|
+
# Integer
|
|
1453
|
+
sample({ "a" => 16777217 }) do
|
|
1454
|
+
expect(subject.get("a")).to be_a(Float).and eq(1.6777217E7)
|
|
1455
|
+
end
|
|
1456
|
+
# Float
|
|
1457
|
+
sample({ "a" => 1.6777217E7 }) do
|
|
1458
|
+
expect(subject.get("a")).to be_a(Float).and eq(1.6777217E7)
|
|
1459
|
+
end
|
|
1460
|
+
# String
|
|
1461
|
+
sample({ "a" => "16777217" }) do
|
|
1462
|
+
expect(subject.get("a")).to be_a(Float).and eq(1.6777217E7)
|
|
1463
|
+
end
|
|
1464
|
+
sample({ "a" => "16777217.0" }) do
|
|
1465
|
+
expect(subject.get("a")).to be_a(Float).and eq(1.6777217E7)
|
|
1466
|
+
end
|
|
1467
|
+
end
|
|
1468
|
+
|
|
1469
|
+
|
|
1470
|
+
context "2147483648" do
|
|
1471
|
+
# Long
|
|
1472
|
+
sample({ "a" => 2147483648 }) do
|
|
1473
|
+
expect(subject.get("a")).to be_a(Float).and eq(2.147483648E9)
|
|
1474
|
+
end
|
|
1475
|
+
# Double
|
|
1476
|
+
sample({ "a" => 2.147483648E9 }) do
|
|
1477
|
+
expect(subject.get("a")).to be_a(Float).and eq(2.147483648E9)
|
|
1478
|
+
end
|
|
1479
|
+
# String
|
|
1480
|
+
sample({ "a" => "2147483648" }) do
|
|
1481
|
+
expect(subject.get("a")).to be_a(Float).and eq(2.147483648E9)
|
|
1482
|
+
end
|
|
1483
|
+
sample({ "a" => "2147483648.0" }) do
|
|
1484
|
+
expect(subject.get("a")).to be_a(Float).and eq(2.147483648E9)
|
|
1485
|
+
end
|
|
1486
|
+
end
|
|
1487
|
+
|
|
1488
|
+
context "9007199254740993" do
|
|
1489
|
+
# Long
|
|
1490
|
+
sample({ "a" => 9007199254740993 }) do
|
|
1491
|
+
expect(subject.get("a")).to be_a(Float).and eq(9.007199254740992E15)
|
|
1492
|
+
end
|
|
1493
|
+
# String
|
|
1494
|
+
sample({ "a" => "9007199254740993" }) do
|
|
1495
|
+
expect(subject.get("a")).to be_a(Float).and eq(9.007199254740992E15)
|
|
1496
|
+
end
|
|
1497
|
+
sample({ "a" => "9007199254740993.0" }) do
|
|
1498
|
+
expect(subject.get("a")).to be_a(Float).and eq(9.007199254740992E15)
|
|
1499
|
+
end
|
|
1500
|
+
sample({ "a" => "9.007199254740993e+15" }) do
|
|
1501
|
+
expect(subject.get("a")).to be_a(Float).and eq(9007199254740992)
|
|
1502
|
+
end
|
|
1503
|
+
end
|
|
1504
|
+
|
|
1505
|
+
context "9223372036854775808" do
|
|
1506
|
+
# String
|
|
1507
|
+
sample({ "a" => "9223372036854775808" }) do
|
|
1508
|
+
expect(subject.get("a")).to be_a(Float).and eq(9.223372036854775808E18)
|
|
1509
|
+
end
|
|
1510
|
+
sample({ "a" => "9223372036854775808.0" }) do
|
|
1511
|
+
expect(subject.get("a")).to be_a(Float).and eq(9.223372036854775808E18)
|
|
1512
|
+
end
|
|
1513
|
+
end
|
|
1514
|
+
|
|
1515
|
+
context "680564693277057720000000000000000000000" do
|
|
1516
|
+
# String
|
|
1517
|
+
sample({ "a" => "680564693277057720000000000000000000000" }) do
|
|
1518
|
+
expect(subject.get("a")).to be_a(Float).and eq(6.805646932770577e+38)
|
|
1519
|
+
end
|
|
1520
|
+
sample({ "a" => "680564693277057720000000000000000000000.0" }) do
|
|
1521
|
+
expect(subject.get("a")).to be_a(Float).and eq(6.805646932770577e+38)
|
|
1522
|
+
end
|
|
1523
|
+
end
|
|
1524
|
+
end
|
|
1525
|
+
|
|
1526
|
+
end unless LogStash::Filters::Mutate.is_lenient_version? # only test type conversions in v8.14+
|
|
1527
|
+
|
|
1528
|
+
describe "parse_signed_hex_str" do
|
|
1529
|
+
subject { LogStash::Filters::Mutate.new({ }) }
|
|
1530
|
+
|
|
1531
|
+
context 'hexadecimal integers' do
|
|
1532
|
+
it 'parses positive hex integer' do
|
|
1533
|
+
expect(subject.send(:parse_signed_hex_str, '0x1A')).to eq(26.0)
|
|
1534
|
+
end
|
|
1535
|
+
|
|
1536
|
+
it 'parses negative hex integer' do
|
|
1537
|
+
expect(subject.send(:parse_signed_hex_str, '-0x1A')).to eq(-26.0)
|
|
1538
|
+
expect(subject.send(:parse_signed_hex_str,'-0xFF')).to eq(-255.0)
|
|
1539
|
+
end
|
|
1540
|
+
|
|
1541
|
+
it 'ignores case in hex prefix' do
|
|
1542
|
+
expect(subject.send(:parse_signed_hex_str,'0x1A')).to eq(26.0)
|
|
1543
|
+
expect(subject.send(:parse_signed_hex_str,'-0x1A')).to eq(-26.0)
|
|
1544
|
+
end
|
|
1545
|
+
end
|
|
1546
|
+
|
|
1547
|
+
context 'hexadecimal floats' do
|
|
1548
|
+
it 'parses positive hex float' do
|
|
1549
|
+
expect(subject.send(:parse_signed_hex_str,'0x1.8p+1')).to eq(3.0)
|
|
1550
|
+
end
|
|
1551
|
+
|
|
1552
|
+
it 'parses negative hex float' do
|
|
1553
|
+
expect(subject.send(:parse_signed_hex_str,'-0x1.8p+1')).to eq(-3.0)
|
|
1554
|
+
expect(subject.send(:parse_signed_hex_str,'-0x1.2p+2')).to eq(-4.5)
|
|
1555
|
+
end
|
|
1556
|
+
end
|
|
1557
|
+
|
|
1558
|
+
context 'non-hex strings' do
|
|
1559
|
+
it 'returns nil for decimal numbers' do
|
|
1560
|
+
expect(subject.send(:parse_signed_hex_str,'123')).to be_nil
|
|
1561
|
+
expect(subject.send(:parse_signed_hex_str,'-456')).to be_nil
|
|
1562
|
+
expect(subject.send(:parse_signed_hex_str,'1.23')).to be_nil
|
|
1563
|
+
end
|
|
1564
|
+
|
|
1565
|
+
it 'returns nil for random strings' do
|
|
1566
|
+
expect(subject.send(:parse_signed_hex_str,'abc')).to be_nil
|
|
1567
|
+
expect(subject.send(:parse_signed_hex_str,'0b1010')).to be_nil
|
|
1568
|
+
end
|
|
1569
|
+
end
|
|
1570
|
+
end unless LogStash::Filters::Mutate.is_lenient_version?
|
|
1571
|
+
|
|
1125
1572
|
end
|
metadata
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: logstash-filter-mutate
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.5.
|
|
4
|
+
version: 3.5.9
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Elastic
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 2025-10-31 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: logstash-core-plugin-api
|
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
|
15
15
|
requirements:
|
|
16
16
|
- - ">="
|
|
@@ -19,9 +19,8 @@ dependencies:
|
|
|
19
19
|
- - "<="
|
|
20
20
|
- !ruby/object:Gem::Version
|
|
21
21
|
version: '2.99'
|
|
22
|
-
name: logstash-core-plugin-api
|
|
23
|
-
prerelease: false
|
|
24
22
|
type: :runtime
|
|
23
|
+
prerelease: false
|
|
25
24
|
version_requirements: !ruby/object:Gem::Requirement
|
|
26
25
|
requirements:
|
|
27
26
|
- - ">="
|
|
@@ -31,56 +30,56 @@ dependencies:
|
|
|
31
30
|
- !ruby/object:Gem::Version
|
|
32
31
|
version: '2.99'
|
|
33
32
|
- !ruby/object:Gem::Dependency
|
|
33
|
+
name: logstash-patterns-core
|
|
34
34
|
requirement: !ruby/object:Gem::Requirement
|
|
35
35
|
requirements:
|
|
36
36
|
- - ">="
|
|
37
37
|
- !ruby/object:Gem::Version
|
|
38
38
|
version: '0'
|
|
39
|
-
name: logstash-patterns-core
|
|
40
|
-
prerelease: false
|
|
41
39
|
type: :development
|
|
40
|
+
prerelease: false
|
|
42
41
|
version_requirements: !ruby/object:Gem::Requirement
|
|
43
42
|
requirements:
|
|
44
43
|
- - ">="
|
|
45
44
|
- !ruby/object:Gem::Version
|
|
46
45
|
version: '0'
|
|
47
46
|
- !ruby/object:Gem::Dependency
|
|
47
|
+
name: logstash-filter-grok
|
|
48
48
|
requirement: !ruby/object:Gem::Requirement
|
|
49
49
|
requirements:
|
|
50
50
|
- - ">="
|
|
51
51
|
- !ruby/object:Gem::Version
|
|
52
52
|
version: '0'
|
|
53
|
-
name: logstash-filter-grok
|
|
54
|
-
prerelease: false
|
|
55
53
|
type: :development
|
|
54
|
+
prerelease: false
|
|
56
55
|
version_requirements: !ruby/object:Gem::Requirement
|
|
57
56
|
requirements:
|
|
58
57
|
- - ">="
|
|
59
58
|
- !ruby/object:Gem::Version
|
|
60
59
|
version: '0'
|
|
61
60
|
- !ruby/object:Gem::Dependency
|
|
61
|
+
name: logstash-codec-plain
|
|
62
62
|
requirement: !ruby/object:Gem::Requirement
|
|
63
63
|
requirements:
|
|
64
64
|
- - ">="
|
|
65
65
|
- !ruby/object:Gem::Version
|
|
66
66
|
version: '0'
|
|
67
|
-
name: logstash-codec-plain
|
|
68
|
-
prerelease: false
|
|
69
67
|
type: :development
|
|
68
|
+
prerelease: false
|
|
70
69
|
version_requirements: !ruby/object:Gem::Requirement
|
|
71
70
|
requirements:
|
|
72
71
|
- - ">="
|
|
73
72
|
- !ruby/object:Gem::Version
|
|
74
73
|
version: '0'
|
|
75
74
|
- !ruby/object:Gem::Dependency
|
|
75
|
+
name: logstash-devutils
|
|
76
76
|
requirement: !ruby/object:Gem::Requirement
|
|
77
77
|
requirements:
|
|
78
78
|
- - ">="
|
|
79
79
|
- !ruby/object:Gem::Version
|
|
80
80
|
version: '0'
|
|
81
|
-
name: logstash-devutils
|
|
82
|
-
prerelease: false
|
|
83
81
|
type: :development
|
|
82
|
+
prerelease: false
|
|
84
83
|
version_requirements: !ruby/object:Gem::Requirement
|
|
85
84
|
requirements:
|
|
86
85
|
- - ">="
|
|
@@ -111,7 +110,6 @@ licenses:
|
|
|
111
110
|
metadata:
|
|
112
111
|
logstash_plugin: 'true'
|
|
113
112
|
logstash_group: filter
|
|
114
|
-
post_install_message:
|
|
115
113
|
rdoc_options: []
|
|
116
114
|
require_paths:
|
|
117
115
|
- lib
|
|
@@ -126,8 +124,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
126
124
|
- !ruby/object:Gem::Version
|
|
127
125
|
version: '0'
|
|
128
126
|
requirements: []
|
|
129
|
-
rubygems_version: 3.
|
|
130
|
-
signing_key:
|
|
127
|
+
rubygems_version: 3.6.3
|
|
131
128
|
specification_version: 4
|
|
132
129
|
summary: Performs mutations on fields
|
|
133
130
|
test_files:
|