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