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 java.util.HashMap;
20  import java.util.Map;
21  
22  import org.apache.logging.log4j.core.Filter;
23  import org.apache.logging.log4j.core.Layout;
24  import org.apache.logging.log4j.core.LogEvent;
25  import org.apache.logging.log4j.core.config.Configuration;
26  import org.apache.logging.log4j.core.config.plugins.Plugin;
27  import org.apache.logging.log4j.core.config.plugins.PluginAttr;
28  import org.apache.logging.log4j.core.config.plugins.PluginConfiguration;
29  import org.apache.logging.log4j.core.config.plugins.PluginElement;
30  import org.apache.logging.log4j.core.config.plugins.PluginFactory;
31  import org.apache.logging.log4j.core.layout.PatternLayout;
32  import org.apache.logging.log4j.core.net.Advertiser;
33  
34  /**
35   * File Appender.
36   */
37  @Plugin(name = "FastFile", type = "Core", elementType = "appender", printObject = true)
38  public final class FastFileAppender extends AbstractOutputStreamAppender {
39  
40      private final String fileName;
41      private Object advertisement;
42      private final Advertiser advertiser;
43  
44      private FastFileAppender(String name, Layout<?> layout, Filter filter,
45              FastFileManager manager, String filename, boolean handleException,
46              boolean immediateFlush, Advertiser advertiser) {
47          super(name, layout, filter, handleException, immediateFlush, manager);
48          if (advertiser != null) {
49              Map<String, String> configuration = new HashMap<String, String>(
50                      layout.getContentFormat());
51              configuration.putAll(manager.getContentFormat());
52              configuration.put("contentType", layout.getContentType());
53              configuration.put("name", name);
54              advertisement = advertiser.advertise(configuration);
55          }
56          this.fileName = filename;
57          this.advertiser = advertiser;
58      }
59  
60      @Override
61      public void stop() {
62          super.stop();
63          if (advertiser != null) {
64              advertiser.unadvertise(advertisement);
65          }
66      }
67  
68      /**
69       * Write the log entry rolling over the file when required.
70       * 
71       * @param event The LogEvent.
72       */
73      @Override
74      public void append(LogEvent event) {
75  
76          // Leverage the nice batching behaviour of async Loggers/Appenders:
77          // we can signal the file manager that it needs to flush the buffer
78          // to disk at the end of a batch.
79          // From a user's point of view, this means that all log events are
80          // _always_ available in the log file, without incurring the overhead
81          // of immediateFlush=true.
82          ((FastFileManager) getManager()).setEndOfBatch(event.isEndOfBatch());
83          super.append(event);
84      }
85  
86      /**
87       * Returns the file name this appender is associated with.
88       * 
89       * @return The File name.
90       */
91      public String getFileName() {
92          return this.fileName;
93      }
94  
95      // difference from standard File Appender:
96      // locking is not supported and buffering cannot be switched off
97      /**
98       * Create a File Appender.
99       * 
100      * @param fileName The name and path of the file.
101      * @param append "True" if the file should be appended to, "false" if it
102      *            should be overwritten. The default is "true".
103      * @param name The name of the Appender.
104      * @param immediateFlush "true" if the contents should be flushed on every
105      *            write, "false" otherwise. The default is "true".
106      * @param suppress "true" if exceptions should be hidden from the
107      *            application, "false" otherwise. The default is "true".
108      * @param layout The layout to use to format the event. If no layout is
109      *            provided the default PatternLayout will be used.
110      * @param filter The filter, if any, to use.
111      * @param advertise "true" if the appender configuration should be
112      *            advertised, "false" otherwise.
113      * @param advertiseURI The advertised URI which can be used to retrieve the
114      *            file contents.
115      * @param config The Configuration.
116      * @return The FileAppender.
117      */
118     @PluginFactory
119     public static FastFileAppender createAppender(
120             @PluginAttr("fileName") String fileName,
121             @PluginAttr("append") String append,
122             @PluginAttr("name") String name,
123             @PluginAttr("immediateFlush") String immediateFlush,
124             @PluginAttr("suppressExceptions") String suppress,
125             @PluginElement("layout") Layout<?> layout,
126             @PluginElement("filters") final Filter filter,
127             @PluginAttr("advertise") final String advertise,
128             @PluginAttr("advertiseURI") final String advertiseURI,
129             @PluginConfiguration final Configuration config) {
130 
131         boolean isAppend = append == null ? true : Boolean.valueOf(append);
132         boolean isFlush = immediateFlush == null ? true : Boolean
133                 .valueOf(immediateFlush);
134         boolean handleExceptions = suppress == null ? true : Boolean
135                 .valueOf(suppress);
136         boolean isAdvertise = advertise == null ? false : Boolean
137                 .valueOf(advertise);
138 
139         if (name == null) {
140             LOGGER.error("No name provided for FileAppender");
141             return null;
142         }
143 
144         if (fileName == null) {
145             LOGGER.error("No filename provided for FileAppender with name "
146                     + name);
147             return null;
148         }
149 
150         FastFileManager manager = FastFileManager.getFileManager(fileName,
151                 isAppend, isFlush, advertiseURI);
152         if (manager == null) {
153             return null;
154         }
155         if (layout == null) {
156             layout = PatternLayout.createLayout(null, null, null, null);
157         }
158         return new FastFileAppender(name, layout, filter, manager, fileName,
159                 handleExceptions, isFlush, isAdvertise ? config.getAdvertiser()
160                         : null);
161     }
162 }