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.core.appender; 018 019 import java.util.HashMap; 020 import java.util.Map; 021 import org.apache.logging.log4j.core.Filter; 022 import org.apache.logging.log4j.core.Layout; 023 import org.apache.logging.log4j.core.LogEvent; 024 import org.apache.logging.log4j.core.appender.rolling.DefaultRolloverStrategy; 025 import org.apache.logging.log4j.core.appender.rolling.RollingFileManager; 026 import org.apache.logging.log4j.core.appender.rolling.RolloverStrategy; 027 import org.apache.logging.log4j.core.appender.rolling.TriggeringPolicy; 028 import org.apache.logging.log4j.core.config.Configuration; 029 import org.apache.logging.log4j.core.config.plugins.Plugin; 030 import org.apache.logging.log4j.core.config.plugins.PluginAttr; 031 import org.apache.logging.log4j.core.config.plugins.PluginConfiguration; 032 import org.apache.logging.log4j.core.config.plugins.PluginElement; 033 import org.apache.logging.log4j.core.config.plugins.PluginFactory; 034 import org.apache.logging.log4j.core.layout.PatternLayout; 035 import org.apache.logging.log4j.core.net.Advertiser; 036 037 /** 038 * An appender that writes to files and can roll over at intervals. 039 */ 040 @Plugin(name = "RollingFile", type = "Core", elementType = "appender", printObject = true) 041 public final class RollingFileAppender extends AbstractOutputStreamAppender { 042 043 private final String fileName; 044 private final String filePattern; 045 private Object advertisement; 046 private final Advertiser advertiser; 047 048 049 private RollingFileAppender(final String name, final Layout layout, final Filter filter, 050 final RollingFileManager manager, final String fileName, 051 final String filePattern, final boolean handleException, final boolean immediateFlush, 052 Advertiser advertiser) { 053 super(name, layout, filter, handleException, immediateFlush, manager); 054 if (advertiser != null) 055 { 056 Map<String, String> configuration = new HashMap<String, String>(layout.getContentFormat()); 057 configuration.put("contentType", layout.getContentType()); 058 configuration.put("name", name); 059 advertisement = advertiser.advertise(configuration); 060 } 061 this.fileName = fileName; 062 this.filePattern = filePattern; 063 this.advertiser = advertiser; 064 } 065 066 @Override 067 public void stop() { 068 super.stop(); 069 if (advertiser != null) { 070 advertiser.unadvertise(advertisement); 071 } 072 } 073 074 /** 075 * Write the log entry rolling over the file when required. 076 077 * @param event The LogEvent. 078 */ 079 @Override 080 public void append(final LogEvent event) { 081 ((RollingFileManager) getManager()).checkRollover(event); 082 super.append(event); 083 } 084 085 /** 086 * Returns the File name for the Appender. 087 * @return The file name. 088 */ 089 public String getFileName() { 090 return fileName; 091 } 092 093 /** 094 * Returns the file pattern used when rolling over. 095 * @return The file pattern. 096 */ 097 public String getFilePattern() { 098 return filePattern; 099 } 100 101 /** 102 * Create a RollingFileAppender. 103 * @param fileName The name of the file that is actively written to. (required). 104 * @param filePattern The pattern of the file name to use on rollover. (required). 105 * @param append If true, events are appended to the file. If false, the file 106 * is overwritten when opened. Defaults to "true" 107 * @param name The name of the Appender (required). 108 * @param bufferedIO When true, I/O will be buffered. Defaults to "true". 109 * @param immediateFlush When true, events are immediately flushed. Defaults to "true". 110 * @param policy The triggering policy. (required). 111 * @param strategy The rollover strategy. Defaults to DefaultRolloverStrategy. 112 * @param layout The layout to use (defaults to the default PatternLayout). 113 * @param filter The Filter or null. 114 * @param suppress "true" if exceptions should be hidden from the application, "false" otherwise. 115 * The default is "true". 116 * @param advertise "true" if the appender configuration should be advertised, "false" otherwise. 117 * @param advertiseURI The advertised URI which can be used to retrieve the file contents. 118 * @param config The Configuration. 119 * @return A RollingFileAppender. 120 */ 121 @PluginFactory 122 public static RollingFileAppender createAppender(@PluginAttr("fileName") final String fileName, 123 @PluginAttr("filePattern") final String filePattern, 124 @PluginAttr("append") final String append, 125 @PluginAttr("name") final String name, 126 @PluginAttr("bufferedIO") final String bufferedIO, 127 @PluginAttr("immediateFlush") final String immediateFlush, 128 @PluginElement("policy") final TriggeringPolicy policy, 129 @PluginElement("strategy") RolloverStrategy strategy, 130 @PluginElement("layout") Layout layout, 131 @PluginElement("filter") final Filter filter, 132 @PluginAttr("suppressExceptions") final String suppress, 133 @PluginAttr("advertise") final String advertise, 134 @PluginAttr("advertiseURI") final String advertiseURI, 135 @PluginConfiguration final Configuration config) { 136 137 final boolean isAppend = append == null ? true : Boolean.valueOf(append); 138 final boolean handleExceptions = suppress == null ? true : Boolean.valueOf(suppress); 139 final boolean isBuffered = bufferedIO == null ? true : Boolean.valueOf(bufferedIO); 140 final boolean isFlush = immediateFlush == null ? true : Boolean.valueOf(immediateFlush); 141 boolean isAdvertise = advertise == null ? false : Boolean.valueOf(advertise); 142 if (name == null) { 143 LOGGER.error("No name provided for FileAppender"); 144 return null; 145 } 146 147 if (fileName == null) { 148 LOGGER.error("No filename was provided for FileAppender with name " + name); 149 return null; 150 } 151 152 if (filePattern == null) { 153 LOGGER.error("No filename pattern provided for FileAppender with name " + name); 154 return null; 155 } 156 157 if (policy == null) { 158 LOGGER.error("A TriggeringPolicy must be provided"); 159 return null; 160 } 161 162 if (strategy == null) { 163 strategy = DefaultRolloverStrategy.createStrategy(null, null, "true", config); 164 } 165 166 final RollingFileManager manager = RollingFileManager.getFileManager(fileName, filePattern, isAppend, 167 isBuffered, policy, strategy, advertiseURI); 168 if (manager == null) { 169 return null; 170 } 171 172 if (layout == null) { 173 layout = PatternLayout.createLayout(null, null, null, null); 174 } 175 176 return new RollingFileAppender(name, layout, filter, manager, fileName, filePattern, 177 handleExceptions, isFlush, isAdvertise ? config.getAdvertiser() : null); 178 } 179 }