fluent-plugin-elasticsearch-timestamp-check 0.2.6 → 0.2.7

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5cd7b06f7edb4ce3f72d1c6dccf21929046ceb51
4
- data.tar.gz: 9ef81ffc2b011bd4e8a06fbdf66b38562c59711f
3
+ metadata.gz: 507e9c8bcb7590f680c4c72c39b26a86ef9029d3
4
+ data.tar.gz: c709c47aa550498ffef8ab50f8493dda0ed154a9
5
5
  SHA512:
6
- metadata.gz: a091f77db169760a13a1838c2d6e2a68b50f97274902f4506b467568f3c279f9b5e0763be181a9259ff7a5051a0ffd9ae8db5e06ef08534d85f20ecaa09a5fe8
7
- data.tar.gz: 0da8c759f7c0d29b5970ccd0d3c06ac2317e2d411cd159321c178cea88bd8e9c538b80442a7c8cf83a9cf7b903ba9620bf43b28a83126cdf89e0bf0e8f45ea08
6
+ metadata.gz: '082a9b6262d7bdd1d0eff963c4b3d30a4e0983012a802192e5c2b8bd2a50241ac65dd2795890c3a3fdfe760624139fa28e14273142165925bc8f2fce67b95d1b'
7
+ data.tar.gz: 02c0c8ce935610f5024f2a39d69670e85ef8474690454f2e5c171a027ce8b6358534662cce83068c039de9d2045ee110430ade8671d47fbf50d47301e94dc4c9
data/README.md CHANGED
@@ -13,23 +13,39 @@ The purpose of this filter is to make sure the @timestamp field exists in the
13
13
  record which is necessary for the record to be indexed properly by
14
14
  elasticsearch.
15
15
 
16
- * If *@timestamp* field already exists, it will ensure the format is correct
16
+ * If `@timestamp` field already exists, it will ensure the format is correct
17
17
  by parse and convert to format '%Y-%m-%dT%H:%M:%S%z'. **As of version 0.2.4, it
18
18
  will support epoch second / epoch millis format as a valid timestamp value. If
19
19
  such value is detected, it will be converted to iso8601 format for easier
20
20
  consumption of elasticsearch when dynamic mapping is used.**
21
21
 
22
- * If a field named *timestamp* or *time* or *syslog_timestamp* exists, it will
23
- parse that field and conver it to format '%Y-%m-%dT%H:%M:%S%z' then store it
24
- in *@timestamp* field.
22
+ * If a field named `timestamp` or `time` or `syslog_timestamp` exists, it will
23
+ parse that field and conver it to format '%Y-%m-%dT%H:%M:%S.%L%z' then store it
24
+ in `@timestamp` field. In addition, a field `fluent_converted_timestamp`
25
+ is added to the object with the same value.
25
26
 
26
27
  * If none of the above field exists, it will insert current time in
27
- '%Y-%m-%dT%H:%M:%S%z' format as the *@timestamp* field.
28
+ '%Y-%m-%dT%H:%M:%S.%L%z' format as the `@timestamp` field. A field
29
+ `fluent_added_timestamp` is added to the object with same value.
30
+
31
+ ## (>=0.2.6) Subsecond Precision
32
+
33
+ `subsecond_precision` controls the subsecond precision during the conversion.
34
+ Default value is set to `3` (millisecond).
35
+
36
+ Other `subsecond_precision` sample values are:
37
+
38
+ * `6` (microsecond)
39
+ * `9` (nanosecond)
40
+ * `12` (picosecond)
41
+
42
+ and more high precision is also supported.
28
43
 
29
44
  ## Usage
30
45
 
31
46
  ```
32
47
  <filter **>
33
48
  type elasticsearch_timestamp_check
49
+ subsecond_precision 3
34
50
  </filter>
35
51
  ```
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |spec|
2
2
  spec.name = "fluent-plugin-elasticsearch-timestamp-check"
3
- spec.version = "0.2.6"
3
+ spec.version = "0.2.7"
4
4
  spec.authors = ["Richard Li"]
5
5
  spec.email = ["evilcat@wisewolfsolutions.com"]
6
6
  spec.description = %q{fluent filter plugin to ensure @timestamp is in proper format}
@@ -2,6 +2,8 @@ require 'fluent/plugin/filter'
2
2
 
3
3
  module Fluent::Plugin
4
4
  class ElasticsearchTimestampCheckFilter < Filter
5
+ attr_reader :timestamp_digits
6
+
5
7
  Fluent::Plugin.register_filter('elasticsearch_timestamp_check', self)
6
8
 
7
9
  config_param :subsecond_precision, :integer, default: 3
@@ -11,6 +13,15 @@ module Fluent::Plugin
11
13
  require 'date'
12
14
  raise Fluent::ConfigError, "specify 1 or bigger number." if subsecond_precision < 1
13
15
  @strftime_format = "%Y-%m-%dT%H:%M:%S.%#{@subsecond_precision}N%z".freeze
16
+ @timestamp_digits = configure_digits
17
+ end
18
+
19
+ def configure_digits
20
+ subepoch_precision = 10 + @subsecond_precision
21
+ timestamp_digits = [10, 13]
22
+ timestamp_digits << subepoch_precision
23
+ timestamp_digits.uniq!
24
+ timestamp_digits
14
25
  end
15
26
 
16
27
  def start
@@ -29,10 +40,11 @@ module Fluent::Plugin
29
40
  # all digit entry would be treated as epoch seconds or epoch millis
30
41
  if !!(timestamp =~ /\A[-+]?\d+\z/)
31
42
  num = timestamp.to_f
32
- # epoch second or epoch millis should be either 10 or 13 digits
43
+ # By default, epoch second or epoch millis should be either 10 or 13 digits
33
44
  # other length should be considered invalid (until the next digit
34
45
  # rollover at 2286-11-20 17:46:40 Z
35
- next unless [10, 13].include?(Math.log10(num).to_i + 1)
46
+ # For user-defined precision also should handle here.
47
+ next unless @timestamp_digits.include?(Math.log10(num).to_i + 1)
36
48
  record['@timestamp'] = record['fluent_converted_timestamp'] =
37
49
  Time.at(
38
50
  num / (10 ** ((Math.log10(num).to_i + 1) - 10))
@@ -64,6 +64,30 @@ class TestElasticsearchTimestampCheckFilter < Test::Unit::TestCase
64
64
  formatted_time = Time.at(
65
65
  num / (10 ** ((Math.log10(num).to_i + 1) - 10))
66
66
  ).strftime('%Y-%m-%dT%H:%M:%S.%3N%z')
67
+ assert_equal([10, 13], d.instance.timestamp_digits)
68
+ assert_true(filtered.key?("@timestamp"))
69
+ assert_true(filtered.key?("fluent_converted_timestamp"))
70
+ assert_equal(formatted_time, filtered["fluent_converted_timestamp"])
71
+ end
72
+
73
+ data('@timestamp' => '@timestamp',
74
+ 'timestamp' => 'timestamp',
75
+ 'time' => 'time',
76
+ 'syslog_timestamp' => 'syslog_timestamp')
77
+ def test_timestamp_with_digit_and_micro_precision(data)
78
+ timekey = data
79
+ precision = 6
80
+ d = create_driver(%[subsecond_precision #{precision}])
81
+ timestamp = '1517878172013770'
82
+ d.run(default_tag: 'test') do
83
+ d.feed({'test' => 'notime'}.merge(timekey => timestamp))
84
+ end
85
+ filtered = d.filtered.map{|e| e.last}.first
86
+ num = timestamp.to_f
87
+ formatted_time = Time.at(
88
+ num / (10 ** ((Math.log10(num).to_i + 1) - 10))
89
+ ).strftime("%Y-%m-%dT%H:%M:%S.%#{precision}N%z")
90
+ assert_equal([10, 13, 10 + precision], d.instance.timestamp_digits)
67
91
  assert_true(filtered.key?("@timestamp"))
68
92
  assert_true(filtered.key?("fluent_converted_timestamp"))
69
93
  assert_equal(formatted_time, filtered["fluent_converted_timestamp"])
@@ -77,7 +101,7 @@ class TestElasticsearchTimestampCheckFilter < Test::Unit::TestCase
77
101
  timekey = data
78
102
  precision = 9
79
103
  d = create_driver(%[subsecond_precision #{precision}])
80
- timestamp = '1505800348899'
104
+ timestamp = '1517878172013770000'
81
105
  d.run(default_tag: 'test') do
82
106
  d.feed({'test' => 'notime'}.merge(timekey => timestamp))
83
107
  end
@@ -86,6 +110,7 @@ class TestElasticsearchTimestampCheckFilter < Test::Unit::TestCase
86
110
  formatted_time = Time.at(
87
111
  num / (10 ** ((Math.log10(num).to_i + 1) - 10))
88
112
  ).strftime("%Y-%m-%dT%H:%M:%S.%#{precision}N%z")
113
+ assert_equal([10, 13, 10 + precision], d.instance.timestamp_digits)
89
114
  assert_true(filtered.key?("@timestamp"))
90
115
  assert_true(filtered.key?("fluent_converted_timestamp"))
91
116
  assert_equal(formatted_time, filtered["fluent_converted_timestamp"])
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-elasticsearch-timestamp-check
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.6
4
+ version: 0.2.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Richard Li
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-02-05 00:00:00.000000000 Z
11
+ date: 2018-02-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fluentd