001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache license, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the license for the specific language governing permissions and
015 * limitations under the license.
016 */
017 package org.apache.logging.log4j.status;
018
019 import java.io.IOException;
020 import java.io.PrintStream;
021
022 import org.apache.logging.log4j.Level;
023
024 /**
025 * StatusListener that writes to the Console.
026 */
027 @SuppressWarnings("UseOfSystemOutOrSystemErr")
028 public class StatusConsoleListener implements StatusListener {
029
030 private Level level = Level.FATAL;
031 private String[] filters;
032 private final PrintStream stream;
033
034 /**
035 * Creates the StatusConsoleListener using the supplied Level.
036 * @param level The Level of status messages that should appear on the console.
037 */
038 public StatusConsoleListener(final Level level) {
039 this(level, System.out);
040 }
041
042 /**
043 * Creates the StatusConsoleListener using the supplied Level. Make sure not to use a logger stream of some sort
044 * to avoid creating an infinite loop of indirection!
045 * @param level The Level of status messages that should appear on the console.
046 * @param stream The PrintStream to write to.
047 * @throws IllegalArgumentException if the PrintStream argument is {@code null}.
048 */
049 public StatusConsoleListener(final Level level, final PrintStream stream) {
050 if (stream == null) {
051 throw new IllegalArgumentException("You must provide a stream to use for this listener.");
052 }
053 this.level = level;
054 this.stream = stream;
055 }
056
057 /**
058 * Sets the level to a new value.
059 * @param level The new Level.
060 */
061 public void setLevel(final Level level) {
062 this.level = level;
063 }
064
065 /**
066 * Return the Log Level for which the Listener should receive events.
067 * @return the Log Level.
068 */
069 @Override
070 public Level getStatusLevel() {
071 return this.level;
072 }
073
074 /**
075 * Writes status messages to the console.
076 * @param data The StatusData.
077 */
078 @Override
079 public void log(final StatusData data) {
080 if (!filtered(data)) {
081 stream.println(data.getFormattedStatus());
082 }
083 }
084
085 /**
086 * Adds package name filters to exclude.
087 * @param filters An array of package names to exclude.
088 */
089 public void setFilters(final String... filters) {
090 this.filters = filters;
091 }
092
093 private boolean filtered(final StatusData data) {
094 if (filters == null) {
095 return false;
096 }
097 final String caller = data.getStackTraceElement().getClassName();
098 for (final String filter : filters) {
099 if (caller.startsWith(filter)) {
100 return true;
101 }
102 }
103 return false;
104 }
105
106 @Override
107 public void close() throws IOException {
108 // only want to close non-system streams
109 if (this.stream != System.out && this.stream != System.err) {
110 this.stream.close();
111 }
112 }
113 }