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
018package org.apache.logging.log4j.core.config;
019
020import java.util.Objects;
021
022import org.apache.logging.log4j.Level;
023import org.apache.logging.log4j.Marker;
024import org.apache.logging.log4j.core.LogEvent;
025import org.apache.logging.log4j.message.Message;
026import org.apache.logging.log4j.status.StatusLogger;
027import org.apache.logging.log4j.util.PropertiesUtil;
028import org.apache.logging.log4j.util.Supplier;
029
030/**
031 * Reliability strategy that sleeps unconditionally for some time before allowing a Configuration to be stopped.
032 */
033public class AwaitUnconditionallyReliabilityStrategy implements ReliabilityStrategy, LocationAwareReliabilityStrategy {
034
035    private static final long DEFAULT_SLEEP_MILLIS = 5000; // 5 seconds
036    private static final long SLEEP_MILLIS = sleepMillis();
037    private final LoggerConfig loggerConfig;
038
039    public AwaitUnconditionallyReliabilityStrategy(final LoggerConfig loggerConfig) {
040        this.loggerConfig = Objects.requireNonNull(loggerConfig, "loggerConfig is null");
041    }
042
043    private static long sleepMillis() {
044        return PropertiesUtil.getProperties().getLongProperty("log4j.waitMillisBeforeStopOldConfig",
045                DEFAULT_SLEEP_MILLIS);
046    }
047
048    /*
049     * (non-Javadoc)
050     *
051     * @see org.apache.logging.log4j.core.config.ReliabilityStrategy#log(org.apache.logging.log4j.util.Supplier,
052     * java.lang.String, java.lang.String, org.apache.logging.log4j.Marker, org.apache.logging.log4j.Level,
053     * org.apache.logging.log4j.message.Message, java.lang.Throwable)
054     */
055    @Override
056    public void log(final Supplier<LoggerConfig> reconfigured, final String loggerName, final String fqcn, final Marker marker, final Level level,
057            final Message data, final Throwable t) {
058        loggerConfig.log(loggerName, fqcn, marker, level, data, t);
059    }
060
061    /*
062     * (non-Javadoc)
063     *
064     * @see org.apache.logging.log4j.core.config.ReliabilityStrategy#log(org.apache.logging.log4j.util.Supplier,
065     * java.lang.String, java.lang.String, java.lang.StackTraceElement, org.apache.logging.log4j.Marker,
066     * org.apache.logging.log4j.Level, org.apache.logging.log4j.message.Message, java.lang.Throwable)
067     */
068    @Override
069    public void log(final Supplier<LoggerConfig> reconfigured, final String loggerName, final String fqcn,
070        final StackTraceElement location, final Marker marker, final Level level, final Message data,
071        final Throwable t) {
072        loggerConfig.log(loggerName, fqcn, location, marker, level, data, t);
073    }
074
075    /*
076     * (non-Javadoc)
077     *
078     * @see org.apache.logging.log4j.core.config.ReliabilityStrategy#log(org.apache.logging.log4j.util.Supplier,
079     * org.apache.logging.log4j.core.LogEvent)
080     */
081    @Override
082    public void log(final Supplier<LoggerConfig> reconfigured, final LogEvent event) {
083        loggerConfig.log(event);
084    }
085
086    /*
087     * (non-Javadoc)
088     *
089     * @see
090     * org.apache.logging.log4j.core.config.ReliabilityStrategy#beforeLogEvent(org.apache.logging.log4j.core.config.
091     * LoggerConfig, org.apache.logging.log4j.util.Supplier)
092     */
093    @Override
094    public LoggerConfig getActiveLoggerConfig(final Supplier<LoggerConfig> next) {
095        return this.loggerConfig;
096    }
097
098    /*
099     * (non-Javadoc)
100     *
101     * @see org.apache.logging.log4j.core.config.ReliabilityStrategy#afterLogEvent()
102     */
103    @Override
104    public void afterLogEvent() {
105        // no action
106    }
107
108    /*
109     * (non-Javadoc)
110     *
111     * @see org.apache.logging.log4j.core.config.ReliabilityStrategy#beforeStopAppenders()
112     */
113    @Override
114    public void beforeStopAppenders() {
115        // no action
116    }
117
118    /*
119     * (non-Javadoc)
120     *
121     * @see
122     * org.apache.logging.log4j.core.config.ReliabilityStrategy#beforeStopConfiguration(org.apache.logging.log4j.core
123     * .config.Configuration)
124     */
125    @Override
126    public void beforeStopConfiguration(final Configuration configuration) {
127        // only sleep once per configuration stop
128        if (loggerConfig == configuration.getRootLogger()) {
129            try {
130                Thread.sleep(SLEEP_MILLIS);
131            } catch (final InterruptedException e) {
132                StatusLogger.getLogger().warn("Sleep before stop configuration was interrupted.");
133            }
134        }
135    }
136
137}