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 org.apache.logging.log4j.core.Filter;
020    import org.apache.logging.log4j.core.Layout;
021    import org.apache.logging.log4j.core.config.plugins.Plugin;
022    import org.apache.logging.log4j.core.config.plugins.PluginAttr;
023    import org.apache.logging.log4j.core.config.plugins.PluginElement;
024    import org.apache.logging.log4j.core.config.plugins.PluginFactory;
025    import org.apache.logging.log4j.core.layout.PatternLayout;
026    
027    /**
028     * File Appender.
029     */
030    @Plugin(name = "File", type = "Core", elementType = "appender", printObject = true)
031    public final class FileAppender extends AbstractOutputStreamAppender {
032    
033        private final String fileName;
034    
035        private FileAppender(String name, Layout layout, Filter filter, FileManager manager, String filename,
036                            boolean handleException, boolean immediateFlush) {
037            super(name, layout, filter, handleException, immediateFlush, manager);
038            this.fileName = filename;
039        }
040    
041        /**
042         * Returns the file name this appender is associated with.
043         * @return The File name.
044         */
045        public String getFileName() {
046            return this.fileName;
047        }
048    
049        /**
050         * Create a File Appender.
051         * @param fileName The name and path of the file.
052         * @param append "True" if the file should be appended to, "false" if it should be overwritten.
053         * The default is "true".
054         * @param locking "True" if the file should be locked. The default is "false".
055         * @param name The name of the Appender.
056         * @param immediateFlush "true" if the contents should be flushed on every write, "false" otherwise. The default
057         * is "true".
058         * @param suppress "true" if exceptions should be hidden from the application, "false" otherwise.
059         * The default is "true".
060         * @param bufferedIO "true" if I/O should be buffered, "false" otherwise. The default is "true".
061         * @param layout The layout to use to format the event. If no layout is provided the default PatternLayout
062         * will be used.
063         * @param filter The filter, if any, to use.
064         * @return The FileAppender.
065         */
066        @PluginFactory
067        public static FileAppender createAppender(@PluginAttr("fileName") String fileName,
068                                                  @PluginAttr("append") String append,
069                                                  @PluginAttr("locking") String locking,
070                                                  @PluginAttr("name") String name,
071                                                  @PluginAttr("immediateFlush") String immediateFlush,
072                                                  @PluginAttr("suppressExceptions") String suppress,
073                                                  @PluginAttr("bufferedIO") String bufferedIO,
074                                                  @PluginElement("layout") Layout layout,
075                                                  @PluginElement("filters") Filter filter) {
076    
077            boolean isAppend = append == null ? true : Boolean.valueOf(append);
078            boolean isLocking = locking == null ? false : Boolean.valueOf(locking);
079            boolean isBuffered = bufferedIO == null ? true : Boolean.valueOf(bufferedIO);
080            if (isLocking && isBuffered) {
081                if (bufferedIO != null) {
082                    LOGGER.warn("Locking and buffering are mutually exclusive. No buffereing will occur for " + fileName);
083                }
084                isBuffered = false;
085            }
086            boolean isFlush = immediateFlush == null ? true : Boolean.valueOf(immediateFlush);
087            boolean handleExceptions = suppress == null ? true : Boolean.valueOf(suppress);
088    
089            if (name == null) {
090                LOGGER.error("No name provided for FileAppender");
091                return null;
092            }
093    
094            if (fileName == null) {
095                LOGGER.error("No filename provided for FileAppender with name "  + name);
096                return null;
097            }
098    
099            FileManager manager = FileManager.getFileManager(fileName, isAppend, isLocking, isBuffered);
100            if (manager == null) {
101                return null;
102            }
103            if (layout == null) {
104                layout = PatternLayout.createLayout(null, null, null, null);
105            }
106            return new FileAppender(name, layout, filter, manager, fileName, handleExceptions, isFlush);
107        }
108    }