View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements. See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache license, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License. You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the license for the specific language governing permissions and
15   * limitations under the license.
16   */
17  package org.apache.logging.log4j.core.appender;
18  
19  import org.apache.logging.log4j.core.Filter;
20  import org.apache.logging.log4j.core.Layout;
21  import org.apache.logging.log4j.core.LogEvent;
22  import org.apache.logging.log4j.core.appender.rolling.DefaultRolloverStrategy;
23  import org.apache.logging.log4j.core.appender.rolling.RollingFileManager;
24  import org.apache.logging.log4j.core.appender.rolling.RolloverStrategy;
25  import org.apache.logging.log4j.core.appender.rolling.TriggeringPolicy;
26  import org.apache.logging.log4j.core.config.Configuration;
27  import org.apache.logging.log4j.core.config.plugins.Plugin;
28  import org.apache.logging.log4j.core.config.plugins.PluginAttr;
29  import org.apache.logging.log4j.core.config.plugins.PluginConfiguration;
30  import org.apache.logging.log4j.core.config.plugins.PluginElement;
31  import org.apache.logging.log4j.core.config.plugins.PluginFactory;
32  import org.apache.logging.log4j.core.layout.PatternLayout;
33  import org.apache.logging.log4j.core.net.Advertiser;
34  
35  import java.io.Serializable;
36  import java.util.HashMap;
37  import java.util.Map;
38  
39  /**
40   * An appender that writes to files and can roll over at intervals.
41   */
42  @Plugin(name = "RollingFile", category = "Core", elementType = "appender", printObject = true)
43  public final class RollingFileAppender<T extends Serializable> extends AbstractOutputStreamAppender<T> {
44  
45      private final String fileName;
46      private final String filePattern;
47      private Object advertisement;
48      private final Advertiser advertiser;
49  
50  
51      private RollingFileAppender(final String name, final Layout<T> layout, final Filter filter,
52                                  final RollingFileManager manager, final String fileName,
53                                  final String filePattern, final boolean handleException, final boolean immediateFlush,
54                                  Advertiser advertiser) {
55          super(name, layout, filter, handleException, immediateFlush, manager);
56          if (advertiser != null)
57          {
58              Map<String, String> configuration = new HashMap<String, String>(layout.getContentFormat());
59              configuration.put("contentType", layout.getContentType());
60              configuration.put("name", name);
61              advertisement = advertiser.advertise(configuration);
62          }
63          this.fileName = fileName;
64          this.filePattern = filePattern;
65          this.advertiser = advertiser;
66      }
67  
68      @Override
69      public void stop() {
70          super.stop();
71          if (advertiser != null) {
72              advertiser.unadvertise(advertisement);
73          }
74      }
75  
76      /**
77       * Write the log entry rolling over the file when required.
78  
79       * @param event The LogEvent.
80       */
81      @Override
82      public void append(final LogEvent event) {
83          ((RollingFileManager) getManager()).checkRollover(event);
84          super.append(event);
85      }
86  
87      /**
88       * Returns the File name for the Appender.
89       * @return The file name.
90       */
91      public String getFileName() {
92          return fileName;
93      }
94  
95      /**
96       * Returns the file pattern used when rolling over.
97       * @return The file pattern.
98       */
99      public String getFilePattern() {
100         return filePattern;
101     }
102 
103     /**
104      * Create a RollingFileAppender.
105      * @param fileName The name of the file that is actively written to. (required).
106      * @param filePattern The pattern of the file name to use on rollover. (required).
107      * @param append If true, events are appended to the file. If false, the file
108      * is overwritten when opened. Defaults to "true"
109      * @param name The name of the Appender (required).
110      * @param bufferedIO When true, I/O will be buffered. Defaults to "true".
111      * @param immediateFlush When true, events are immediately flushed. Defaults to "true".
112      * @param policy The triggering policy. (required).
113      * @param strategy The rollover strategy. Defaults to DefaultRolloverStrategy.
114      * @param layout The layout to use (defaults to the default PatternLayout).
115      * @param filter The Filter or null.
116      * @param suppress "true" if exceptions should be hidden from the application, "false" otherwise.
117      * The default is "true".
118      * @param advertise "true" if the appender configuration should be advertised, "false" otherwise.
119      * @param advertiseURI The advertised URI which can be used to retrieve the file contents.
120      * @param config The Configuration.
121      * @return A RollingFileAppender.
122      */
123     @PluginFactory
124     public static <S extends Serializable> RollingFileAppender<S> createAppender(
125                                               @PluginAttr("fileName") final String fileName,
126                                               @PluginAttr("filePattern") final String filePattern,
127                                               @PluginAttr("append") final String append,
128                                               @PluginAttr("name") final String name,
129                                               @PluginAttr("bufferedIO") final String bufferedIO,
130                                               @PluginAttr("immediateFlush") final String immediateFlush,
131                                               @PluginElement("policy") final TriggeringPolicy policy,
132                                               @PluginElement("strategy") RolloverStrategy strategy,
133                                               @PluginElement("layout") Layout<S> layout,
134                                               @PluginElement("filter") final Filter filter,
135                                               @PluginAttr("suppressExceptions") final String suppress,
136                                               @PluginAttr("advertise") final String advertise,
137                                               @PluginAttr("advertiseURI") final String advertiseURI,
138                                               @PluginConfiguration final Configuration config) {
139 
140         final boolean isAppend = append == null ? true : Boolean.valueOf(append);
141         final boolean handleExceptions = suppress == null ? true : Boolean.valueOf(suppress);
142         final boolean isBuffered = bufferedIO == null ? true : Boolean.valueOf(bufferedIO);
143         final boolean isFlush = immediateFlush == null ? true : Boolean.valueOf(immediateFlush);
144         boolean isAdvertise = advertise == null ? false : Boolean.valueOf(advertise);
145         if (name == null) {
146             LOGGER.error("No name provided for FileAppender");
147             return null;
148         }
149 
150         if (fileName == null) {
151             LOGGER.error("No filename was provided for FileAppender with name "  + name);
152             return null;
153         }
154 
155         if (filePattern == null) {
156             LOGGER.error("No filename pattern provided for FileAppender with name "  + name);
157             return null;
158         }
159 
160         if (policy == null) {
161             LOGGER.error("A TriggeringPolicy must be provided");
162             return null;
163         }
164 
165         if (strategy == null) {
166             strategy = DefaultRolloverStrategy.createStrategy(null, null, "true", config);
167         }
168 
169         final RollingFileManager manager = RollingFileManager.getFileManager(fileName, filePattern, isAppend,
170             isBuffered, policy, strategy, advertiseURI);
171         if (manager == null) {
172             return null;
173         }
174 
175         if (layout == null) {
176             @SuppressWarnings({"unchecked", "UnnecessaryLocalVariable"})
177             Layout<S> l = (Layout<S>)PatternLayout.createLayout(null, null, null, null);
178             layout = l;
179         }
180 
181         return new RollingFileAppender<S>(name, layout, filter, manager, fileName, filePattern,
182             handleExceptions, isFlush, isAdvertise ? config.getAdvertiser() : null);
183     }
184 }