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, LocationAwareReliabilityStrategy { 034 private final LoggerConfig loggerConfig; 035 private final ReadWriteLock reconfigureLock = new ReentrantReadWriteLock(); 036 private volatile boolean isStopping; 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 * 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 final LoggerConfig config = getActiveLoggerConfig(reconfigured); 073 try { 074 config.log(loggerName, fqcn, location, marker, level, data, t); 075 } finally { 076 config.getReliabilityStrategy().afterLogEvent(); 077 } 078 } 079 080 /* 081 * (non-Javadoc) 082 * 083 * @see org.apache.logging.log4j.core.config.ReliabilityStrategy#log(org.apache.logging.log4j.util.Supplier, 084 * org.apache.logging.log4j.core.LogEvent) 085 */ 086 @Override 087 public void log(final Supplier<LoggerConfig> reconfigured, final LogEvent event) { 088 final LoggerConfig config = getActiveLoggerConfig(reconfigured); 089 try { 090 config.log(event); 091 } finally { 092 config.getReliabilityStrategy().afterLogEvent(); 093 } 094 } 095 096 /* 097 * (non-Javadoc) 098 * 099 * @see 100 * org.apache.logging.log4j.core.config.ReliabilityStrategy#beforeLogEvent(org.apache.logging.log4j.core.config. 101 * LoggerConfig, org.apache.logging.log4j.util.Supplier) 102 */ 103 @Override 104 public LoggerConfig getActiveLoggerConfig(final Supplier<LoggerConfig> next) { 105 LoggerConfig result = this.loggerConfig; 106 if (!beforeLogEvent()) { 107 result = next.get(); 108 return result == this.loggerConfig ? result : result.getReliabilityStrategy().getActiveLoggerConfig(next); 109 } 110 return result; 111 } 112 113 private boolean beforeLogEvent() { 114 reconfigureLock.readLock().lock(); 115 if (isStopping) { 116 reconfigureLock.readLock().unlock(); 117 return false; 118 } 119 return true; 120 } 121 122 @Override 123 public void afterLogEvent() { 124 reconfigureLock.readLock().unlock(); 125 } 126 127 /* 128 * (non-Javadoc) 129 * 130 * @see org.apache.logging.log4j.core.config.ReliabilityStrategy#beforeStopAppenders() 131 */ 132 @Override 133 public void beforeStopAppenders() { 134 reconfigureLock.writeLock().lock(); 135 try { 136 isStopping = true; 137 } finally { 138 reconfigureLock.writeLock().unlock(); 139 } 140 } 141 142 /* 143 * (non-Javadoc) 144 * 145 * @see 146 * org.apache.logging.log4j.core.config.ReliabilityStrategy#beforeStopConfiguration(org.apache.logging.log4j.core 147 * .config.Configuration) 148 */ 149 @Override 150 public void beforeStopConfiguration(final Configuration configuration) { 151 // no action 152 } 153 154}