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; 021import java.util.concurrent.locks.ReadWriteLock; 022import java.util.concurrent.locks.ReentrantReadWriteLock; 023 024import org.apache.logging.log4j.Level; 025import org.apache.logging.log4j.Marker; 026import org.apache.logging.log4j.core.LogEvent; 027import org.apache.logging.log4j.message.Message; 028import org.apache.logging.log4j.util.Supplier; 029 030/** 031 * ReliabilityStrategy that uses read/write locks to prevent the LoggerConfig from stopping while it is in use. 032 */ 033public class LockingReliabilityStrategy implements ReliabilityStrategy { 034 private final LoggerConfig loggerConfig; 035 private final ReadWriteLock reconfigureLock = new ReentrantReadWriteLock(); 036 private volatile boolean isStopping = false; 037 038 public LockingReliabilityStrategy(final LoggerConfig loggerConfig) { 039 this.loggerConfig = Objects.requireNonNull(loggerConfig, "loggerConfig was null"); 040 } 041 042 /* 043 * (non-Javadoc) 044 * 045 * @see org.apache.logging.log4j.core.config.ReliabilityStrategy#log(org.apache.logging.log4j.util.Supplier, 046 * java.lang.String, java.lang.String, org.apache.logging.log4j.Marker, org.apache.logging.log4j.Level, 047 * org.apache.logging.log4j.message.Message, java.lang.Throwable) 048 */ 049 @Override 050 public void log(final Supplier<LoggerConfig> reconfigured, final String loggerName, final String fqcn, 051 final Marker marker, final Level level, final Message data, final Throwable t) { 052 053 final LoggerConfig config = getActiveLoggerConfig(reconfigured); 054 try { 055 config.log(loggerName, fqcn, marker, level, data, t); 056 } finally { 057 config.getReliabilityStrategy().afterLogEvent(); 058 } 059 } 060 061 /* 062 * (non-Javadoc) 063 * 064 * @see org.apache.logging.log4j.core.config.ReliabilityStrategy#log(org.apache.logging.log4j.util.Supplier, 065 * org.apache.logging.log4j.core.LogEvent) 066 */ 067 @Override 068 public void log(final Supplier<LoggerConfig> reconfigured, final LogEvent event) { 069 final LoggerConfig config = getActiveLoggerConfig(reconfigured); 070 try { 071 config.log(event); 072 } finally { 073 config.getReliabilityStrategy().afterLogEvent(); 074 } 075 } 076 077 /* 078 * (non-Javadoc) 079 * 080 * @see 081 * org.apache.logging.log4j.core.config.ReliabilityStrategy#beforeLogEvent(org.apache.logging.log4j.core.config. 082 * LoggerConfig, org.apache.logging.log4j.util.Supplier) 083 */ 084 @Override 085 public LoggerConfig getActiveLoggerConfig(final Supplier<LoggerConfig> next) { 086 LoggerConfig result = this.loggerConfig; 087 if (!beforeLogEvent()) { 088 result = next.get(); 089 return result.getReliabilityStrategy().getActiveLoggerConfig(next); 090 } 091 return result; 092 } 093 094 private boolean beforeLogEvent() { 095 reconfigureLock.readLock().lock(); 096 if (isStopping) { 097 reconfigureLock.readLock().unlock(); 098 return false; 099 } 100 return true; 101 } 102 103 @Override 104 public void afterLogEvent() { 105 reconfigureLock.readLock().unlock(); 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 reconfigureLock.writeLock().lock(); 116 try { 117 isStopping = true; 118 } finally { 119 reconfigureLock.writeLock().unlock(); 120 } 121 } 122 123 /* 124 * (non-Javadoc) 125 * 126 * @see 127 * org.apache.logging.log4j.core.config.ReliabilityStrategy#beforeStopConfiguration(org.apache.logging.log4j.core 128 * .config.Configuration) 129 */ 130 @Override 131 public void beforeStopConfiguration(Configuration configuration) { 132 // no action 133 } 134 135}