Skip to content

Commit 1b7fe94

Browse files
committed
add STRICT shortcut for ISO8601 date pattern, fixes LOGBACK-262
Signed-off-by: Ceki Gulcu <[email protected]>
1 parent 94b67db commit 1b7fe94

File tree

3 files changed

+62
-54
lines changed

3 files changed

+62
-54
lines changed

logback-classic/src/main/java/ch/qos/logback/classic/pattern/DateConverter.java

+5
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ public class DateConverter extends ClassicConverter {
3030
public void start() {
3131

3232
String datePattern = getFirstOption();
33+
3334
if (datePattern == null) {
3435
datePattern = CoreConstants.ISO8601_PATTERN;
3536
}
@@ -38,6 +39,10 @@ public void start() {
3839
datePattern = CoreConstants.ISO8601_PATTERN;
3940
}
4041

42+
if (datePattern.equals(CoreConstants.STRICT_STR)) {
43+
datePattern = CoreConstants.STRICT_ISO8601_PATTERN;
44+
}
45+
4146
List<String> optionList = getOptionList();
4247
ZoneId zoneId = null;
4348
// if the option list contains a TZ option, then set it.

logback-classic/src/test/java/ch/qos/logback/classic/pattern/ConverterTest.java

+44-54
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,7 @@
1313
*/
1414
package ch.qos.logback.classic.pattern;
1515

16-
import ch.qos.logback.classic.ClassicConstants;
17-
import ch.qos.logback.classic.ClassicTestConstants;
18-
import ch.qos.logback.classic.Level;
19-
import ch.qos.logback.classic.Logger;
20-
import ch.qos.logback.classic.LoggerContext;
16+
import ch.qos.logback.classic.*;
2117
import ch.qos.logback.classic.spi.ILoggingEvent;
2218
import ch.qos.logback.classic.spi.LoggingEvent;
2319
import ch.qos.logback.classic.util.LogbackMDCAdapter;
@@ -31,21 +27,20 @@
3127
import org.junit.jupiter.api.Test;
3228
import org.slf4j.MarkerFactory;
3329

30+
import java.time.Instant;
3431
import java.util.ArrayList;
3532
import java.util.List;
3633
import java.util.regex.Pattern;
3734

38-
import static org.junit.jupiter.api.Assertions.assertEquals;
39-
import static org.junit.jupiter.api.Assertions.assertTrue;
40-
import static org.junit.jupiter.api.Assertions.fail;
35+
import static org.junit.jupiter.api.Assertions.*;
4136

4237
public class ConverterTest {
4338

4439
LoggerContext loggerContext = new LoggerContext();
4540
LogbackMDCAdapter logbackMDCAdapter = new LogbackMDCAdapter();
4641
Logger logger = loggerContext.getLogger(ConverterTest.class);
4742
LoggingEvent le;
48-
List<String> optionList = new ArrayList<String>();
43+
//List<String> optionList = new ArrayList<String>();
4944

5045
// The LoggingEvent is massaged with an FCQN of FormattingConverter. This
5146
// forces the returned caller information to match the caller stack for
@@ -77,7 +72,7 @@ public void testLineOfCaller() {
7772
StringBuilder buf = new StringBuilder();
7873
converter.write(buf, le);
7974
// the number below should be the line number of the previous line
80-
assertEquals("78", buf.toString());
75+
assertEquals("73", buf.toString());
8176
}
8277
}
8378

@@ -134,8 +129,7 @@ public void testException() {
134129

135130
{
136131
DynamicConverter<ILoggingEvent> converter = new ThrowableProxyConverter();
137-
this.optionList.add("3");
138-
converter.setOptionList(this.optionList);
132+
converter.setOptionList(List.of("3"));
139133
StringBuilder buf = new StringBuilder();
140134
converter.write(buf, le);
141135
}
@@ -152,8 +146,7 @@ public void testLogger() {
152146

153147
{
154148
ClassicConverter converter = new LoggerConverter();
155-
this.optionList.add("20");
156-
converter.setOptionList(this.optionList);
149+
converter.setOptionList(List.of("20"));
157150
converter.start();
158151
StringBuilder buf = new StringBuilder();
159152
converter.write(buf, le);
@@ -162,9 +155,7 @@ public void testLogger() {
162155

163156
{
164157
DynamicConverter<ILoggingEvent> converter = new LoggerConverter();
165-
this.optionList.clear();
166-
this.optionList.add("0");
167-
converter.setOptionList(this.optionList);
158+
converter.setOptionList(List.of("0"));
168159
converter.start();
169160
StringBuilder buf = new StringBuilder();
170161
converter.write(buf, le);
@@ -175,8 +166,7 @@ public void testLogger() {
175166
@Test
176167
public void testVeryLongLoggerName() {
177168
ClassicConverter converter = new LoggerConverter();
178-
this.optionList.add("5");
179-
converter.setOptionList(this.optionList);
169+
converter.setOptionList(List.of("5"));
180170
converter.start();
181171
StringBuilder buf = new StringBuilder();
182172

@@ -239,9 +229,7 @@ public void testCallerData() {
239229

240230
{
241231
DynamicConverter<ILoggingEvent> converter = new CallerDataConverter();
242-
this.optionList.add("2");
243-
this.optionList.add("XXX");
244-
converter.setOptionList(this.optionList);
232+
converter.setOptionList(List.of("2", "XXX"));
245233
converter.start();
246234

247235
StringBuilder buf = new StringBuilder();
@@ -255,11 +243,7 @@ public void testCallerData() {
255243

256244
{
257245
DynamicConverter<ILoggingEvent> converter = new CallerDataConverter();
258-
this.optionList.clear();
259-
this.optionList.add("2");
260-
this.optionList.add("XXX");
261-
this.optionList.add("*");
262-
converter.setOptionList(this.optionList);
246+
converter.setOptionList(List.of("2", "XXX", "*"));
263247
converter.start();
264248

265249
StringBuilder buf = new StringBuilder();
@@ -272,11 +256,7 @@ public void testCallerData() {
272256
}
273257
{
274258
DynamicConverter<ILoggingEvent> converter = new CallerDataConverter();
275-
this.optionList.clear();
276-
this.optionList.add("2");
277-
this.optionList.add("XXX");
278-
this.optionList.add("+");
279-
converter.setOptionList(this.optionList);
259+
converter.setOptionList(List.of("2", "XXX", "*"));
280260
converter.start();
281261

282262
StringBuilder buf = new StringBuilder();
@@ -290,11 +270,7 @@ public void testCallerData() {
290270

291271
{
292272
DynamicConverter<ILoggingEvent> converter = new CallerDataConverter();
293-
this.optionList.clear();
294-
this.optionList.add("2");
295-
this.optionList.add("XXX");
296-
this.optionList.add("*");
297-
converter.setOptionList(this.optionList);
273+
converter.setOptionList(List.of("2", "XXX", "*"));
298274
converter.start();
299275

300276
StringBuilder buf = new StringBuilder();
@@ -307,16 +283,10 @@ public void testCallerData() {
307283

308284
{
309285
DynamicConverter<ILoggingEvent> converter = new CallerDataConverter();
310-
this.optionList.clear();
311-
286+
312287
boolean jdk18 = EnvUtil.isJDK18OrHigher();
313288
// jdk 18EA creates a different stack trace
314-
if(jdk18) {
315-
this.optionList.add("2..3");
316-
} else {
317-
this.optionList.add("4..5");
318-
}
319-
converter.setOptionList(this.optionList);
289+
converter.setOptionList(jdk18 ? List.of("2..3") : List.of("4..5"));
320290
converter.start();
321291

322292
StringBuilder buf = new StringBuilder();
@@ -352,9 +322,7 @@ public void testRelativeTime() throws Exception {
352322
@Test
353323
public void testSyslogStart() throws Exception {
354324
DynamicConverter<ILoggingEvent> converter = new SyslogStartConverter();
355-
this.optionList.clear();
356-
this.optionList.add("MAIL");
357-
converter.setOptionList(this.optionList);
325+
converter.setOptionList(List.of("MAIL"));
358326
converter.start();
359327

360328
ILoggingEvent event = makeLoggingEvent(null);
@@ -371,9 +339,7 @@ public void testMDCConverter() throws Exception {
371339
logbackMDCAdapter.clear();
372340
logbackMDCAdapter.put("someKey", "someValue");
373341
MDCConverter converter = new MDCConverter();
374-
this.optionList.clear();
375-
this.optionList.add("someKey");
376-
converter.setOptionList(optionList);
342+
converter.setOptionList(List.of("someKey"));
377343
converter.start();
378344

379345
ILoggingEvent event = makeLoggingEvent(null);
@@ -401,9 +367,7 @@ public void contextNameConverter() {
401367
public void contextProperty() {
402368
PropertyConverter converter = new PropertyConverter();
403369
converter.setContext(loggerContext);
404-
List<String> ol = new ArrayList<String>();
405-
ol.add("k");
406-
converter.setOptionList(ol);
370+
converter.setOptionList(List.of("k"));
407371
converter.start();
408372
loggerContext.setName("aValue");
409373
loggerContext.putProperty("k", "v");
@@ -427,4 +391,30 @@ public void testSequenceNumber() {
427391
assertEquals("123", converter.convert(event));
428392
StatusPrinter.print(loggerContext);
429393
}
394+
395+
@Test
396+
void dateConverterTest() {
397+
dateConverterChecker(List.of("STRICT", "GMT"), "2024-08-14T15:29:25,956");
398+
dateConverterChecker(List.of("ISO8601", "GMT"), "2024-08-14 15:29:25,956");
399+
dateConverterChecker(List.of("ISO8601", "UTC"), "2024-08-14 15:29:25,956");
400+
dateConverterChecker(List.of("yyyy-MM-EE", "UTC", "fr-CH"), "2024-08-mer.");
401+
402+
}
403+
404+
void dateConverterChecker(List<String> options, String expected) {
405+
DateConverter dateConverter = new DateConverter();
406+
dateConverter.setOptionList(options) ;
407+
dateConverter.setContext(loggerContext);
408+
dateConverter.start();
409+
410+
assertTrue(dateConverter.isStarted());
411+
LoggingEvent event = makeLoggingEvent(null);
412+
413+
// 2024-08-14T1Z:29:25,956 GMT
414+
long millis = 1_723_649_365_956L; //System.currentTimeMillis();
415+
Instant now = Instant.ofEpochMilli(millis);
416+
event.setInstant(now);
417+
String result = dateConverter.convert(event);
418+
assertEquals(expected, result);
419+
}
430420
}

logback-core/src/main/java/ch/qos/logback/core/CoreConstants.java

+13
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,19 @@ public class CoreConstants {
6161
public static final String ISO8601_STR = "ISO8601";
6262
public static final String ISO8601_PATTERN = "yyyy-MM-dd HH:mm:ss,SSS";
6363

64+
/**
65+
* Keyword for setting a strict ISO8601 pattern which includes 'T' between the date and the time
66+
*
67+
* @since 1.5.7
68+
*/
69+
public static final String STRICT_STR = "STRICT";
70+
/**
71+
* Strict ISO8601 pattern which includes 'T' between the date and the time
72+
* @since 15.7
73+
*/
74+
public static final String STRICT_ISO8601_PATTERN = "yyyy-MM-dd'T'HH:mm:ss,SSS";
75+
76+
6477
public static final String FILE_TIMESTAMP_PATTERN = "yyyy-MM-dd'T'HHmm";
6578
public static final String DAILY_DATE_PATTERN = "yyyy-MM-dd";
6679

0 commit comments

Comments
 (0)