@@ -2,9 +2,10 @@ use super::Decoder;
2
2
use crate :: flowgger:: config:: Config ;
3
3
use crate :: flowgger:: record:: Record ;
4
4
use crate :: flowgger:: utils;
5
- use chrono:: { Datelike , NaiveDateTime , TimeZone , Utc } ;
6
- use chrono_tz:: Tz ;
7
5
use std:: io:: { stderr, Write } ;
6
+ use time:: { format_description, OffsetDateTime , PrimitiveDateTime } ;
7
+ use time_tz:: timezones:: get_by_name;
8
+ use time_tz:: PrimitiveDateTimeExt ;
8
9
9
10
#[ derive( Clone ) ]
10
11
pub struct RFC3164Decoder { }
@@ -169,49 +170,60 @@ fn parse_date<'a>(
169
170
// If no year in the string, parse manually add the current year
170
171
if has_year {
171
172
idx = 4 ;
172
- ts_str = ts_tokens[ 0 ..idx] . join ( " " ) ;
173
+ ts_str = match ts_tokens. get ( 0 ..idx) {
174
+ Some ( str) => str. join ( " " ) ,
175
+ None => return Err ( "Unable to parse RFC3164 date with year" ) ,
176
+ } ;
173
177
} else {
174
178
idx = 3 ;
175
- let current_year = Utc :: now ( ) . year ( ) ;
176
- ts_str = format ! ( "{} {}" , current_year, ts_tokens[ 0 ..idx] . join( " " ) ) ;
179
+ let current_year = OffsetDateTime :: now_utc ( ) . year ( ) ;
180
+ ts_str = match ts_tokens. get ( 0 ..idx) {
181
+ Some ( str) => format ! ( "{} {}" , current_year, str . join( " " ) ) ,
182
+ None => return Err ( "Unable to parse RFC3164 date without year" ) ,
183
+ } ;
177
184
}
178
185
179
- match NaiveDateTime :: parse_from_str ( & ts_str, "%Y %b %d %H:%M:%S" ) {
180
- Ok ( naive_dt) => {
186
+ let format_item = format_description:: parse (
187
+ "[year] [month repr:short] [day padding:none] [hour]:[minute]:[second]" ,
188
+ )
189
+ . unwrap ( ) ;
190
+ match PrimitiveDateTime :: parse ( & ts_str, & format_item) {
191
+ Ok ( primitive_date) => {
181
192
// See if the next token is a timezone
182
- let mut ts = 0.0 ;
183
- let tz_res: Result < Tz , String > = if ts_tokens. len ( ) > idx {
184
- ts_tokens[ idx] . parse ( )
193
+ let ts : f64 ;
194
+ let tz_res = if ts_tokens. len ( ) > idx {
195
+ get_by_name ( ts_tokens[ idx] ) . ok_or ( "No timezone" . to_string ( ) )
185
196
} else {
186
197
Err ( "No timezone" . to_string ( ) )
187
198
} ;
199
+
188
200
if let Ok ( tz) = tz_res {
189
- let dt = tz. from_local_datetime ( & naive_dt) . single ( ) ;
190
- if dt. is_some ( ) {
191
- ts = utils:: PreciseTimestamp :: from_datetime_tz ( dt. unwrap ( ) ) . as_f64 ( ) ;
192
- idx += 1 ;
193
- }
201
+ let dt = primitive_date. assume_timezone ( tz) ;
202
+ ts = utils:: PreciseTimestamp :: from_offset_datetime ( dt) . as_f64 ( ) ;
203
+ idx += 1 ;
194
204
}
195
205
// No timezome, give a timestamp without tz
196
206
else {
197
- ts = utils:: PreciseTimestamp :: from_naive_datetime ( naive_dt ) . as_f64 ( ) ;
207
+ ts = utils:: PreciseTimestamp :: from_primitive_datetime ( primitive_date ) . as_f64 ( ) ;
198
208
}
199
209
Ok ( ( ts, ts_tokens[ idx..] . to_vec ( ) ) )
200
210
}
201
- Err ( _err ) => Err ( "Unable to parse date" ) ,
211
+ Err ( _ ) => Err ( "Unable to parse the date in RFC3164 decoder " ) ,
202
212
}
203
213
}
204
214
205
215
#[ cfg( test) ]
206
216
use crate :: flowgger:: utils:: test_utils:: rfc_test_utils:: {
207
217
ts_from_date_time, ts_from_partial_date_time,
208
218
} ;
219
+ #[ cfg( test) ]
220
+ use time:: Month ;
209
221
210
222
#[ test]
211
223
fn test_rfc3164_decode_nopri ( ) {
212
224
let msg = r#"Aug 6 11:15:24 testhostname appname 69 42 [origin@123 software="te\st sc\"ript" swVersion="0.0.1"] test message"# ;
213
225
let cfg = Config :: from_string ( "[input]\n [input.ltsv_schema]\n format = \" rfc3164\" \n " ) . unwrap ( ) ;
214
- let expected_ts = ts_from_partial_date_time ( 8 , 6 , 11 , 15 , 24 ) ;
226
+ let expected_ts = ts_from_partial_date_time ( Month :: August , 6 , 11 , 15 , 24 ) ;
215
227
216
228
let decoder = RFC3164Decoder :: new ( & cfg) ;
217
229
let res = decoder. decode ( msg) . unwrap ( ) ;
@@ -231,7 +243,7 @@ fn test_rfc3164_decode_nopri() {
231
243
fn test_rfc3164_decode_with_pri ( ) {
232
244
let msg = r#"<13>Aug 6 11:15:24 testhostname appname 69 42 [origin@123 software="te\st sc\"ript" swVersion="0.0.1"] test message"# ;
233
245
let cfg = Config :: from_string ( "[input]\n [input.ltsv_schema]\n format = \" rfc3164\" \n " ) . unwrap ( ) ;
234
- let expected_ts = ts_from_partial_date_time ( 8 , 6 , 11 , 15 , 24 ) ;
246
+ let expected_ts = ts_from_partial_date_time ( Month :: August , 6 , 11 , 15 , 24 ) ;
235
247
236
248
let decoder = RFC3164Decoder :: new ( & cfg) ;
237
249
let res = decoder. decode ( msg) . unwrap ( ) ;
@@ -251,7 +263,7 @@ fn test_rfc3164_decode_with_pri() {
251
263
fn test_rfc3164_decode_with_pri_year ( ) {
252
264
let msg = r#"<13>2020 Aug 6 11:15:24 testhostname appname 69 42 [origin@123 software="te\st sc\"ript" swVersion="0.0.1"] test message"# ;
253
265
let cfg = Config :: from_string ( "[input]\n [input.ltsv_schema]\n format = \" rfc3164\" \n " ) . unwrap ( ) ;
254
- let expected_ts = ts_from_date_time ( 2020 , 8 , 6 , 11 , 15 , 24 , 0 ) ;
266
+ let expected_ts = ts_from_date_time ( 2020 , Month :: August , 6 , 11 , 15 , 24 , 0 ) ;
255
267
256
268
let decoder = RFC3164Decoder :: new ( & cfg) ;
257
269
let res = decoder. decode ( msg) . unwrap ( ) ;
@@ -269,9 +281,9 @@ fn test_rfc3164_decode_with_pri_year() {
269
281
270
282
#[ test]
271
283
fn test_rfc3164_decode_with_pri_year_tz ( ) {
272
- let msg = r#"<13>2020 Aug 6 11 :15:24 UTC testhostname appname 69 42 [origin@123 software="te\st sc\"ript" swVersion="0.0.1"] test message"# ;
284
+ let msg = r#"<13>2020 Aug 6 05 :15:24 America/Sao_Paulo testhostname appname 69 42 [origin@123 software="te\st sc\"ript" swVersion="0.0.1"] test message"# ;
273
285
let cfg = Config :: from_string ( "[input]\n [input.ltsv_schema]\n format = \" rfc3164\" \n " ) . unwrap ( ) ;
274
- let expected_ts = ts_from_date_time ( 2020 , 8 , 6 , 11 , 15 , 24 , 0 ) ;
286
+ let expected_ts = ts_from_date_time ( 2020 , Month :: August , 6 , 08 , 15 , 24 , 0 ) ;
275
287
276
288
let decoder = RFC3164Decoder :: new ( & cfg) ;
277
289
let res = decoder. decode ( msg) . unwrap ( ) ;
@@ -291,7 +303,7 @@ fn test_rfc3164_decode_with_pri_year_tz() {
291
303
fn test_rfc3164_decode_tz_no_year ( ) {
292
304
let msg = r#"Aug 6 11:15:24 UTC testhostname appname 69 42 [origin@123 software="te\st sc\"ript" swVersion="0.0.1"] test message"# ;
293
305
let cfg = Config :: from_string ( "[input]\n [input.ltsv_schema]\n format = \" rfc3164\" \n " ) . unwrap ( ) ;
294
- let expected_ts = ts_from_partial_date_time ( 8 , 6 , 11 , 15 , 24 ) ;
306
+ let expected_ts = ts_from_partial_date_time ( Month :: August , 6 , 11 , 15 , 24 ) ;
295
307
296
308
let decoder = RFC3164Decoder :: new ( & cfg) ;
297
309
let res = decoder. decode ( msg) . unwrap ( ) ;
@@ -329,11 +341,9 @@ fn test_rfc3164_decode_invalid_date() {
329
341
330
342
#[ test]
331
343
fn test_rfc3164_decode_custom_with_year ( ) {
332
- // let msg = r#"testhostname: 2019 Mar 27 12:09:39 UTC: appname: test message"#;
333
344
let msg = r#"testhostname: 2020 Aug 6 11:15:24 UTC: appname 69 42 some test message"# ;
334
345
let cfg = Config :: from_string ( "[input]\n [input.ltsv_schema]\n format = \" rfc3164\" \n " ) . unwrap ( ) ;
335
- // let expected_ts = ts_from_date_time(2019, 3, 27, 12, 9, 39, 0);
336
- let expected_ts = ts_from_date_time ( 2020 , 8 , 6 , 11 , 15 , 24 , 0 ) ;
346
+ let expected_ts = ts_from_date_time ( 2020 , Month :: August , 6 , 11 , 15 , 24 , 0 ) ;
337
347
338
348
let decoder = RFC3164Decoder :: new ( & cfg) ;
339
349
let res = decoder. decode ( msg) . unwrap ( ) ;
@@ -356,7 +366,7 @@ fn test_rfc3164_decode_custom_with_year() {
356
366
fn test_rfc3164_decode_custom_with_year_notz ( ) {
357
367
let msg = r#"testhostname: 2019 Mar 27 12:09:39: appname: a test message"# ;
358
368
let cfg = Config :: from_string ( "[input]\n [input.ltsv_schema]\n format = \" rfc3164\" \n " ) . unwrap ( ) ;
359
- let expected_ts = ts_from_date_time ( 2019 , 3 , 27 , 12 , 9 , 39 , 0 ) ;
369
+ let expected_ts = ts_from_date_time ( 2019 , Month :: March , 27 , 12 , 9 , 39 , 0 ) ;
360
370
361
371
let decoder = RFC3164Decoder :: new ( & cfg) ;
362
372
let res = decoder. decode ( msg) . unwrap ( ) ;
@@ -376,7 +386,7 @@ fn test_rfc3164_decode_custom_with_year_notz() {
376
386
fn test_rfc3164_decode_custom_with_pri ( ) {
377
387
let msg = r#"<13>testhostname: 2019 Mar 27 12:09:39 UTC: appname: test message"# ;
378
388
let cfg = Config :: from_string ( "[input]\n [input.ltsv_schema]\n format = \" rfc3164\" \n " ) . unwrap ( ) ;
379
- let expected_ts = ts_from_date_time ( 2019 , 3 , 27 , 12 , 9 , 39 , 0 ) ;
389
+ let expected_ts = ts_from_date_time ( 2019 , Month :: March , 27 , 12 , 9 , 39 , 0 ) ;
380
390
381
391
let decoder = RFC3164Decoder :: new ( & cfg) ;
382
392
let res = decoder. decode ( msg) . unwrap ( ) ;
@@ -396,7 +406,7 @@ fn test_rfc3164_decode_custom_with_pri() {
396
406
fn test_rfc3164_decode_custom_trimed ( ) {
397
407
let msg = "<13>testhostname: 2019 Mar 27 12:09:39 UTC: appname: test message \n " ;
398
408
let cfg = Config :: from_string ( "[input]\n [input.ltsv_schema]\n format = \" rfc3164\" \n " ) . unwrap ( ) ;
399
- let expected_ts = ts_from_date_time ( 2019 , 3 , 27 , 12 , 9 , 39 , 0 ) ;
409
+ let expected_ts = ts_from_date_time ( 2019 , Month :: March , 27 , 12 , 9 , 39 , 0 ) ;
400
410
401
411
let decoder = RFC3164Decoder :: new ( & cfg) ;
402
412
let res = decoder. decode ( msg) . unwrap ( ) ;
0 commit comments