////
    Licensed to the Apache Software Foundation (ASF) under one or more
    contributor license agreements.  See the NOTICE file distributed with
    this work for additional information regarding copyright ownership.
    The ASF licenses this file to You under the Apache License, Version 2.0
    (the "License"); you may not use this file except in compliance with
    the License.  You may obtain a copy of the License at

         http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
////

[#fileappender]
= FileAppender

The `FileAppender` writes log messages to a specified file.
It can append to existing files or overwrite them, depending on the configuration.

The following example shows how to configure the `FileAppender` to write messages to a file.
The file specified is MyApp.log.
The file will be appended to rather than overwritten each time the logging process starts.

[source,xml]
----
<appender name="FileAppender" type="log4net.Appender.FileAppender">
  <file value="MyApp.log" />
  <appendToFile value="true" />
  <layout type="log4net.Layout.PatternLayout">
    <conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
  </layout>
</appender>
----

This example shows how to configure the file name to write to using an environment variable TEMP.
The encoding to use to write to the file is also specified.

[source,xml]
----
<appender name="FileAppender" type="log4net.Appender.FileAppender">
  <file value="${TEMP}/MyApp.log" />
  <appendToFile value="true" />
  <encoding value="unicodeFFFE" />
  <layout type="log4net.Layout.PatternLayout">
    <conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
  </layout>
</appender>
----

This example shows how to configure the appender to use the minimal locking model that allows multiple processes to write to the same file.

[source,xml]
----
<appender name="FileAppender" type="log4net.Appender.FileAppender">
  <file value="MyApp.log" />
  <appendToFile value="true" />
  <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
  <layout type="log4net.Layout.PatternLayout">
    <conversionPattern value="%date [%thread] %-5level %logger %message%newline" />
  </layout>
</appender>
----

[#fileappender-lock-timeout]
== Waiting for the lock

`InterProcessLock` coordinates several processes writing to one file through a named mutex.
The wait for it happens while the appender lock is held, so a lock nobody releases would suspend
every thread logging through the appender.

The wait is therefore bounded by `lockTimeoutMillis`, 10000 by default.
An event that cannot get the lock in time is reported through the error handler and dropped, and the
appender carries on with the next one.
Raise the value when the file is on storage where the lock is legitimately slow to obtain, such as a
network share, or set it to `-1` to wait for as long as it takes.

[source,xml]
----
<appender name="FileAppender" type="log4net.Appender.FileAppender">
  <file value="MyApp.log" />
  <appendToFile value="true" />
  <lockingModel type="log4net.Appender.FileAppender+InterProcessLock">
    <lockTimeoutMillis value="10000" />
  </lockingModel>
  <layout type="log4net.Layout.PatternLayout">
    <conversionPattern value="%date [%thread] %-5level %logger %message%newline" />
  </layout>
</appender>
----

`RollingFileAppender` takes a second mutex around the decision to roll and has its own
`lockTimeoutMillis` for it, with the same default.
An event that cannot get that lock is written to the current file without checking whether it should
roll first, rather than waiting.