logstash-filter-date 2.0.2 → 2.1.0

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: 0779b4e5cffb47a4e1fa70185deceb766726f0f4
4
- data.tar.gz: 971764c7d79a63e3b5360b7350613e7de980e555
3
+ metadata.gz: 90514b78e723a6637fbf1f1225cd43d043ecdcb5
4
+ data.tar.gz: 7129c219a98c1486b73cc715471619cf1393728f
5
5
  SHA512:
6
- metadata.gz: 182c23c6cfe4c53aa61d371951fb08687654fbfcd899d4771b1f561aa929ce4e91de63f4c9dbc07f1d1b81e8a5abf8fa1addf7bb529f07c6e8175682c70b0f2f
7
- data.tar.gz: 11064858b17452ce30490d50e6a3e6b067d0705db782d529e62949219899cf0f6cd540206ba14108f42d490c267c2058d6d6eb00b58a21440d9e8319cacbe413
6
+ metadata.gz: b3fc8119ad011c783c2d13bbbe30b463db520477d752a2a0268c7a6baef22872fd18628109044121d0da2292216706c40260da90c2eda2b51479ce047ad25833
7
+ data.tar.gz: b2340da5d6ec579266aa4b76db2398490bcb3e19bc5bc152d0a0a5cd58dd58cc662b9cb8bf66232fd6fa2aca8d28fd278c78f11d78411399d2a2d4f4d32cc6a1
data/CHANGELOG.md CHANGED
@@ -1,3 +1,12 @@
1
+ ## 2.1.0
2
+ - New year rollover should be handled better now when a year is not present in
3
+ the time format. If local time is December, and event time is January, the
4
+ year will be set to next year. Similar for if local time is January and
5
+ Event time is December, the year will be set to the previous year. This
6
+ should help keep times correct in the upcoming year rollover. (#33, #4)
7
+ - The `timezone` setting now supports sprintf format (#31)
8
+ - use Event#tag, relax specs for Java Event, code cleanups
9
+
1
10
  ## 2.0.0
2
11
  - Plugins were updated to follow the new shutdown semantic, this mainly allows Logstash to instruct input plugins to terminate gracefully,
3
12
  instead of using Thread.raise on the plugins' threads. Ref: https://github.com/elastic/logstash/pull/3895
data/README.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # Logstash Plugin
2
2
 
3
+ [![Build
4
+ Status](http://build-eu-00.elastic.co/view/LS%20Plugins/view/LS%20Filters/job/logstash-plugin-filter-date-unit/badge/icon)](http://build-eu-00.elastic.co/view/LS%20Plugins/view/LS%20Filters/job/logstash-plugin-filter-date-unit/)
5
+
3
6
  This is a plugin for [Logstash](https://github.com/elastic/logstash).
4
7
 
5
8
  It is fully free and fully open source. The license is Apache 2.0, meaning you are pretty much free to use it however you want in whatever way.
@@ -35,6 +35,7 @@ class LogStash::Filters::Date < LogStash::Filters::Base
35
35
  # If this is not specified the platform default will be used.
36
36
  # Canonical ID is good as it takes care of daylight saving time for you
37
37
  # For example, `America/Los_Angeles` or `Europe/Paris` are valid IDs.
38
+ # This field can be dynamic and include parts of the event using the `%{field}` syntax
38
39
  config :timezone, :validate => :string
39
40
 
40
41
  # Specify a locale to be used for date parsing using either IETF-BCP47 or POSIX language tag.
@@ -87,7 +88,7 @@ class LogStash::Filters::Date < LogStash::Filters::Base
87
88
 
88
89
  # Store the matching timestamp into the given target field. If not provided,
89
90
  # default to updating the `@timestamp` field of the event.
90
- config :target, :validate => :string, :default => "@timestamp"
91
+ config :target, :validate => :string, :default => LogStash::Event::TIMESTAMP
91
92
 
92
93
  # Append values to the `tags` field when there has been no
93
94
  # successful match
@@ -96,14 +97,12 @@ class LogStash::Filters::Date < LogStash::Filters::Base
96
97
  # LOGSTASH-34
97
98
  DATEPATTERNS = %w{ y d H m s S }
98
99
 
99
- public
100
100
  def initialize(config = {})
101
101
  super
102
102
 
103
103
  @parsers = Hash.new { |h,k| h[k] = [] }
104
104
  end # def initialize
105
105
 
106
- public
107
106
  def register
108
107
  require "java"
109
108
  if @match.length < 2
@@ -120,6 +119,9 @@ class LogStash::Filters::Date < LogStash::Filters::Base
120
119
  end
121
120
  locale = java.util.Locale.forLanguageTag(@locale)
122
121
  end
122
+
123
+ @sprintf_timezone = @timezone && !@timezone.index("%{").nil?
124
+
123
125
  setupMatcher(@config["match"].shift, locale, @config["match"] )
124
126
  end
125
127
 
@@ -129,7 +131,7 @@ class LogStash::Filters::Date < LogStash::Filters::Base
129
131
  case format
130
132
  when "ISO8601"
131
133
  iso_parser = org.joda.time.format.ISODateTimeFormat.dateTimeParser
132
- if @timezone
134
+ if @timezone && !@sprintf_timezone
133
135
  iso_parser = iso_parser.withZone(org.joda.time.DateTimeZone.forID(@timezone))
134
136
  else
135
137
  iso_parser = iso_parser.withOffsetParsed
@@ -138,10 +140,12 @@ class LogStash::Filters::Date < LogStash::Filters::Base
138
140
  #Fall back solution of almost ISO8601 date-time
139
141
  almostISOparsers = [
140
142
  org.joda.time.format.DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss.SSSZ").getParser(),
141
- org.joda.time.format.DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss.SSS").getParser()
143
+ org.joda.time.format.DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss.SSS").getParser(),
144
+ org.joda.time.format.DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss,SSSZ").getParser(),
145
+ org.joda.time.format.DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss,SSS").getParser()
142
146
  ].to_java(org.joda.time.format.DateTimeParser)
143
147
  joda_parser = org.joda.time.format.DateTimeFormatterBuilder.new.append( nil, almostISOparsers ).toFormatter()
144
- if @timezone
148
+ if @timezone && !@sprintf_timezone
145
149
  joda_parser = joda_parser.withZone(org.joda.time.DateTimeZone.forID(@timezone))
146
150
  else
147
151
  joda_parser = joda_parser.withOffsetParsed
@@ -158,15 +162,16 @@ class LogStash::Filters::Date < LogStash::Filters::Base
158
162
  date.to_i
159
163
  end
160
164
  when "TAI64N" # TAI64 with nanoseconds, -10000 accounts for leap seconds
161
- parsers << lambda do |date|
165
+ parsers << lambda do |date|
162
166
  # Skip leading "@" if it is present (common in tai64n times)
163
167
  date = date[1..-1] if date[0, 1] == "@"
164
168
  return (date[1..15].hex * 1000 - 10000)+(date[16..23].hex/1000000)
165
169
  end
166
170
  else
167
171
  begin
168
- joda_parser = org.joda.time.format.DateTimeFormat.forPattern(format).withDefaultYear(Time.new.year)
169
- if @timezone
172
+ format_has_year = format.match(/y|Y/)
173
+ joda_parser = org.joda.time.format.DateTimeFormat.forPattern(format)
174
+ if @timezone && !@sprintf_timezone
170
175
  joda_parser = joda_parser.withZone(org.joda.time.DateTimeZone.forID(@timezone))
171
176
  else
172
177
  joda_parser = joda_parser.withOffsetParsed
@@ -174,7 +179,28 @@ class LogStash::Filters::Date < LogStash::Filters::Base
174
179
  if locale
175
180
  joda_parser = joda_parser.withLocale(locale)
176
181
  end
177
- parsers << lambda { |date| joda_parser.parseMillis(date) }
182
+ if @sprintf_timezone
183
+ parsers << lambda { |date , tz|
184
+ joda_parser.withZone(org.joda.time.DateTimeZone.forID(tz)).parseMillis(date)
185
+ }
186
+ end
187
+ parsers << lambda do |date|
188
+ return joda_parser.parseMillis(date) if format_has_year
189
+ now = Time.now
190
+ now_month = now.month
191
+ result = joda_parser.parseDateTime(date)
192
+ event_month = result.getMonthOfYear
193
+
194
+ if (event_month == now_month)
195
+ result.with_year(now.year)
196
+ elsif (event_month == 12 && now_month == 1)
197
+ result.with_year(now.year-1)
198
+ elsif (event_month == 1 && now_month == 12)
199
+ result.with_year(now.year+1)
200
+ else
201
+ result.with_year(now.year)
202
+ end.get_millis
203
+ end
178
204
 
179
205
  #Include a fallback parser to english when default locale is non-english
180
206
  if !locale &&
@@ -199,12 +225,9 @@ class LogStash::Filters::Date < LogStash::Filters::Base
199
225
  end
200
226
  end
201
227
 
202
- # def register
203
-
204
- public
205
228
  def filter(event)
206
229
  @logger.debug? && @logger.debug("Date filter: received event", :type => event["type"])
207
-
230
+
208
231
  @parsers.each do |field, fieldparsers|
209
232
  @logger.debug? && @logger.debug("Date filter looking for field",
210
233
  :type => event["type"], :field => field)
@@ -221,7 +244,11 @@ class LogStash::Filters::Date < LogStash::Filters::Base
221
244
  fieldparsers.each do |parserconfig|
222
245
  parserconfig[:parser].each do |parser|
223
246
  begin
224
- epochmillis = parser.call(value)
247
+ if @sprintf_timezone
248
+ epochmillis = parser.call(value, event.sprintf(@timezone))
249
+ else
250
+ epochmillis = parser.call(value)
251
+ end
225
252
  success = true
226
253
  break # success
227
254
  rescue StandardError, JavaException => e
@@ -247,13 +274,12 @@ class LogStash::Filters::Date < LogStash::Filters::Base
247
274
  # Tag this event if we can't parse it. We can use this later to
248
275
  # reparse+reindex logs if we improve the patterns given.
249
276
  @tag_on_failure.each do |tag|
250
- event["tags"] ||= []
251
- event["tags"] << tag unless event["tags"].include?(tag)
277
+ event.tag(tag)
252
278
  end
253
- end # begin
254
- end # fieldvalue.each
255
- end # @parsers.each
279
+ end
280
+ end
281
+ end
256
282
 
257
283
  return event
258
- end # def filter
259
- end # class LogStash::Filters::Date
284
+ end
285
+ end
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
 
3
3
  s.name = 'logstash-filter-date'
4
- s.version = '2.0.2'
4
+ s.version = '2.1.0'
5
5
  s.licenses = ['Apache License (2.0)']
6
6
  s.summary = "The date filter is used for parsing dates from fields, and then using that date or timestamp as the logstash timestamp for the event."
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/plugin install gemname. This gem is not a stand-alone program"
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  require "logstash/devutils/rspec/spec_helper"
2
4
  require "logstash/filters/date"
3
5
 
@@ -48,15 +50,18 @@ RUBY_ENGINE == "jruby" and describe LogStash::Filters::Date do
48
50
  "2001-09-05T16:36:36.123+0700" => "2001-09-05T09:36:36.123Z",
49
51
  "2001-11-06T20:45:45.123-0000" => "2001-11-06T20:45:45.123Z",
50
52
  "2001-12-07T23:54:54.123Z" => "2001-12-07T23:54:54.123Z",
53
+ "2001-12-07T23:54:54,123Z" => "2001-12-07T23:54:54.123Z",
51
54
 
52
55
  #Almost ISO8601 support, with timezone
53
56
 
54
57
  "2001-11-06 20:45:45.123-0000" => "2001-11-06T20:45:45.123Z",
55
58
  "2001-12-07 23:54:54.123Z" => "2001-12-07T23:54:54.123Z",
59
+ "2001-12-07 23:54:54,123Z" => "2001-12-07T23:54:54.123Z",
56
60
 
57
61
  #Almost ISO8601 support, without timezone
58
62
 
59
63
  "2001-11-06 20:45:45.123" => "2001-11-06T20:45:45.123Z",
64
+ "2001-11-06 20:45:45,123" => "2001-11-06T20:45:45.123Z",
60
65
 
61
66
  }
62
67
 
@@ -357,6 +362,30 @@ RUBY_ENGINE == "jruby" and describe LogStash::Filters::Date do
357
362
  end # times.each
358
363
  end
359
364
 
365
+ describe "parsing with timezone from event" do
366
+ config <<-CONFIG
367
+ filter {
368
+ date {
369
+ match => ["mydate", "yyyy MMM dd HH:mm:ss"]
370
+ locale => "en"
371
+ timezone => "%{mytz}"
372
+ }
373
+ }
374
+ CONFIG
375
+
376
+ require 'java'
377
+ times = {
378
+ "2013 Nov 24 01:29:01" => "2013-11-24T09:29:01.000Z",
379
+ "2013 Jun 24 01:29:01" => "2013-06-24T08:29:01.000Z",
380
+ }
381
+ times.each do |input, output|
382
+ sample("mydate" => input, "mytz" => "America/Los_Angeles") do
383
+ insist { subject["mydate"] } == input
384
+ insist { subject["@timestamp"].time } == Time.iso8601(output).utc
385
+ end
386
+ end # times.each
387
+ end
388
+
360
389
  describe "LOGSTASH-34 - Default year should be this year" do
361
390
  config <<-CONFIG
362
391
  filter {
@@ -372,6 +401,42 @@ RUBY_ENGINE == "jruby" and describe LogStash::Filters::Date do
372
401
  end
373
402
  end
374
403
 
404
+ describe "fill last year if december events arrive in january" do
405
+ config <<-CONFIG
406
+ filter {
407
+ date {
408
+ match => [ "message", "MMM dd HH:mm:ss" ]
409
+ locale => "en"
410
+ timezone => "UTC"
411
+ }
412
+ }
413
+ CONFIG
414
+
415
+ sample "Dec 31 23:59:00" do
416
+ logstash_time = Time.utc(2014,1,1,00,30,50)
417
+ expect(Time).to receive(:now).at_most(:twice).and_return(logstash_time)
418
+ insist { subject["@timestamp"].year } == 2013
419
+ end
420
+ end
421
+
422
+ describe "fill next year if january events arrive in december" do
423
+ config <<-CONFIG
424
+ filter {
425
+ date {
426
+ match => [ "message", "MMM dd HH:mm:ss" ]
427
+ locale => "en"
428
+ timezone => "UTC"
429
+ }
430
+ }
431
+ CONFIG
432
+
433
+ sample "Jan 01 01:00:00" do
434
+ logstash_time = Time.utc(2013,12,31,23,59,50)
435
+ expect(Time).to receive(:now).at_most(:twice).and_return(logstash_time)
436
+ insist { subject["@timestamp"].year } == 2014
437
+ end
438
+ end
439
+
375
440
  describe "Supporting locale only" do
376
441
  config <<-CONFIG
377
442
  filter {
metadata CHANGED
@@ -1,22 +1,22 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstash-filter-date
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.2
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Elastic
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-10-14 00:00:00.000000000 Z
11
+ date: 2015-12-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
15
15
  requirements:
16
- - - '>='
16
+ - - ">="
17
17
  - !ruby/object:Gem::Version
18
18
  version: 2.0.0.beta2
19
- - - <
19
+ - - "<"
20
20
  - !ruby/object:Gem::Version
21
21
  version: 3.0.0
22
22
  name: logstash-core
@@ -24,16 +24,16 @@ dependencies:
24
24
  type: :runtime
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
- - - '>='
27
+ - - ">="
28
28
  - !ruby/object:Gem::Version
29
29
  version: 2.0.0.beta2
30
- - - <
30
+ - - "<"
31
31
  - !ruby/object:Gem::Version
32
32
  version: 3.0.0
33
33
  - !ruby/object:Gem::Dependency
34
34
  requirement: !ruby/object:Gem::Requirement
35
35
  requirements:
36
- - - '>='
36
+ - - ">="
37
37
  - !ruby/object:Gem::Version
38
38
  version: '0'
39
39
  name: logstash-input-generator
@@ -41,13 +41,13 @@ dependencies:
41
41
  type: :runtime
42
42
  version_requirements: !ruby/object:Gem::Requirement
43
43
  requirements:
44
- - - '>='
44
+ - - ">="
45
45
  - !ruby/object:Gem::Version
46
46
  version: '0'
47
47
  - !ruby/object:Gem::Dependency
48
48
  requirement: !ruby/object:Gem::Requirement
49
49
  requirements:
50
- - - '>='
50
+ - - ">="
51
51
  - !ruby/object:Gem::Version
52
52
  version: '0'
53
53
  name: logstash-codec-json
@@ -55,13 +55,13 @@ dependencies:
55
55
  type: :runtime
56
56
  version_requirements: !ruby/object:Gem::Requirement
57
57
  requirements:
58
- - - '>='
58
+ - - ">="
59
59
  - !ruby/object:Gem::Version
60
60
  version: '0'
61
61
  - !ruby/object:Gem::Dependency
62
62
  requirement: !ruby/object:Gem::Requirement
63
63
  requirements:
64
- - - '>='
64
+ - - ">="
65
65
  - !ruby/object:Gem::Version
66
66
  version: '0'
67
67
  name: logstash-output-null
@@ -69,13 +69,13 @@ dependencies:
69
69
  type: :runtime
70
70
  version_requirements: !ruby/object:Gem::Requirement
71
71
  requirements:
72
- - - '>='
72
+ - - ">="
73
73
  - !ruby/object:Gem::Version
74
74
  version: '0'
75
75
  - !ruby/object:Gem::Dependency
76
76
  requirement: !ruby/object:Gem::Requirement
77
77
  requirements:
78
- - - '>='
78
+ - - ">="
79
79
  - !ruby/object:Gem::Version
80
80
  version: '0'
81
81
  name: logstash-devutils
@@ -83,7 +83,7 @@ dependencies:
83
83
  type: :development
84
84
  version_requirements: !ruby/object:Gem::Requirement
85
85
  requirements:
86
- - - '>='
86
+ - - ">="
87
87
  - !ruby/object:Gem::Version
88
88
  version: '0'
89
89
  description: This gem is a logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/plugin install gemname. This gem is not a stand-alone program
@@ -113,12 +113,12 @@ require_paths:
113
113
  - lib
114
114
  required_ruby_version: !ruby/object:Gem::Requirement
115
115
  requirements:
116
- - - '>='
116
+ - - ">="
117
117
  - !ruby/object:Gem::Version
118
118
  version: '0'
119
119
  required_rubygems_version: !ruby/object:Gem::Requirement
120
120
  requirements:
121
- - - '>='
121
+ - - ">="
122
122
  - !ruby/object:Gem::Version
123
123
  version: '0'
124
124
  requirements: []