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.simple;
018    
019    import java.io.FileNotFoundException;
020    import java.io.FileOutputStream;
021    import java.io.PrintStream;
022    import java.util.concurrent.ConcurrentHashMap;
023    import java.util.concurrent.ConcurrentMap;
024    
025    import org.apache.logging.log4j.Level;
026    import org.apache.logging.log4j.message.MessageFactory;
027    import org.apache.logging.log4j.spi.AbstractLogger;
028    import org.apache.logging.log4j.spi.ExtendedLogger;
029    import org.apache.logging.log4j.spi.LoggerContext;
030    import org.apache.logging.log4j.util.PropertiesUtil;
031    
032    /**
033     *
034     */
035    public class SimpleLoggerContext implements LoggerContext {
036    
037        /** The default format to use when formatting dates */
038        protected static final String DEFAULT_DATE_TIME_FORMAT = "yyyy/MM/dd HH:mm:ss:SSS zzz";
039    
040        /** All system properties used by <code>SimpleLog</code> start with this */
041        protected static final String SYSTEM_PREFIX = "org.apache.logging.log4j.simplelog.";
042    
043        private final PropertiesUtil props;
044    
045        /** Include the instance name in the log message? */
046        private final boolean showLogName;
047        /**
048         * Include the short name ( last component ) of the logger in the log message. Defaults to true - otherwise we'll be
049         * lost in a flood of messages without knowing who sends them.
050         */
051        private final boolean showShortName;
052        /** Include the current time in the log message */
053        private final boolean showDateTime;
054        /** Include the ThreadContextMap in the log message */
055        private final boolean showContextMap;
056        /** The date and time format to use in the log message */
057        private final String dateTimeFormat;
058    
059        private final Level defaultLevel;
060    
061        private final PrintStream stream;
062    
063        private final ConcurrentMap<String, ExtendedLogger> loggers = new ConcurrentHashMap<String, ExtendedLogger>();
064    
065        public SimpleLoggerContext() {
066            props = new PropertiesUtil("log4j2.simplelog.properties");
067    
068            showContextMap = props.getBooleanProperty(SYSTEM_PREFIX + "showContextMap", false);
069            showLogName = props.getBooleanProperty(SYSTEM_PREFIX + "showlogname", false);
070            showShortName = props.getBooleanProperty(SYSTEM_PREFIX + "showShortLogname", true);
071            showDateTime = props.getBooleanProperty(SYSTEM_PREFIX + "showdatetime", false);
072            final String lvl = props.getStringProperty(SYSTEM_PREFIX + "level");
073            defaultLevel = Level.toLevel(lvl, Level.ERROR);
074    
075            dateTimeFormat = showDateTime ? props.getStringProperty(SimpleLoggerContext.SYSTEM_PREFIX + "dateTimeFormat",
076                    DEFAULT_DATE_TIME_FORMAT) : null;
077    
078            final String fileName = props.getStringProperty(SYSTEM_PREFIX + "logFile", "system.err");
079            PrintStream ps;
080            if ("system.err".equalsIgnoreCase(fileName)) {
081                ps = System.err;
082            } else if ("system.out".equalsIgnoreCase(fileName)) {
083                ps = System.out;
084            } else {
085                try {
086                    final FileOutputStream os = new FileOutputStream(fileName);
087                    ps = new PrintStream(os);
088                } catch (final FileNotFoundException fnfe) {
089                    ps = System.err;
090                }
091            }
092            this.stream = ps;
093        }
094    
095        @Override
096        public ExtendedLogger getLogger(final String name) {
097            return getLogger(name, null);
098        }
099    
100        @Override
101        public ExtendedLogger getLogger(final String name, final MessageFactory messageFactory) {
102            if (loggers.containsKey(name)) {
103                final ExtendedLogger logger = loggers.get(name);
104                AbstractLogger.checkMessageFactory(logger, messageFactory);
105                return logger;
106            }
107    
108            loggers.putIfAbsent(name, new SimpleLogger(name, defaultLevel, showLogName, showShortName, showDateTime,
109                    showContextMap, dateTimeFormat, messageFactory, props, stream));
110            return loggers.get(name);
111        }
112    
113        @Override
114        public boolean hasLogger(final String name) {
115            return false;
116        }
117    
118        @Override
119        public Object getExternalContext() {
120            return null;
121        }
122    }