From 7a8cf00a1c919eac64a45f064ad26554de280934 Mon Sep 17 00:00:00 2001 From: Oleg Smirnov Date: Tue, 28 Jun 2022 17:44:05 +0300 Subject: [PATCH] [TH2-3724] Parameter for setting time zone for log timestamps (#30) * [TH2-3724] Added parameter to define time zone for timestamp in log file * [TH2-3724] Update readme and version * [TH2-3724] Update README.md Co-authored-by: Nikita Shaposhnikov Co-authored-by: Nikita Shaposhnikov --- README.md | 8 +++++++- gradle.properties | 2 +- .../java/com/exactpro/th2/readlog/LogData.java | 11 +++++++++++ .../com/exactpro/th2/readlog/RegexLogParser.java | 1 + .../th2/readlog/cfg/AliasConfiguration.java | 16 +++++++++++++++- .../th2/readlog/impl/RegexpContentParser.java | 5 ++++- 6 files changed, 39 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index fd371cc..0432076 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Log Reader User Manual 3.3.3 +# Log Reader User Manual 3.4.0 ## Document Information @@ -43,6 +43,7 @@ spec: pathFilter: "fileC.*\\.log" timestampRegexp: "^202.+?(?= QUICK)" timestampFormat: "yyyy-MM-dd HH:mm:ss" + timestampZone: UTC D: regexp: ".*" pathFilter: "fileC.*\\.log" @@ -102,6 +103,7 @@ spec: + If the _timestampFormat_ specified the timestamp will be used as a message timestamp. Otherwise, the message's timestamp will be generated. + timestampFormat - the format for the timestamp extract from the log's line. **Works only with specified _timestampRegexp_ parameter**. If _timestampFormat_ is specified the timestamp extract with _timestampRegexp_ will be parsed using this format and used as a message's timestamp. + + timestampZone - the zone which should be used to process the timestamp from the log file + joinGroups - enables joining groups into a message in CSV format. Can be used to extract generic data from the log. Disabled by default. + groupsJoinDelimiter - the delimiter that will be used to join groups from the _regexp_ parameter. **Works only if _joinGroups_ is enabled**. The default value is `,`. + headersFormat - the headers' definition. The reader uses the keys as headers. The value to the key will be converted to a value for each match in the current line. @@ -168,6 +170,10 @@ Output: 8=FIXT.1.1\u00019=66\u000135=A\u000134=1\u000149=NFT2_FIX1\u000156=FGW\u ## Changes +### 3.4.0 + ++ Add parameter `timestampZone` which should be used to process the timestamp from the log file + ### 3.3.3 + Update common version from `3.16.1` to `3.37.1` diff --git a/gradle.properties b/gradle.properties index 17084fb..3ca4a3b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1 @@ -release_version=3.3.3 \ No newline at end of file +release_version=3.4.0 \ No newline at end of file diff --git a/src/main/java/com/exactpro/th2/readlog/LogData.java b/src/main/java/com/exactpro/th2/readlog/LogData.java index c06ee3e..ebe362f 100644 --- a/src/main/java/com/exactpro/th2/readlog/LogData.java +++ b/src/main/java/com/exactpro/th2/readlog/LogData.java @@ -16,6 +16,7 @@ package com.exactpro.th2.readlog; import java.time.LocalDateTime; +import java.time.ZoneId; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -25,6 +26,8 @@ final public class LogData { private String rawTimestamp; private LocalDateTime parsedTimestamp; + private ZoneId timestampZone; + public void addBody(String item) { initIfNeeded(); body.add(item); @@ -50,6 +53,14 @@ public void setParsedTimestamp(LocalDateTime localDateTime) { this.parsedTimestamp = localDateTime; } + public ZoneId getTimestampZone() { + return timestampZone; + } + + public void setTimestampZone(ZoneId timestampZone) { + this.timestampZone = timestampZone; + } + private void initIfNeeded() { if (body == null) { body = new ArrayList<>(); diff --git a/src/main/java/com/exactpro/th2/readlog/RegexLogParser.java b/src/main/java/com/exactpro/th2/readlog/RegexLogParser.java index e4ff06d..0a077b2 100644 --- a/src/main/java/com/exactpro/th2/readlog/RegexLogParser.java +++ b/src/main/java/com/exactpro/th2/readlog/RegexLogParser.java @@ -97,6 +97,7 @@ public LogData parse(StreamId streamId, String raw) { DateTimeFormatter timestampFormat = configuration.getTimestampFormat(); if (timestampFormat != null) { parseTimestamp(timestampFormat, resultData); + resultData.setTimestampZone(configuration.getTimestampZone()); } return resultData; diff --git a/src/main/java/com/exactpro/th2/readlog/cfg/AliasConfiguration.java b/src/main/java/com/exactpro/th2/readlog/cfg/AliasConfiguration.java index 17cd38f..a2212cc 100644 --- a/src/main/java/com/exactpro/th2/readlog/cfg/AliasConfiguration.java +++ b/src/main/java/com/exactpro/th2/readlog/cfg/AliasConfiguration.java @@ -19,6 +19,8 @@ import com.exactpro.th2.common.grpc.Direction; import com.fasterxml.jackson.annotation.JsonPropertyDescription; +import java.time.ZoneId; +import java.time.ZoneOffset; import java.time.format.DateTimeFormatter; import java.util.Collections; import java.util.EnumMap; @@ -54,6 +56,10 @@ public class AliasConfiguration { private Map headersFormat = Collections.emptyMap(); + @JsonPropertyDescription("Defines time zone that should be used to parse the timestamp from the log file." + + "It not set the time zone from the local machine will be taken") + private ZoneId timestampZone; + @JsonCreator public AliasConfiguration( @JsonProperty(value = "regexp", required = true) String regexp, @@ -73,7 +79,7 @@ public AliasConfiguration( Pattern.compile(Objects.requireNonNull(directionRegexp, "'Direction regexp' parameter")))); } directionToPattern = Collections.unmodifiableMap(patternByDirection); - this.timestampRegexp = timestampRegexp != null ? Pattern.compile(timestampRegexp) : null; + this.timestampRegexp = timestampRegexp == null ? null : Pattern.compile(timestampRegexp); this.timestampFormat = StringUtils.isEmpty(timestampFormat) ? null : DateTimeFormatter.ofPattern(timestampFormat); @@ -135,4 +141,12 @@ public Map getHeadersFormat() { public void setHeadersFormat(Map headersFormat) { this.headersFormat = new TreeMap<>(headersFormat); } + + public ZoneId getTimestampZone() { + return timestampZone; + } + + public void setTimestampZone(ZoneOffset timestampZone) { + this.timestampZone = timestampZone; + } } diff --git a/src/main/java/com/exactpro/th2/readlog/impl/RegexpContentParser.java b/src/main/java/com/exactpro/th2/readlog/impl/RegexpContentParser.java index 6f974d1..a5f4a9e 100644 --- a/src/main/java/com/exactpro/th2/readlog/impl/RegexpContentParser.java +++ b/src/main/java/com/exactpro/th2/readlog/impl/RegexpContentParser.java @@ -60,7 +60,10 @@ protected List lineToMessages(@Nonnull StreamId streamId, @N private void setupMetadata(RawMessageMetadata.Builder builder, LogData logData) { if (logData.getParsedTimestamp() != null) { - ZoneOffset currentOffsetForMyZone = ZoneId.systemDefault().getRules().getOffset(Instant.now()); + ZoneOffset currentOffsetForMyZone = Objects.requireNonNullElse( + logData.getTimestampZone(), + ZoneId.systemDefault() + ).getRules().getOffset(Instant.now()); builder.setTimestamp(MessageUtils.toTimestamp(logData.getParsedTimestamp(),currentOffsetForMyZone)); } if (logData.getRawTimestamp() != null) {