logstash-filter-date 2.0.2 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
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: []