## 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.
#set($h1='#')
#set($h2='##')
#set($h3='###')
#set($relVersion=$announceParameters.releaseVersion)
#set($relCount=$announceParameters.releaseCount)
#macro(formatAction $item)
## Use replaceAll to fix up LF-only line ends on Windows.
## Also replace < and > with entity versions to avoid HTML being misinterpreted.
#set($action=$item.action.replaceAll("\n","
").replaceAll("<", "&lt;").replaceAll(">", "&gt;"))
#if($item.issue)
#set($issue = $item.issue)
#set($url = "https://issues.apache.org/jira/browse/$issue")
#else
#set($issue = "")
#end
* #if($issue)[$issue]($url):#end

${action}#if($item.dueTo) Thanks to ${item.dueTo}.#end

#end
## -----------------------------------------
<!---
 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.
-->
$h1 Apache Log4j ${relVersion} Release Notes

The ${developmentTeam} is pleased to announce the Log4j ${relVersion} release!

Apache Log4j is a well known framework for logging application behavior. Log4j 2 is an upgrade
to Log4j that provides significant improvements over its predecessor, Log4j 1.x, and provides
many other modern features such as support for Markers, lambda expressions for lazy logging,
property substitution using Lookups, multiple patterns on a PatternLayout and asynchronous
Loggers. Another notable Log4j 2 feature is the ability to be "garbage-free" (avoid allocating
temporary objects) while logging. In addition, Log4j 2 will not lose events while reconfiguring.

The artifacts may be downloaded from https://logging.apache.org/log4j/2.x/download.html.

This release contains bugfixes and minor enhancements.

Due to a break in compatibility in the SLF4J binding, Log4j now ships with two versions of the SLF4J to Log4j adapters.
log4j-slf4j-impl should be used with SLF4J 1.7.x and earlier and log4j-slf4j18-impl should be used with SLF4J 1.8.x and
later.

Note that the default XML, JSON and YAML formats changed in the 2.11.0 release: they no longer have the "timeMillis"
attribute and instead have an "Instant" element with "epochSecond" and "nanoOfSecond" attributes. If the previous
behavior is desired the "includeTimeMillis" attribute may be set to true on each of the respective Layouts.

The Log4j ${relVersion} API, as well as many core components, maintains binary compatibility with previous releases.

## Hack to improve layout: replace all pairs of spaces with a single new-line
$h2 $release.description.replaceAll("  ", "
")

#if ($release.actions.size() == 0)
No changes defined in this version.
#else
Changes in this version include:

#if ($release.getActions('add').size() !=0)
$h3 New Features
#foreach($actionItem in $release.getActions('add'))
#formatAction($actionItem)
#end
#end

#if ($release.getActions('fix').size() !=0)
$h3 Fixed Bugs
#foreach($actionItem in $release.getActions('fix'))
#formatAction($actionItem)
#end
#end

#if ($release.getActions('update').size() !=0)
$h3 Changes
#foreach($actionItem in $release.getActions('update'))
#formatAction($actionItem)
#end
#end

#if ($release.getActions('remove').size() !=0)
$h3 Removed
#foreach($actionItem in $release.getActions('remove'))
#formatAction($actionItem)
#end
#end
## End of main loop
#end
---

Apache Log4j ${relVersion} requires a minimum of Java 8 to build and run. Log4j 2.3 was the
last release that supported Java 6 and Log4j 2.12.1 is the last release to support Java 7.

For complete information on ${project.name}, including instructions on how to submit bug
reports, patches, or suggestions for improvement, see the Apache ${project.name} website:

${project.url}