Skip to content

Commit 87aa827

Browse files
Merge pull request #197 from wttech/log-timestamps
Log timestamps
2 parents 44b452e + d0f7671 commit 87aa827

File tree

5 files changed

+111
-126
lines changed

5 files changed

+111
-126
lines changed

core/src/main/java/dev/vml/es/acm/core/code/CodeLoggerPrinter.java

Lines changed: 0 additions & 72 deletions
This file was deleted.

core/src/main/java/dev/vml/es/acm/core/code/CodePrintStream.java

Lines changed: 99 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,19 @@
22

33
import ch.qos.logback.classic.Logger;
44
import ch.qos.logback.classic.LoggerContext;
5+
import ch.qos.logback.classic.spi.ILoggingEvent;
6+
import ch.qos.logback.core.AppenderBase;
7+
import dev.vml.es.acm.core.AcmException;
58
import java.io.OutputStream;
69
import java.io.PrintStream;
10+
import java.time.Instant;
11+
import java.time.LocalDateTime;
12+
import java.time.ZoneId;
13+
import java.time.format.DateTimeFormatter;
14+
import java.util.HashSet;
715
import java.util.List;
16+
import java.util.Set;
17+
import org.apache.commons.lang3.StringUtils;
818
import org.slf4j.LoggerFactory;
919

1020
/**
@@ -13,17 +23,101 @@
1323
*/
1424
public class CodePrintStream extends PrintStream {
1525

26+
public static final String LOGGER_NAME_ACL = "dev.vml.es.acm.core.acl";
27+
public static final String LOGGER_NAME_REPO = "dev.vml.es.acm.core.repo";
28+
public static final String[] LOGGER_NAMES = {LOGGER_NAME_ACL, LOGGER_NAME_REPO};
29+
30+
// have to match pattern in 'monaco/log.ts'
31+
private static final DateTimeFormatter LOGGER_TIMESTAMP_FORMATTER = DateTimeFormatter.ofPattern("HH:mm:ss.SSS");
32+
1633
private final Logger logger;
1734

18-
private final CodeLoggerPrinter loggerPrinter;
35+
private final LoggerContext loggerContext;
36+
37+
private final Set<String> loggerNames;
38+
39+
private boolean loggerTimestamps;
40+
41+
private final LogAppender logAppender;
1942

2043
public CodePrintStream(OutputStream output, String id) {
2144
super(output);
2245

23-
LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
24-
25-
this.loggerPrinter = new CodeLoggerPrinter(loggerContext, output);
46+
this.loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
47+
this.loggerNames = new HashSet<>();
48+
this.loggerTimestamps = true;
2649
this.logger = loggerContext.getLogger(id);
50+
this.logAppender = new LogAppender();
51+
}
52+
53+
private class LogAppender extends AppenderBase<ILoggingEvent> {
54+
@Override
55+
protected void append(ILoggingEvent event) {
56+
String loggerName = event.getLoggerName();
57+
for (String loggerPrefix : loggerNames) {
58+
if (StringUtils.startsWith(loggerName, loggerPrefix)) {
59+
String level = event.getLevel().toString();
60+
if (loggerTimestamps) {
61+
LocalDateTime eventTime = LocalDateTime.ofInstant(
62+
Instant.ofEpochMilli(event.getTimeStamp()), ZoneId.systemDefault());
63+
String timestamp = eventTime.format(LOGGER_TIMESTAMP_FORMATTER);
64+
println(timestamp + " [" + level + "] " + event.getFormattedMessage());
65+
} else {
66+
println('[' + level + "] " + event.getFormattedMessage());
67+
}
68+
break;
69+
}
70+
}
71+
}
72+
}
73+
74+
public void fromLogger(String loggerName) {
75+
if (StringUtils.isBlank(loggerName)) {
76+
throw new AcmException("Logger name cannot be blank!");
77+
}
78+
enableAppender();
79+
loggerNames.add(loggerName);
80+
}
81+
82+
@Override
83+
public void close() {
84+
disableAppender();
85+
super.close();
86+
}
87+
88+
private void enableAppender() {
89+
if (logAppender.isStarted()) {
90+
return;
91+
}
92+
Logger rootLogger = getRootLogger();
93+
rootLogger.addAppender(logAppender);
94+
logAppender.setContext(loggerContext);
95+
logAppender.start();
96+
}
97+
98+
private void disableAppender() {
99+
if (!logAppender.isStarted()) {
100+
return;
101+
}
102+
logAppender.stop();
103+
Logger rootLogger = getRootLogger();
104+
rootLogger.detachAppender(logAppender);
105+
}
106+
107+
private Logger getRootLogger() {
108+
return loggerContext.getLogger(Logger.ROOT_LOGGER_NAME);
109+
}
110+
111+
public Logger getLogger() {
112+
return logger;
113+
}
114+
115+
public boolean isLoggerTimestamps() {
116+
return loggerTimestamps;
117+
}
118+
119+
public void withLoggerTimestamps(boolean flag) {
120+
this.loggerTimestamps = flag;
27121
}
28122

29123
public void fromLogs() {
@@ -40,11 +134,7 @@ public void fromSelfLogger() {
40134
}
41135

42136
public void fromRecommendedLoggers() {
43-
fromLoggers(CodeLoggerPrinter.NAMES);
44-
}
45-
46-
public void fromLogger(String loggerName) {
47-
loggerPrinter.fromLogger(loggerName);
137+
fromLoggers(LOGGER_NAMES);
48138
}
49139

50140
public void fromLoggers(String... loggerNames) {
@@ -56,14 +146,4 @@ public void fromLoggers(String... loggerNames) {
56146
public void fromLoggers(List<String> loggerNames) {
57147
loggerNames.forEach(this::fromLogger);
58148
}
59-
60-
@Override
61-
public void close() {
62-
loggerPrinter.disable();
63-
super.close();
64-
}
65-
66-
protected Logger getLogger() {
67-
return logger;
68-
}
69149
}

core/src/main/java/dev/vml/es/acm/core/code/Executor.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,12 @@ public class Executor {
5454
@AttributeDefinition(
5555
name = "Log Printing Names",
5656
description = "Additional loggers to print logs from (class names or package names)")
57-
String[] logPrintingNames() default {CodeLoggerPrinter.NAME_ACL, CodeLoggerPrinter.NAME_REPO};
57+
String[] logPrintingNames() default {CodePrintStream.LOGGER_NAME_ACL, CodePrintStream.LOGGER_NAME_REPO};
58+
59+
@AttributeDefinition(
60+
name = "Log Printing Timestamps",
61+
description = "Prints timestamps in the execution output.")
62+
boolean logPrintingTimestamps() default true;
5863

5964
@AttributeDefinition(
6065
name = "Notification Enabled",
@@ -170,6 +175,7 @@ private ImmediateExecution executeImmediately(ExecutionContext context) {
170175
if (config.logPrintingEnabled()) {
171176
context.getOut().fromSelfLogger();
172177
context.getOut().fromLoggers(config.logPrintingNames());
178+
context.getOut().withLoggerTimestamps(config.logPrintingTimestamps());
173179
}
174180
contentScript.run();
175181
return execution.end(ExecutionStatus.SUCCEEDED);

ui.content/src/main/content/jcr_root/conf/acm/settings/snippet/available/core/misc/demo_notifier.yml

Lines changed: 0 additions & 29 deletions
This file was deleted.

ui.frontend/src/utils/monaco/log.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,11 @@ export function registerLogLanguage(instance: Monaco) {
1515
instance.languages.setMonarchTokensProvider(LOG_LANGUAGE_ID, {
1616
tokenizer: {
1717
root: [
18-
[/^\[ERROR].*$/, 'log-error'],
19-
[/^\[WARN].*$/, 'log-warn'],
20-
[/^\[INFO].*$/, 'log-info'],
21-
[/^\[DEBUG].*$/, 'log-debug'],
22-
[/^\[TRACE].*$/, 'log-trace'],
18+
[/^(\d{2}:\d{2}:\d{2}\.\d{3} )?\[ERROR\].*$/, 'log-error'],
19+
[/^(\d{2}:\d{2}:\d{2}\.\d{3} )?\[WARN\].*$/, 'log-warn'],
20+
[/^(\d{2}:\d{2}:\d{2}\.\d{3} )?\[INFO\].*$/, 'log-info'],
21+
[/^(\d{2}:\d{2}:\d{2}\.\d{3} )?\[DEBUG\].*$/, 'log-debug'],
22+
[/^(\d{2}:\d{2}:\d{2}\.\d{3} )?\[TRACE\].*$/, 'log-trace'],
2323
],
2424
},
2525
});

0 commit comments

Comments
 (0)