View Javadoc
1   /*
2    * Copyright 2018 SPF4J.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.spf4j.test.log;
17  
18  import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
19  import java.io.IOException;
20  import java.io.UncheckedIOException;
21  import java.nio.charset.Charset;
22  import java.time.ZoneId;
23  import java.time.format.DateTimeFormatter;
24  import java.time.format.DateTimeFormatterBuilder;
25  import java.time.temporal.ChronoField;
26  import static java.time.temporal.ChronoField.HOUR_OF_DAY;
27  import static java.time.temporal.ChronoField.MINUTE_OF_HOUR;
28  import static java.time.temporal.ChronoField.SECOND_OF_MINUTE;
29  import javax.annotation.ParametersAreNonnullByDefault;
30  import org.spf4j.log.Level;
31  
32  /**
33   * A log handler that will print all logs that are not marked as printed above a log level.
34   * It passes through all logs to downstream handlers.
35   * Marks Log messages a PRINTED.
36   * @author Zoltan Farkas
37   */
38  @ParametersAreNonnullByDefault
39  @SuppressFBWarnings("FCCD_FIND_CLASS_CIRCULAR_DEPENDENCY") // this is with LogRecord...
40  public final class LogPrinter implements LogHandler {
41  
42    private static final DateTimeFormatter FMT =
43            TestUtils.isExecutedFromIDE() ? new DateTimeFormatterBuilder()
44                  .appendValue(HOUR_OF_DAY, 2)
45                  .appendLiteral(':')
46                  .appendValue(MINUTE_OF_HOUR, 2)
47                  .optionalStart()
48                  .appendLiteral(':')
49                  .appendValue(SECOND_OF_MINUTE, 2)
50                  .optionalStart()
51                  .appendFraction(ChronoField.MILLI_OF_SECOND, 3, 3, true)
52                  .toFormatter().withZone(ZoneId.systemDefault())
53            : DateTimeFormatter.ISO_INSTANT;
54  
55    public static final org.spf4j.log.LogPrinter PRINTER = new org.spf4j.log.LogPrinter(FMT, Charset.defaultCharset());
56  
57    private final Level minLogged;
58  
59  
60    LogPrinter(final Level minLogged) {
61      this.minLogged = minLogged;
62    }
63  
64    /**
65     * {@inheritDoc}
66     */
67    @Override
68    public Handling handles(final Level level) {
69      return level.ordinal() >= minLogged.ordinal() ? Handling.HANDLE_PASS : Handling.NONE;
70    }
71  
72    /**
73     * {@inheritDoc}
74     */
75    @SuppressFBWarnings({ "CFS_CONFUSING_FUNCTION_SEMANTICS", "EXS_EXCEPTION_SOFTENING_NO_CHECKED" })
76    @Override
77    public TestLogRecord handle(final TestLogRecord record) {
78      if (record.hasAttachment(Attachments.PRINTED) || record.hasAttachment(Attachments.DO_NOT_PRINT)) {
79        return record;
80      }
81      try {
82        PRINTER.print(record, System.out, System.err).flush();
83      } catch (IOException ex) {
84        throw new UncheckedIOException(ex);
85      }
86      record.attach(Attachments.PRINTED);
87      return record;
88    }
89  
90  
91  
92    @Override
93    public String toString() {
94      return "LogPrinter{" + "minLogged=" + minLogged + '}';
95    }
96  
97  }