22
33import ch .qos .logback .classic .Logger ;
44import 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 ;
58import java .io .OutputStream ;
69import 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 ;
715import java .util .List ;
16+ import java .util .Set ;
17+ import org .apache .commons .lang3 .StringUtils ;
818import org .slf4j .LoggerFactory ;
919
1020/**
1323 */
1424public 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}
0 commit comments