blob: da1271cbe3c1118f68342e6741cb4f9241b63643 [file] [log] [blame]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="Asciidoctor 2.0.18">
<title>Log4j Tools</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700">
<style>
/*! Asciidoctor default stylesheet | MIT License | https://asciidoctor.org */
/* Uncomment the following line when using as a custom stylesheet */
/* @import "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700"; */
html{font-family:sans-serif;-webkit-text-size-adjust:100%}
a{background:none}
a:focus{outline:thin dotted}
a:active,a:hover{outline:0}
h1{font-size:2em;margin:.67em 0}
b,strong{font-weight:bold}
abbr{font-size:.9em}
abbr[title]{cursor:help;border-bottom:1px dotted #dddddf;text-decoration:none}
dfn{font-style:italic}
hr{height:0}
mark{background:#ff0;color:#000}
code,kbd,pre,samp{font-family:monospace;font-size:1em}
pre{white-space:pre-wrap}
q{quotes:"\201C" "\201D" "\2018" "\2019"}
small{font-size:80%}
sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}
sup{top:-.5em}
sub{bottom:-.25em}
img{border:0}
svg:not(:root){overflow:hidden}
figure{margin:0}
audio,video{display:inline-block}
audio:not([controls]){display:none;height:0}
fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}
legend{border:0;padding:0}
button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}
button,input{line-height:normal}
button,select{text-transform:none}
button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}
button[disabled],html input[disabled]{cursor:default}
input[type=checkbox],input[type=radio]{padding:0}
button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}
textarea{overflow:auto;vertical-align:top}
table{border-collapse:collapse;border-spacing:0}
*,::before,::after{box-sizing:border-box}
html,body{font-size:100%}
body{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:"Noto Serif","DejaVu Serif",serif;line-height:1;position:relative;cursor:auto;-moz-tab-size:4;-o-tab-size:4;tab-size:4;word-wrap:anywhere;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased}
a:hover{cursor:pointer}
img,object,embed{max-width:100%;height:auto}
object,embed{height:100%}
img{-ms-interpolation-mode:bicubic}
.left{float:left!important}
.right{float:right!important}
.text-left{text-align:left!important}
.text-right{text-align:right!important}
.text-center{text-align:center!important}
.text-justify{text-align:justify!important}
.hide{display:none}
img,object,svg{display:inline-block;vertical-align:middle}
textarea{height:auto;min-height:50px}
select{width:100%}
.subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#7a2518;font-weight:400;margin-top:0;margin-bottom:.25em}
div,dl,dt,dd,ul,ol,li,h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0}
a{color:#2156a5;text-decoration:underline;line-height:inherit}
a:hover,a:focus{color:#1d4b8f}
a img{border:0}
p{line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility}
p aside{font-size:.875em;line-height:1.35;font-style:italic}
h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:"Open Sans","DejaVu Sans",sans-serif;font-weight:300;font-style:normal;color:#ba3925;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.0125em}
h1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{font-size:60%;color:#e99b8f;line-height:0}
h1{font-size:2.125em}
h2{font-size:1.6875em}
h3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em}
h4,h5{font-size:1.125em}
h6{font-size:1em}
hr{border:solid #dddddf;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em}
em,i{font-style:italic;line-height:inherit}
strong,b{font-weight:bold;line-height:inherit}
small{font-size:60%;line-height:inherit}
code{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;color:rgba(0,0,0,.9)}
ul,ol,dl{line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit}
ul,ol{margin-left:1.5em}
ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0}
ul.circle{list-style-type:circle}
ul.disc{list-style-type:disc}
ul.square{list-style-type:square}
ul.circle ul:not([class]),ul.disc ul:not([class]),ul.square ul:not([class]){list-style:inherit}
ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0}
dl dt{margin-bottom:.3125em;font-weight:bold}
dl dd{margin-bottom:1.25em}
blockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd}
blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)}
@media screen and (min-width:768px){h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2}
h1{font-size:2.75em}
h2{font-size:2.3125em}
h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em}
h4{font-size:1.4375em}}
table{background:#fff;margin-bottom:1.25em;border:1px solid #dedede;word-wrap:normal}
table thead,table tfoot{background:#f7f8f7}
table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:.5em .625em .625em;font-size:inherit;color:rgba(0,0,0,.8);text-align:left}
table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)}
table tr.even,table tr.alt{background:#f8f8f7}
table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{line-height:1.6}
h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em}
h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400}
.center{margin-left:auto;margin-right:auto}
.stretch{width:100%}
.clearfix::before,.clearfix::after,.float-group::before,.float-group::after{content:" ";display:table}
.clearfix::after,.float-group::after{clear:both}
:not(pre).nobreak{word-wrap:normal}
:not(pre).nowrap{white-space:nowrap}
:not(pre).pre-wrap{white-space:pre-wrap}
:not(pre):not([class^=L])>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background:#f7f7f8;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed}
pre{color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;line-height:1.45;text-rendering:optimizeSpeed}
pre code,pre pre{color:inherit;font-size:inherit;line-height:inherit}
pre>code{display:block}
pre.nowrap,pre.nowrap pre{white-space:pre;word-wrap:normal}
em em{font-style:normal}
strong strong{font-weight:400}
.keyseq{color:rgba(51,51,51,.8)}
kbd{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;display:inline-block;color:rgba(0,0,0,.8);font-size:.65em;line-height:1.45;background:#f7f7f7;border:1px solid #ccc;border-radius:3px;box-shadow:0 1px 0 rgba(0,0,0,.2),inset 0 0 0 .1em #fff;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap}
.keyseq kbd:first-child{margin-left:0}
.keyseq kbd:last-child{margin-right:0}
.menuseq,.menuref{color:#000}
.menuseq b:not(.caret),.menuref{font-weight:inherit}
.menuseq{word-spacing:-.02em}
.menuseq b.caret{font-size:1.25em;line-height:.8}
.menuseq i.caret{font-weight:bold;text-align:center;width:.45em}
b.button::before,b.button::after{position:relative;top:-1px;font-weight:400}
b.button::before{content:"[";padding:0 3px 0 2px}
b.button::after{content:"]";padding:0 2px 0 3px}
p a>code:hover{color:rgba(0,0,0,.9)}
#header,#content,#footnotes,#footer{width:100%;margin:0 auto;max-width:62.5em;*zoom:1;position:relative;padding-left:.9375em;padding-right:.9375em}
#header::before,#header::after,#content::before,#content::after,#footnotes::before,#footnotes::after,#footer::before,#footer::after{content:" ";display:table}
#header::after,#content::after,#footnotes::after,#footer::after{clear:both}
#content{margin-top:1.25em}
#content::before{content:none}
#header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0}
#header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #dddddf}
#header>h1:only-child,body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #dddddf;padding-bottom:8px}
#header .details{border-bottom:1px solid #dddddf;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:flex;flex-flow:row wrap}
#header .details span:first-child{margin-left:-.125em}
#header .details span.email a{color:rgba(0,0,0,.85)}
#header .details br{display:none}
#header .details br+span::before{content:"\00a0\2013\00a0"}
#header .details br+span.author::before{content:"\00a0\22c5\00a0";color:rgba(0,0,0,.85)}
#header .details br+span#revremark::before{content:"\00a0|\00a0"}
#header #revnumber{text-transform:capitalize}
#header #revnumber::after{content:"\00a0"}
#content>h1:first-child:not([class]){color:rgba(0,0,0,.85);border-bottom:1px solid #dddddf;padding-bottom:8px;margin-top:0;padding-top:1rem;margin-bottom:1.25rem}
#toc{border-bottom:1px solid #e7e7e9;padding-bottom:.5em}
#toc>ul{margin-left:.125em}
#toc ul.sectlevel0>li>a{font-style:italic}
#toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0}
#toc ul{font-family:"Open Sans","DejaVu Sans",sans-serif;list-style-type:none}
#toc li{line-height:1.3334;margin-top:.3334em}
#toc a{text-decoration:none}
#toc a:active{text-decoration:underline}
#toctitle{color:#7a2518;font-size:1.2em}
@media screen and (min-width:768px){#toctitle{font-size:1.375em}
body.toc2{padding-left:15em;padding-right:0}
#toc.toc2{margin-top:0!important;background:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #e7e7e9;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto}
#toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em}
#toc.toc2>ul{font-size:.9em;margin-bottom:0}
#toc.toc2 ul ul{margin-left:0;padding-left:1em}
#toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em}
body.toc2.toc-right{padding-left:0;padding-right:15em}
body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #e7e7e9;left:auto;right:0}}
@media screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0}
#toc.toc2{width:20em}
#toc.toc2 #toctitle{font-size:1.375em}
#toc.toc2>ul{font-size:.95em}
#toc.toc2 ul ul{padding-left:1.25em}
body.toc2.toc-right{padding-left:0;padding-right:20em}}
#content #toc{border:1px solid #e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;border-radius:4px}
#content #toc>:first-child{margin-top:0}
#content #toc>:last-child{margin-bottom:0}
#footer{max-width:none;background:rgba(0,0,0,.8);padding:1.25em}
#footer-text{color:hsla(0,0%,100%,.8);line-height:1.44}
#content{margin-bottom:.625em}
.sect1{padding-bottom:.625em}
@media screen and (min-width:768px){#content{margin-bottom:1.25em}
.sect1{padding-bottom:1.25em}}
.sect1:last-child{padding-bottom:0}
.sect1+.sect1{border-top:1px solid #e7e7e9}
#content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;display:block;text-decoration:none!important;visibility:hidden;text-align:center;font-weight:400}
#content h1>a.anchor::before,h2>a.anchor::before,h3>a.anchor::before,#toctitle>a.anchor::before,.sidebarblock>.content>.title>a.anchor::before,h4>a.anchor::before,h5>a.anchor::before,h6>a.anchor::before{content:"\00A7";font-size:.85em;display:block;padding-top:.1em}
#content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible}
#content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#ba3925;text-decoration:none}
#content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#a53221}
details,.audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em}
details{margin-left:1.25rem}
details>summary{cursor:pointer;display:block;position:relative;line-height:1.6;margin-bottom:.625rem;outline:none;-webkit-tap-highlight-color:transparent}
details>summary::-webkit-details-marker{display:none}
details>summary::before{content:"";border:solid transparent;border-left:solid;border-width:.3em 0 .3em .5em;position:absolute;top:.5em;left:-1.25rem;transform:translateX(15%)}
details[open]>summary::before{border:solid transparent;border-top:solid;border-width:.5em .3em 0;transform:translateY(15%)}
details>summary::after{content:"";width:1.25rem;height:1em;position:absolute;top:.3em;left:-1.25rem}
.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{text-rendering:optimizeLegibility;text-align:left;font-family:"Noto Serif","DejaVu Serif",serif;font-size:1rem;font-style:italic}
table.tableblock.fit-content>caption.title{white-space:nowrap;width:0}
.paragraph.lead>p,#preamble>.sectionbody>[class=paragraph]:first-of-type p{font-size:1.21875em;line-height:1.6;color:rgba(0,0,0,.85)}
.admonitionblock>table{border-collapse:separate;border:0;background:none;width:100%}
.admonitionblock>table td.icon{text-align:center;width:80px}
.admonitionblock>table td.icon img{max-width:none}
.admonitionblock>table td.icon .title{font-weight:bold;font-family:"Open Sans","DejaVu Sans",sans-serif;text-transform:uppercase}
.admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #dddddf;color:rgba(0,0,0,.6);word-wrap:anywhere}
.admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0}
.exampleblock>.content{border:1px solid #e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;border-radius:4px}
.exampleblock>.content>:first-child{margin-top:0}
.exampleblock>.content>:last-child{margin-bottom:0}
.sidebarblock{border:1px solid #dbdbd6;margin-bottom:1.25em;padding:1.25em;background:#f3f3f2;border-radius:4px}
.sidebarblock>:first-child{margin-top:0}
.sidebarblock>:last-child{margin-bottom:0}
.sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center}
.exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0}
.literalblock pre,.listingblock>.content>pre{border-radius:4px;overflow-x:auto;padding:1em;font-size:.8125em}
@media screen and (min-width:768px){.literalblock pre,.listingblock>.content>pre{font-size:.90625em}}
@media screen and (min-width:1280px){.literalblock pre,.listingblock>.content>pre{font-size:1em}}
.literalblock pre,.listingblock>.content>pre:not(.highlight),.listingblock>.content>pre[class=highlight],.listingblock>.content>pre[class^="highlight "]{background:#f7f7f8}
.literalblock.output pre{color:#f7f7f8;background:rgba(0,0,0,.9)}
.listingblock>.content{position:relative}
.listingblock code[data-lang]::before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:inherit;opacity:.5}
.listingblock:hover code[data-lang]::before{display:block}
.listingblock.terminal pre .command::before{content:attr(data-prompt);padding-right:.5em;color:inherit;opacity:.5}
.listingblock.terminal pre .command:not([data-prompt])::before{content:"$"}
.listingblock pre.highlightjs{padding:0}
.listingblock pre.highlightjs>code{padding:1em;border-radius:4px}
.listingblock pre.prettyprint{border-width:0}
.prettyprint{background:#f7f7f8}
pre.prettyprint .linenums{line-height:1.45;margin-left:2em}
pre.prettyprint li{background:none;list-style-type:inherit;padding-left:0}
pre.prettyprint li code[data-lang]::before{opacity:1}
pre.prettyprint li:not(:first-child) code[data-lang]::before{display:none}
table.linenotable{border-collapse:separate;border:0;margin-bottom:0;background:none}
table.linenotable td[class]{color:inherit;vertical-align:top;padding:0;line-height:inherit;white-space:normal}
table.linenotable td.code{padding-left:.75em}
table.linenotable td.linenos,pre.pygments .linenos{border-right:1px solid;opacity:.35;padding-right:.5em;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}
pre.pygments span.linenos{display:inline-block;margin-right:.75em}
.quoteblock{margin:0 1em 1.25em 1.5em;display:table}
.quoteblock:not(.excerpt)>.title{margin-left:-1.5em;margin-bottom:.75em}
.quoteblock blockquote,.quoteblock p{color:rgba(0,0,0,.85);font-size:1.15rem;line-height:1.75;word-spacing:.1em;letter-spacing:0;font-style:italic;text-align:justify}
.quoteblock blockquote{margin:0;padding:0;border:0}
.quoteblock blockquote::before{content:"\201c";float:left;font-size:2.75em;font-weight:bold;line-height:.6em;margin-left:-.6em;color:#7a2518;text-shadow:0 1px 2px rgba(0,0,0,.1)}
.quoteblock blockquote>.paragraph:last-child p{margin-bottom:0}
.quoteblock .attribution{margin-top:.75em;margin-right:.5ex;text-align:right}
.verseblock{margin:0 1em 1.25em}
.verseblock pre{font-family:"Open Sans","DejaVu Sans",sans-serif;font-size:1.15rem;color:rgba(0,0,0,.85);font-weight:300;text-rendering:optimizeLegibility}
.verseblock pre strong{font-weight:400}
.verseblock .attribution{margin-top:1.25rem;margin-left:.5ex}
.quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic}
.quoteblock .attribution br,.verseblock .attribution br{display:none}
.quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.025em;color:rgba(0,0,0,.6)}
.quoteblock.abstract blockquote::before,.quoteblock.excerpt blockquote::before,.quoteblock .quoteblock blockquote::before{display:none}
.quoteblock.abstract blockquote,.quoteblock.abstract p,.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{line-height:1.6;word-spacing:0}
.quoteblock.abstract{margin:0 1em 1.25em;display:block}
.quoteblock.abstract>.title{margin:0 0 .375em;font-size:1.15em;text-align:center}
.quoteblock.excerpt>blockquote,.quoteblock .quoteblock{padding:0 0 .25em 1em;border-left:.25em solid #dddddf}
.quoteblock.excerpt,.quoteblock .quoteblock{margin-left:0}
.quoteblock.excerpt blockquote,.quoteblock.excerpt p,.quoteblock .quoteblock blockquote,.quoteblock .quoteblock p{color:inherit;font-size:1.0625rem}
.quoteblock.excerpt .attribution,.quoteblock .quoteblock .attribution{color:inherit;font-size:.85rem;text-align:left;margin-right:0}
p.tableblock:last-child{margin-bottom:0}
td.tableblock>.content{margin-bottom:1.25em;word-wrap:anywhere}
td.tableblock>.content>:last-child{margin-bottom:-1.25em}
table.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede}
table.grid-all>*>tr>*{border-width:1px}
table.grid-cols>*>tr>*{border-width:0 1px}
table.grid-rows>*>tr>*{border-width:1px 0}
table.frame-all{border-width:1px}
table.frame-ends{border-width:1px 0}
table.frame-sides{border-width:0 1px}
table.frame-none>colgroup+*>:first-child>*,table.frame-sides>colgroup+*>:first-child>*{border-top-width:0}
table.frame-none>:last-child>:last-child>*,table.frame-sides>:last-child>:last-child>*{border-bottom-width:0}
table.frame-none>*>tr>:first-child,table.frame-ends>*>tr>:first-child{border-left-width:0}
table.frame-none>*>tr>:last-child,table.frame-ends>*>tr>:last-child{border-right-width:0}
table.stripes-all>*>tr,table.stripes-odd>*>tr:nth-of-type(odd),table.stripes-even>*>tr:nth-of-type(even),table.stripes-hover>*>tr:hover{background:#f8f8f7}
th.halign-left,td.halign-left{text-align:left}
th.halign-right,td.halign-right{text-align:right}
th.halign-center,td.halign-center{text-align:center}
th.valign-top,td.valign-top{vertical-align:top}
th.valign-bottom,td.valign-bottom{vertical-align:bottom}
th.valign-middle,td.valign-middle{vertical-align:middle}
table thead th,table tfoot th{font-weight:bold}
tbody tr th{background:#f7f8f7}
tbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:rgba(0,0,0,.8);font-weight:bold}
p.tableblock>code:only-child{background:none;padding:0}
p.tableblock{font-size:1em}
ol{margin-left:1.75em}
ul li ol{margin-left:1.5em}
dl dd{margin-left:1.125em}
dl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0}
li p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:.625em}
ul.checklist,ul.none,ol.none,ul.no-bullet,ol.no-bullet,ol.unnumbered,ul.unstyled,ol.unstyled{list-style-type:none}
ul.no-bullet,ol.no-bullet,ol.unnumbered{margin-left:.625em}
ul.unstyled,ol.unstyled{margin-left:0}
li>p:empty:only-child::before{content:"";display:inline-block}
ul.checklist>li>p:first-child{margin-left:-1em}
ul.checklist>li>p:first-child>.fa-square-o:first-child,ul.checklist>li>p:first-child>.fa-check-square-o:first-child{width:1.25em;font-size:.8em;position:relative;bottom:.125em}
ul.checklist>li>p:first-child>input[type=checkbox]:first-child{margin-right:.25em}
ul.inline{display:flex;flex-flow:row wrap;list-style:none;margin:0 0 .625em -1.25em}
ul.inline>li{margin-left:1.25em}
.unstyled dl dt{font-weight:400;font-style:normal}
ol.arabic{list-style-type:decimal}
ol.decimal{list-style-type:decimal-leading-zero}
ol.loweralpha{list-style-type:lower-alpha}
ol.upperalpha{list-style-type:upper-alpha}
ol.lowerroman{list-style-type:lower-roman}
ol.upperroman{list-style-type:upper-roman}
ol.lowergreek{list-style-type:lower-greek}
.hdlist>table,.colist>table{border:0;background:none}
.hdlist>table>tbody>tr,.colist>table>tbody>tr{background:none}
td.hdlist1,td.hdlist2{vertical-align:top;padding:0 .625em}
td.hdlist1{font-weight:bold;padding-bottom:1.25em}
td.hdlist2{word-wrap:anywhere}
.literalblock+.colist,.listingblock+.colist{margin-top:-.5em}
.colist td:not([class]):first-child{padding:.4em .75em 0;line-height:1;vertical-align:top}
.colist td:not([class]):first-child img{max-width:none}
.colist td:not([class]):last-child{padding:.25em 0}
.thumb,.th{line-height:0;display:inline-block;border:4px solid #fff;box-shadow:0 0 0 1px #ddd}
.imageblock.left{margin:.25em .625em 1.25em 0}
.imageblock.right{margin:.25em 0 1.25em .625em}
.imageblock>.title{margin-bottom:0}
.imageblock.thumb,.imageblock.th{border-width:6px}
.imageblock.thumb>.title,.imageblock.th>.title{padding:0 .125em}
.image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0}
.image.left{margin-right:.625em}
.image.right{margin-left:.625em}
a.image{text-decoration:none;display:inline-block}
a.image object{pointer-events:none}
sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super}
sup.footnote a,sup.footnoteref a{text-decoration:none}
sup.footnote a:active,sup.footnoteref a:active{text-decoration:underline}
#footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em}
#footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em;border-width:1px 0 0}
#footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;margin-bottom:.2em}
#footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none;margin-left:-1.05em}
#footnotes .footnote:last-of-type{margin-bottom:0}
#content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0}
div.unbreakable{page-break-inside:avoid}
.big{font-size:larger}
.small{font-size:smaller}
.underline{text-decoration:underline}
.overline{text-decoration:overline}
.line-through{text-decoration:line-through}
.aqua{color:#00bfbf}
.aqua-background{background:#00fafa}
.black{color:#000}
.black-background{background:#000}
.blue{color:#0000bf}
.blue-background{background:#0000fa}
.fuchsia{color:#bf00bf}
.fuchsia-background{background:#fa00fa}
.gray{color:#606060}
.gray-background{background:#7d7d7d}
.green{color:#006000}
.green-background{background:#007d00}
.lime{color:#00bf00}
.lime-background{background:#00fa00}
.maroon{color:#600000}
.maroon-background{background:#7d0000}
.navy{color:#000060}
.navy-background{background:#00007d}
.olive{color:#606000}
.olive-background{background:#7d7d00}
.purple{color:#600060}
.purple-background{background:#7d007d}
.red{color:#bf0000}
.red-background{background:#fa0000}
.silver{color:#909090}
.silver-background{background:#bcbcbc}
.teal{color:#006060}
.teal-background{background:#007d7d}
.white{color:#bfbfbf}
.white-background{background:#fafafa}
.yellow{color:#bfbf00}
.yellow-background{background:#fafa00}
span.icon>.fa{cursor:default}
a span.icon>.fa{cursor:inherit}
.admonitionblock td.icon [class^="fa icon-"]{font-size:2.5em;text-shadow:1px 1px 2px rgba(0,0,0,.5);cursor:default}
.admonitionblock td.icon .icon-note::before{content:"\f05a";color:#19407c}
.admonitionblock td.icon .icon-tip::before{content:"\f0eb";text-shadow:1px 1px 2px rgba(155,155,0,.8);color:#111}
.admonitionblock td.icon .icon-warning::before{content:"\f071";color:#bf6900}
.admonitionblock td.icon .icon-caution::before{content:"\f06d";color:#bf3400}
.admonitionblock td.icon .icon-important::before{content:"\f06a";color:#bf0000}
.conum[data-value]{display:inline-block;color:#fff!important;background:rgba(0,0,0,.8);border-radius:50%;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans","DejaVu Sans",sans-serif;font-style:normal;font-weight:bold}
.conum[data-value] *{color:#fff!important}
.conum[data-value]+b{display:none}
.conum[data-value]::after{content:attr(data-value)}
pre .conum[data-value]{position:relative;top:-.125em}
b.conum *{color:inherit!important}
.conum:not([data-value]):empty{display:none}
dt,th.tableblock,td.content,div.footnote{text-rendering:optimizeLegibility}
h1,h2,p,td.content,span.alt,summary{letter-spacing:-.01em}
p strong,td.content strong,div.footnote strong{letter-spacing:-.005em}
p,blockquote,dt,td.content,span.alt,summary{font-size:1.0625rem}
p{margin-bottom:1.25rem}
.sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em}
.exampleblock>.content{background:#fffef7;border-color:#e0e0dc;box-shadow:0 1px 4px #e0e0dc}
.print-only{display:none!important}
@page{margin:1.25cm .75cm}
@media print{*{box-shadow:none!important;text-shadow:none!important}
html{font-size:80%}
a{color:inherit!important;text-decoration:underline!important}
a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important}
a[href^="http:"]:not(.bare)::after,a[href^="https:"]:not(.bare)::after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em}
abbr[title]{border-bottom:1px dotted}
abbr[title]::after{content:" (" attr(title) ")"}
pre,blockquote,tr,img,object,svg{page-break-inside:avoid}
thead{display:table-header-group}
svg{max-width:100%}
p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3}
h2,h3,#toctitle,.sidebarblock>.content>.title{page-break-after:avoid}
#header,#content,#footnotes,#footer{max-width:none}
#toc,.sidebarblock,.exampleblock>.content{background:none!important}
#toc{border-bottom:1px solid #dddddf!important;padding-bottom:0!important}
body.book #header{text-align:center}
body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em}
body.book #header .details{border:0!important;display:block;padding:0!important}
body.book #header .details span:first-child{margin-left:0!important}
body.book #header .details br{display:block}
body.book #header .details br+span::before{content:none!important}
body.book #toc{border:0!important;text-align:left!important;padding:0!important;margin:0!important}
body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-break-before:always}
.listingblock code[data-lang]::before{display:block}
#footer{padding:0 .9375em}
.hide-on-print{display:none!important}
.print-only{display:block!important}
.hide-for-print{display:none!important}
.show-for-print{display:inherit!important}}
@media amzn-kf8,print{#header>h1:first-child{margin-top:1.25rem}
.sect1{padding:0!important}
.sect1+.sect1{border:0}
#footer{background:none}
#footer-text{color:rgba(0,0,0,.6);font-size:.9em}}
@media amzn-kf8{#header,#content,#footnotes,#footer{padding:0}}
</style>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<style>
/*! Stylesheet for CodeRay to loosely match GitHub themes | MIT License */
pre.CodeRay{background:#f7f7f8}
.CodeRay .line-numbers{border-right:1px solid;opacity:.35;padding:0 .5em 0 0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}
.CodeRay span.line-numbers{display:inline-block;margin-right:.75em}
.CodeRay .line-numbers strong{color:#000}
table.CodeRay{border-collapse:separate;border:0;margin-bottom:0;background:none}
table.CodeRay td{vertical-align:top;line-height:inherit}
table.CodeRay td.line-numbers{text-align:right}
table.CodeRay td.code{padding:0 0 0 .75em}
.CodeRay .debug{color:#fff!important;background:navy!important}
.CodeRay .annotation{color:#007}
.CodeRay .attribute-name{color:navy}
.CodeRay .attribute-value{color:#700}
.CodeRay .binary{color:#509}
.CodeRay .comment{color:#998;font-style:italic}
.CodeRay .char{color:#04d}
.CodeRay .char .content{color:#04d}
.CodeRay .char .delimiter{color:#039}
.CodeRay .class{color:#458;font-weight:bold}
.CodeRay .complex{color:#a08}
.CodeRay .constant,.CodeRay .predefined-constant{color:teal}
.CodeRay .color{color:#099}
.CodeRay .class-variable{color:#369}
.CodeRay .decorator{color:#b0b}
.CodeRay .definition{color:#099}
.CodeRay .delimiter{color:#000}
.CodeRay .doc{color:#970}
.CodeRay .doctype{color:#34b}
.CodeRay .doc-string{color:#d42}
.CodeRay .escape{color:#666}
.CodeRay .entity{color:#800}
.CodeRay .error{color:#808}
.CodeRay .exception{color:inherit}
.CodeRay .filename{color:#099}
.CodeRay .function{color:#900;font-weight:bold}
.CodeRay .global-variable{color:teal}
.CodeRay .hex{color:#058}
.CodeRay .integer,.CodeRay .float{color:#099}
.CodeRay .include{color:#555}
.CodeRay .inline{color:#000}
.CodeRay .inline .inline{background:#ccc}
.CodeRay .inline .inline .inline{background:#bbb}
.CodeRay .inline .inline-delimiter{color:#d14}
.CodeRay .inline-delimiter{color:#d14}
.CodeRay .important{color:#555;font-weight:bold}
.CodeRay .interpreted{color:#b2b}
.CodeRay .instance-variable{color:teal}
.CodeRay .label{color:#970}
.CodeRay .local-variable{color:#963}
.CodeRay .octal{color:#40e}
.CodeRay .predefined{color:#369}
.CodeRay .preprocessor{color:#579}
.CodeRay .pseudo-class{color:#555}
.CodeRay .directive{font-weight:bold}
.CodeRay .type{font-weight:bold}
.CodeRay .predefined-type{color:inherit}
.CodeRay .reserved,.CodeRay .keyword{color:#000;font-weight:bold}
.CodeRay .key{color:#808}
.CodeRay .key .delimiter{color:#606}
.CodeRay .key .char{color:#80f}
.CodeRay .value{color:#088}
.CodeRay .regexp .delimiter{color:#808}
.CodeRay .regexp .content{color:#808}
.CodeRay .regexp .modifier{color:#808}
.CodeRay .regexp .char{color:#d14}
.CodeRay .regexp .function{color:#404;font-weight:bold}
.CodeRay .string{color:#d20}
.CodeRay .string .string .string{background:#ffd0d0}
.CodeRay .string .content{color:#d14}
.CodeRay .string .char{color:#d14}
.CodeRay .string .delimiter{color:#d14}
.CodeRay .shell{color:#d14}
.CodeRay .shell .delimiter{color:#d14}
.CodeRay .symbol{color:#990073}
.CodeRay .symbol .content{color:#a60}
.CodeRay .symbol .delimiter{color:#630}
.CodeRay .tag{color:teal}
.CodeRay .tag-special{color:#d70}
.CodeRay .variable{color:#036}
.CodeRay .insert{background:#afa}
.CodeRay .delete{background:#faa}
.CodeRay .change{color:#aaf;background:#007}
.CodeRay .head{color:#f8f;background:#505}
.CodeRay .insert .insert{color:#080}
.CodeRay .delete .delete{color:#800}
.CodeRay .change .change{color:#66f}
.CodeRay .head .head{color:#f4f}
</style>
</head>
<body class="article toc2 toc-left">
<div id="header">
<h1>Log4j Tools</h1>
<div id="toc" class="toc2">
<div id="toctitle">Table of Contents</div>
<ul class="sectlevel1">
<li><a href="#log4j-changelog">Log4j Changelog</a>
<ul class="sectlevel2">
<li><a href="#log4j-changelog-dependencies">Dependencies</a></li>
<li><a href="#log4j-changelog-what-is-a-changelog">What is a changelog?</a></li>
<li><a href="#log4j-changelog-why-different">Why yet another changelog tool?</a></li>
<li><a href="#log4j-changelog-look">What does it look like?</a></li>
<li><a href="#log4j-changelog-release-entry-file">Release entry file</a></li>
<li><a href="#log4j-changelog-changelog-entry-file">Changelog entry file</a></li>
<li><a href="#log4j-changelog-export">Exporting changelogs</a></li>
<li><a href="#log4j-changelog-qa">Q&amp;A</a></li>
</ul>
</li>
<li><a href="#log4j-changelog-maven-plugin">Log4j Changelog Maven Plugin</a>
<ul class="sectlevel2">
<li><a href="#log4j-changelog-maven-plugin-dependencies">Dependencies</a></li>
<li><a href="#log4j-changelog-maven-plugin-export">Exporting changelogs</a></li>
<li><a href="#log4j-changelog-maven-plugin-release">Populating a release changelog directory</a></li>
</ul>
</li>
<li><a href="#log4j-docgen">Log4j Docgen</a>
<ul class="sectlevel2">
<li><a href="#log4j-docgen-dependencies">Dependencies</a></li>
<li><a href="#log4j-docgen-descriptor-generator">Descriptor generator</a></li>
<li><a href="#log4j-docgen-documentation-generator">Documentation generator</a></li>
<li><a href="#log4j-docgen-schema-generator">Schema generator</a></li>
</ul>
</li>
<li><a href="#log4j-docgen-maven-plugin">Log4j Docgen Maven Plugin</a>
<ul class="sectlevel2">
<li><a href="#log4j-docgen-maven-plugin-dependencies">Dependencies</a></li>
<li><a href="#log4j-docgen-maven-plugin-generate-documentation">Generate documentation</a></li>
<li><a href="#log4j-docgen-maven-plugin-generate-schema">Generate schema</a></li>
</ul>
</li>
<li><a href="#log4j-docgen-asciidoctor-extension">Log4j Docgen AsciiDoctor extension</a></li>
<li><a href="#development">Development</a></li>
<li><a href="#distribution">Distribution</a>
<ul class="sectlevel2">
<li><a href="#maven-bom">Maven Bill of Materials (BOM)</a></li>
<li><a href="#cyclonedx-sbom">CycloneDX Software Bill of Materials (SBOM)</a></li>
</ul>
</li>
<li><a href="#support">Support</a></li>
<li><a href="#security">Security</a></li>
<li><a href="#release-notes">Release Notes</a>
<ul class="sectlevel2">
<li><a href="#release-notes-0-8-0">0.8.0</a></li>
<li><a href="#release-notes-0-7-0">0.7.0</a></li>
<li><a href="#release-notes-0-6-0">0.6.0</a></li>
<li><a href="#release-notes-0-5-0">0.5.0</a></li>
<li><a href="#release-notes-0-4-0">0.4.0</a></li>
<li><a href="#release-notes-0-3-0">0.3.0</a></li>
<li><a href="#release-notes-0-2-0">0.2.0</a></li>
<li><a href="#release-notes-0-1-0">0.1.0</a></li>
</ul>
</li>
<li><a href="#release-instructions">Release instructions</a></li>
<li><a href="#license">License</a></li>
</ul>
</div>
</div>
<div id="content">
<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>Tooling <strong>internally</strong> used by <a href="https://logging.apache.org/log4j/2.x/">the Apache Log4j project</a> infrastructure.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="log4j-changelog">Log4j Changelog</h2>
<div class="sectionbody">
<div class="paragraph">
<p>This project contains tools to maintain changelogs.
It is designed for Apache Log4j, but can be used for any Java project.</p>
</div>
<div class="sect2">
<h3 id="log4j-changelog-dependencies">Dependencies</h3>
<div class="paragraph">
<p>You need to have the <code>org.apache.logging.log4j:log4j-changelog</code> dependency in your classpath:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="xml"><span class="tag">&lt;dependency&gt;</span>
<span class="tag">&lt;groupId&gt;</span>org.apache.logging.log4j<span class="tag">&lt;/groupId&gt;</span>
<span class="tag">&lt;artifactId&gt;</span>log4j-changelog<span class="tag">&lt;/artifactId&gt;</span>
<span class="tag">&lt;version&gt;</span>0.8.0<span class="tag">&lt;/version&gt;</span>
<span class="tag">&lt;/dependency&gt;</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Java module name and OSGi <code>Bundle-SymbolicName</code> are set to <code>org.apache.logging.log4j.changelog</code>.</p>
</div>
</div>
<div class="sect2">
<h3 id="log4j-changelog-what-is-a-changelog">What is a changelog?</h3>
<div class="paragraph">
<p>A changelog is a log of all notable changes made to a project.</p>
</div>
</div>
<div class="sect2">
<h3 id="log4j-changelog-why-different">Why yet another changelog tool?</h3>
<div class="paragraph">
<p>Existing changelog practices (e.g., <a href="https://keepachangelog.com">Keep a changelog</a>, <a href="https://maven.apache.org/plugins/maven-changes-plugin/">maven-changes-plugin</a>) store changelog entries in the same file.
This creates merge conflicts between different branches.
Imagine multiple people working on multiple branches each containing a change to <code>CHANGELOG.md</code>.
Whoever succeeds in merging their branch to <code>main</code> first will cause a merge-conflict for the others, even though their work might be totally unrelated from each other.</p>
</div>
<div class="paragraph">
<p>This project embraces a model where changelog entries are kept in separate files and hence are not prone to merge conflicts.
Similar to <code>maven-changes-plugin</code>, changelog sources and their exports (e.g., AsciiDoc-formatted) are split by design.</p>
</div>
</div>
<div class="sect2">
<h3 id="log4j-changelog-look">What does it look like?</h3>
<div class="paragraph">
<p>All changelog <em>sources</em> and templates used to <em>export</em> them are stored in folders under <em>the changelog directory</em> (e.g., <code>/src/changelog</code>):</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code>$ tree -a src/changelog
├── 2.18.0 <i class="conum" data-value="1"></i><b>(1)</b>
│ ├── LOG4J2-3424_Properties_defined_in_configuration_using_a_value_attribute.xml <i class="conum" data-value="4"></i><b>(4)</b>
│ ├── LOG4J2-3425_Syslog_appender_lacks_the_SocketOptions_setting.xml <i class="conum" data-value="4"></i><b>(4)</b>
│ ├── LOG4J2-3426_Log4j_1_2_bridge_should_not_wrap_components_unnecessarily.xml <i class="conum" data-value="4"></i><b>(4)</b>
│ ├── LOG4J2-3427_Improves_ServiceLoader_support_on_servlet_containers.xml <i class="conum" data-value="4"></i><b>(4)</b>
│ ├── .release-notes.adoc.ftl <i class="conum" data-value="5"></i><b>(5)</b>
│ └── .release.xml <i class="conum" data-value="3"></i><b>(3)</b>
├── 2.19.0 <i class="conum" data-value="1"></i><b>(1)</b>
│ ├── LOG4J2-3588_Allow_PropertySources_to_be_added.xml <i class="conum" data-value="4"></i><b>(4)</b>
│ ├── LOG4J2-3590_Remove_SLF4J_1_8_x_binding.xml <i class="conum" data-value="4"></i><b>(4)</b>
│ ├── LOG4J2-3614_Harden_InstantFormatter_against_delegate_failures.xml <i class="conum" data-value="4"></i><b>(4)</b>
│ ├── LOG4J2-3556_JsonTemplateLayout_stack_trace_truncation_fix.xml <i class="conum" data-value="4"></i><b>(4)</b>
│ ├── .release-notes.adoc.ftl <i class="conum" data-value="5"></i><b>(5)</b>
│ └── .release.xml <i class="conum" data-value="3"></i><b>(3)</b>
├── .2.x.x <i class="conum" data-value="2"></i><b>(2)</b>
│ ├── LOG4J2-1284_redirect_old_javadoc_urls.xml <i class="conum" data-value="4"></i><b>(4)</b>
│ └── .release-notes.adoc.ftl <i class="conum" data-value="5"></i><b>(5)</b>
├── .changelog.adoc.ftl <i class="conum" data-value="5"></i><b>(5)</b>
└── .index.adoc.ftl <i class="conum" data-value="5"></i><b>(5)</b></code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>Changelog sources of <em>released versions</em> are stored in <code>&lt;changelogDirectory&gt;/&lt;releaseVersion&gt;</code> folders (e.g., <code>src/changelog/2.19.0</code>)</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>Changelog sources of <em>upcoming releases</em> are stored in <code>&lt;changelogDirectory&gt;/.&lt;releaseVersionMajor&gt;.x.x</code> folders (e.g., <code>/src/changelog/.2.x.x</code>)</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b>3</b></td>
<td><code>.release.xml</code> contains the information about the associated release.
Note that upcoming release folders (e.g., <code>src/changelog/.2.x.x</code>) don&#8217;t contain a <code>.release.xml</code>, since these releases are by definition not done yet.</td>
</tr>
<tr>
<td><i class="conum" data-value="4"></i><b>4</b></td>
<td>All XML files not prefixed with a <code>.</code> (e.g., <code>src/changelog/.2.x.x/LOG4J2-3628_new_changelog_infra.xml</code>) constitute changelog entries</td>
</tr>
<tr>
<td><i class="conum" data-value="5"></i><b>5</b></td>
<td><a href="https://freemarker.apache.org">FreeMarker</a> templates are used to <em>export</em> this information to various forms; AsciiDoc-formatted pages for the website, Markdown-formatted files for GitHub Releases, etc.</td>
</tr>
</table>
</div>
</div>
<div class="sect2">
<h3 id="log4j-changelog-release-entry-file">Release entry file</h3>
<div class="paragraph">
<p>A release entry file, <code>.release.xml</code>, consists of meta information regarding a particular release.
A sample <em>release entry</em> file is shared below.</p>
</div>
<div class="listingblock">
<div class="title"><code>src/changelog/2.19.0/release.xml</code> file contents</div>
<div class="content">
<pre class="CodeRay highlight"><code data-lang="xml"><span class="preprocessor">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;</span>
<span class="tag">&lt;release</span> <span class="attribute-name">xmlns</span>=<span class="string"><span class="delimiter">&quot;</span><span class="content">https://logging.apache.org/xml/ns</span><span class="delimiter">&quot;</span></span>
<span class="attribute-name">xmlns:xsi</span>=<span class="string"><span class="delimiter">&quot;</span><span class="content">http://www.w3.org/2001/XMLSchema-instance</span><span class="delimiter">&quot;</span></span>
<span class="attribute-name">xsi:schemaLocation</span>=<span class="string"><span class="delimiter">&quot;</span>
<span class="content">https://logging.apache.org/xml/ns</span>
<span class="content">https://logging.apache.org/xml/ns/log4j-changelog-0.xsd</span>
<span class="content">date=</span><span class="delimiter">&quot;</span></span><span class="attribute-name">2022-09-09</span><span class="error">&quot;</span>
<span class="attribute-name">version</span>=<span class="string"><span class="delimiter">&quot;</span><span class="content">2.19.0</span><span class="delimiter">&quot;</span></span><span class="tag">/&gt;</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Note that upcoming release folders (e.g., <code>src/changelog/.2.x.x</code>) don&#8217;t contain a <code>.release.xml</code>, since these releases are by definition not done yet.</p>
</div>
</div>
<div class="sect2">
<h3 id="log4j-changelog-changelog-entry-file">Changelog entry file</h3>
<div class="paragraph">
<p>A changelog entry file consists of short meta information regarding a particular change.
They are named following the <code>[&lt;issueId&gt;_]&lt;shortSummary&gt;.xml</code> pattern.
Consider the following examples:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>LOG4J2-3556_JsonTemplateLayout_stack_trace_truncation_fix.xml</code></p>
</li>
<li>
<p><code>LOG4J2-3578_Generate_new_SSL_certs_for_testing.xml</code></p>
</li>
<li>
<p><code>Update_jackson_2_11_0_2_11_2.xml</code></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>A sample <em>changelog entry</em> file is shared below.</p>
</div>
<div class="listingblock">
<div class="title"><code>src/changelog/2.19.0/LOG4J2-3556_JsonTemplateLayout_stack_trace_truncation_fix.xml</code> file contents</div>
<div class="content">
<pre class="CodeRay highlight"><code data-lang="xml"><span class="tag">&lt;entry</span> <span class="attribute-name">xmlns</span>=<span class="string"><span class="delimiter">&quot;</span><span class="content">https://logging.apache.org/xml/ns</span><span class="delimiter">&quot;</span></span>
<span class="attribute-name">xmlns:xsi</span>=<span class="string"><span class="delimiter">&quot;</span><span class="content">http://www.w3.org/2001/XMLSchema-instance</span><span class="delimiter">&quot;</span></span>
<span class="attribute-name">xsi:schemaLocation</span>=<span class="string"><span class="delimiter">&quot;</span>
<span class="content">https://logging.apache.org/xml/ns</span>
<span class="content">https://logging.apache.org/xml/ns/log4j-changelog-0.xsd</span>
<span class="content">type=</span><span class="delimiter">&quot;</span></span><span class="attribute-name">fixed</span><span class="error">&quot;</span><span class="tag">&gt;</span>
<span class="tag">&lt;issue</span> <span class="attribute-name">id</span>=<span class="string"><span class="delimiter">&quot;</span><span class="content">LOG4J2-3556</span><span class="delimiter">&quot;</span></span> <span class="attribute-name">link</span>=<span class="string"><span class="delimiter">&quot;</span><span class="content">https://issues.apache.org/jira/browse/LOG4J2-3556</span><span class="delimiter">&quot;</span></span><span class="tag">/&gt;</span>
<span class="tag">&lt;description</span> <span class="attribute-name">format</span>=<span class="string"><span class="delimiter">&quot;</span><span class="content">asciidoc</span><span class="delimiter">&quot;</span></span><span class="tag">&gt;</span>
Make `JsonTemplateLayout` stack trace truncation operate for each label block
<span class="tag">&lt;/description&gt;</span>
<span class="tag">&lt;/entry&gt;</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>Some remarks about the structure of changelog entry files:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>The root element must be named <code>entry</code></p>
</li>
<li>
<p><code>entry.type</code> attribute is required and must be one of the change types:</p>
<div class="ulist">
<ul>
<li>
<p><code>added</code> – for new features</p>
</li>
<li>
<p><code>changed</code> – for changes in existing functionality</p>
</li>
<li>
<p><code>deprecated</code> – for soon-to-be removed features</p>
</li>
<li>
<p><code>fixed</code> – for any bug fixes</p>
</li>
<li>
<p><code>removed</code> – for now removed features</p>
</li>
<li>
<p><code>updated</code> – for dependency updates</p>
</li>
</ul>
</div>
</li>
<li>
<p><code>issue</code> element is optional, can occur multiple times, and, if present, must contain <code>id</code> and <code>link</code> attributes</p>
</li>
<li>
<p>There must be a single <code>description</code> element with non-blank content and <code>format</code> attribute</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="log4j-changelog-export">Exporting changelogs</h3>
<div class="paragraph">
<p><em>Exporting</em> changelogs is the act of feeding provided changelog and release information into <a href="https://freemarker.apache.org">FreeMarker</a> templates to generate certain files; e.g., release notes for the website.
There are two types template files supported:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1"><a href="#log4j-changelog-changelog-template">Changelog templates</a></dt>
<dd>
<p>These templates are rendered with the release and changelog information of a particular release.
These are generally used to generate release notes for a particular release.</p>
</dd>
<dt class="hdlist1"><a href="#log4j-changelog-index-template">Index templates</a></dt>
<dd>
<p>These templates are rendered with the release information of all releases.
These are generally used to generate the index page referencing to release notes of each release.</p>
</dd>
</dl>
</div>
<div class="paragraph">
<p><code>ChangelogExporter</code> is responsible for performing the export operation.</p>
</div>
<div class="sect3">
<h4 id="log4j-changelog-changelog-template">Changelog templates</h4>
<div class="paragraph">
<p>Changelog template files (e.g., <code>src/changelog/2.19.0/.release-notes.adoc.ftl</code> ) are rendered with the release and changelog information of a particular release using the following input data hash:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>release</code> → <code>ChangelogRelease</code></p>
</li>
<li>
<p><code>entriesByType</code> → <code>Map&lt;ChangelogEntry.Type, List&lt;ChangelogEntry&gt;&gt;</code></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>See <code>ChangelogRelease</code> and <code>ChangelogEntry</code> for details.</p>
</div>
<div class="paragraph">
<p>These templates are generally used to generate release notes for a particular release.
A sample changelog template file is shared below.</p>
</div>
<div class="listingblock">
<div class="title"><code>src/changelog/2.19.0/.release-notes.adoc.ftl</code> file contents</div>
<div class="content">
<pre class="CodeRay highlight"><code data-lang="asciidoc">= ${release.version}&lt;#if release.date?has_content&gt; (${release.date})&lt;/#if&gt;
This release primarily contains bug fixes and minor enhancements.
&lt;#if entriesByType?size gt 0&gt;== Changes
&lt;#list entriesByType as entryType, entries&gt;
=== ${entryType?capitalize}
&lt;#list entries as entry&gt;
* ${entry.description.text?replace(&quot;\\s+&quot;, &quot; &quot;, &quot;r&quot;)}
(&lt;#list entry.issues as issue&gt;${issue.link}[${issue.id}]&lt;#if issue?has_next&gt;, &lt;/#if&gt;&lt;/#list&gt;)
&lt;/#list&gt;
&lt;/#list&gt;
&lt;/#if&gt;</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="log4j-changelog-index-template">Index templates</h4>
<div class="paragraph">
<p>Index template files (e.g., <code>src/changelog/.index.adoc.ftl</code>) are rendered with the release information of all releases using the following input data hash:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>releases</code> &#8594; list of hashes containing following keys:</p>
<div class="ulist">
<ul>
<li>
<p><code>version</code></p>
</li>
<li>
<p><code>date</code></p>
</li>
</ul>
</div>
</li>
</ul>
</div>
<div class="paragraph">
<p>These template files are generally used to generate the index page referencing to release notes of each release.
A sample index template file is shared below.</p>
</div>
<div class="listingblock">
<div class="title"><code>src/changelog/.index.adoc.ftl</code> file contents</div>
<div class="content">
<pre class="CodeRay highlight"><code data-lang="asciidoc">= Release changelogs
&lt;#list releases as release&gt;
* xref:${release.version}.adoc[${release.version}]&lt;#if release.date?has_content&gt; (${release.date})&lt;/#if&gt;
&lt;/#list&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="log4j-changelog-qa">Q&amp;A</h3>
<div class="sect3">
<h4 id="log4j-changelog-qa-entry">How can I add an entry for a change I am about to commit?</h4>
<div class="paragraph">
<p>You have just committed, or better, about to commit a great feature you have been working on.
Simply create a <a href="#log4j-changelog-changelog-entry-file">Changelog entry file</a> and commit it along with your change!</p>
</div>
</div>
<div class="sect3">
<h4 id="log4j-changelog-qa-generate">How can I export changelogs to AsciiDoc, Markdown, etc. files?</h4>
<div class="paragraph">
<p>You need to use <a href="#log4j-changelog-maven-plugin-export">the <code>export</code> goal the Maven plugin</a>.</p>
</div>
</div>
<div class="sect3">
<h4 id="log4j-changelog-qa-deploy-release">I am about to deploy a new release. What shall I do?</h4>
<div class="paragraph">
<p>Just before a release, three things need to happen in the changelog sources:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p><strong>Changelog entry files needs to be moved</strong> from the <em>upcoming</em> release changelog directory <code>&lt;changelogDirectory&gt;/.&lt;releaseVersionMajor&gt;.x.x</code> to the <em>new</em> release changelog directory <code>&lt;changelogDirectory&gt;/&lt;releaseVersion&gt;</code></p>
</li>
<li>
<p><strong>Templates need to be copied</strong> from the <em>upcoming</em> release changelog directory to the <em>new</em> release changelog directory, unless it already exists in the target</p>
</li>
<li>
<p><strong><code>.release.xml</code> needs to be created</strong> in the <em>new</em> release changelog directory</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>Due to the nature of release candidates, above steps might need to be repeated multiple times.</p>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
<div class="paragraph">
<p>Log4j <em>releases</em> and <em>release candidates</em> all get deployed to the same <a href="https://repository.apache.org/#stagingRepositories"><em>staging repository</em></a>.
Their <code>pom.xml</code> files all contain the same release version, e.g., <code>2.19.0</code>.
There are no <code>-rc1</code>, <code>-rc2</code>, etc. suffixes in the version of a release candidate.
Once a release candidate voting reaches to a consensus for release, associated artifacts simply get promoted from the <em>staging</em> to the <em>public</em> repository.
Hence, there are no differences between releases and release candidates from the point of view of changelogs.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>How to carry out aforementioned changes are explained below in steps:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Populate the <code>&lt;changelogDirectory&gt;/&lt;releaseVersion&gt;</code> directory (e.g., <code>/src/changelog/2.19.0</code>) from the upcoming release changelog directory (e.g., <code>&lt;changelogDirectory&gt;/.2.x.x</code>) using the <a href="#log4j-changelog-maven-plugin-release"><code>release</code> Maven goal</a>:</p>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="bash">./mvnw log4j-changelog:release \
-Dlog4j.changelog.directory=/path/to/changelog/directory \
-Dlog4j.changelog.releaseVersion=X.Y.Z</code></pre>
</div>
</div>
</li>
<li>
<p>Verify that all changelog entry files are moved from <code>&lt;changelogDirectory&gt;/.&lt;releaseVersionMajor&gt;.x.x</code> directory (e.g., <code>/src/changelog/.2.x.x</code>)</p>
</li>
<li>
<p>Verify that <code>&lt;changelogDirectory&gt;/&lt;releaseVersion&gt;</code> directory (e.g., <code>/src/changelog/2.19.0</code>) is created, and it contains templates, changelog entry files, and a <code>.release.xml</code></p>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
<div class="paragraph">
<p>If <code>&lt;changelogDirectory&gt;/&lt;releaseVersion&gt;</code> directory (e.g., <code>/src/changelog/2.19.0</code>) already exists with certain content, <code>ChangelogReleaser</code> will only move new changelog entry files and override <code>.release.xml</code>; templates will not be overridden.
This allows one to run <code>ChangelogReleaser</code> multiple times, e.g., to incorporate changes added to a release candidate.</p>
</div>
</td>
</tr>
</table>
</div>
</li>
<li>
<p>Edit the populated templates (e.g., update the release notes with a short summary paragraph)</p>
</li>
<li>
<p><code>git add</code> the changes in the changelog directory (e.g., <code>/src/changelog</code>) and commit them</p>
</li>
</ol>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="log4j-changelog-maven-plugin">Log4j Changelog Maven Plugin</h2>
<div class="sectionbody">
<div class="paragraph">
<p>This project ships a Maven plugin providing access to the <code>ChangelogExporter</code> and <code>ChangelogReleaser</code> of <a href="#log4j-changelog">Log4j Changelog</a>.</p>
</div>
<div class="sect2">
<h3 id="log4j-changelog-maven-plugin-dependencies">Dependencies</h3>
<div class="paragraph">
<p>You need to have the <code>org.apache.logging.log4j:log4j-changelog-maven-plugin</code> dependency in your classpath:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="xml"><span class="tag">&lt;plugin&gt;</span>
<span class="tag">&lt;groupId&gt;</span>org.apache.logging.log4j<span class="tag">&lt;/groupId&gt;</span>
<span class="tag">&lt;artifactId&gt;</span>log4j-changelog-maven-plugin<span class="tag">&lt;/artifactId&gt;</span>
<span class="tag">&lt;version&gt;</span>0.8.0<span class="tag">&lt;/version&gt;</span>
<span class="tag">&lt;/plugin&gt;</span></code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="log4j-changelog-maven-plugin-export">Exporting changelogs</h3>
<div class="paragraph">
<p><em>Exporting</em> changelogs is the act of feeding provided changelog and release information into <a href="https://freemarker.apache.org">FreeMarker</a> templates to generate certain files; e.g., release notes for the website.
There are two types template files supported:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1"><a href="#log4j-changelog-changelog-template">Changelog templates</a></dt>
<dd>
<p>These templates are rendered with the release and changelog information of a particular release.
These are generally used to generate release notes for a particular release.</p>
</dd>
<dt class="hdlist1"><a href="#log4j-changelog-index-template">Index templates</a></dt>
<dd>
<p>These templates are rendered with the release information of all releases.
These are generally used to generate the index page referencing to release notes of each release.</p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>See <a href="#log4j-changelog-export">the Log4j Changelog documentation</a> for further details.</p>
</div>
<div class="paragraph">
<p>You can use the <code>export</code> goal as follows:</p>
</div>
<div class="listingblock">
<div class="title"><code>build &gt; plugins</code> block entry of <code>pom.xml</code></div>
<div class="content">
<pre class="CodeRay highlight"><code data-lang="xml"><span class="comment">&lt;!-- Export AsciiDoc-formatted release notes --&gt;</span>
<span class="tag">&lt;plugin&gt;</span>
<span class="tag">&lt;groupId&gt;</span>org.apache.logging.log4j<span class="tag">&lt;/groupId&gt;</span>
<span class="tag">&lt;artifactId&gt;</span>log4j-changelog-maven-plugin<span class="tag">&lt;/artifactId&gt;</span>
<span class="tag">&lt;version&gt;</span>0.8.0<span class="tag">&lt;/version&gt;</span>
<span class="tag">&lt;inherited&gt;</span>false<span class="tag">&lt;/inherited&gt;</span>
<span class="tag">&lt;configuration&gt;</span>
<span class="tag">&lt;indexTemplates&gt;</span>
<span class="tag">&lt;template&gt;</span>
<span class="tag">&lt;source&gt;</span>.index.adoc.ftl<span class="tag">&lt;/source&gt;</span>
<span class="tag">&lt;/template&gt;</span>
<span class="tag">&lt;/indexTemplates&gt;</span>
<span class="tag">&lt;changelogTemplates&gt;</span>
<span class="tag">&lt;template&gt;</span>
<span class="tag">&lt;source&gt;</span>.release-notes.adoc.ftl<span class="tag">&lt;/source&gt;</span>
<span class="tag">&lt;target&gt;</span>%v.adoc<span class="tag">&lt;/target&gt;</span>
<span class="tag">&lt;/template&gt;</span>
<span class="tag">&lt;/changelogTemplates&gt;</span>
<span class="tag">&lt;/configuration&gt;</span>
<span class="tag">&lt;executions&gt;</span>
<span class="tag">&lt;execution&gt;</span>
<span class="tag">&lt;id&gt;</span>generate-changelog<span class="tag">&lt;/id&gt;</span>
<span class="tag">&lt;goals&gt;</span>
<span class="tag">&lt;goal&gt;</span>export<span class="tag">&lt;/goal&gt;</span>
<span class="tag">&lt;/goals&gt;</span>
<span class="tag">&lt;/execution&gt;</span>
<span class="tag">&lt;/executions&gt;</span>
<span class="tag">&lt;/plugin&gt;</span></code></pre>
</div>
</div>
<div class="paragraph">
<p><code>export</code> goal by default runs during the <code>pre-site</code> phase and accepts the following configuration:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1"><code>changelogDirectory</code> (parameter)</dt>
<dd>
<p>Directory containing release folders composed of changelog entry XML files.
It defaults to <code>${project.basedir}/src/changelog</code> and can be set using the <code>log4j.changelog.directory</code> property.</p>
</dd>
<dt class="hdlist1"><code>outputDirectory</code> (parameter)</dt>
<dd>
<p>Directory to write rendered templates.
It defaults to <code>${project.build.directory}/generated-sources/site/changelog</code> and can be set using the <code>log4j.changelog.exporter.outputDirectory</code> property.</p>
</dd>
<dt class="hdlist1"><code>indexTemplates</code> (parameter)</dt>
<dd>
<p>List of <a href="#log4j-changelog-maven-plugin-export-template-type">template</a>s that will be rendered with release information of all releases.
See <a href="#log4j-changelog-index-template">the index template file documentation</a> for details.</p>
</dd>
<dt class="hdlist1"><code>changelogTemplates</code> (parameter)</dt>
<dd>
<p>List of <a href="#log4j-changelog-maven-plugin-export-template-type">template</a>s that will be rendered with release and changelog information of a particular release.
See <a href="#log4j-changelog-changelog-template">the changelog template file documentation</a> for details.</p>
</dd>
</dl>
</div>
<div id="log4j-changelog-maven-plugin-export-template-type" class="dlist">
<dl>
<dt class="hdlist1"><code>Template</code> (type)</dt>
<dd>
<p>An object composed of following fields:</p>
<div class="dlist">
<dl>
<dt class="hdlist1"><code>source</code> (parameter)</dt>
<dd>
<p>the <a href="https://freemarker.apache.org">FreeMarker</a> template file</p>
</dd>
<dt class="hdlist1"><code>target</code> (parameter)</dt>
<dd>
<p>The output file.
If not provided, it will be derived from the <code>source</code>: if the <code>source</code> is <code>.index.adoc.ftl</code>, the <code>target</code> will be set to <code>index.adoc</code>.
If the value contains a <code>%v</code> (e.g., <code>%v.adoc</code>), it will be replaced with the associated release version.
<code>%v</code> substitution is only allowed for changelog templates and will not work for index templates.</p>
</dd>
<dt class="hdlist1"><code>failIfNotFound</code> (parameter)</dt>
<dd>
<p>Indicates if export should fail when the source cannot be found.
Defaults to <code>false</code>.</p>
</dd>
</dl>
</div>
</dd>
</dl>
</div>
</div>
<div class="sect2">
<h3 id="log4j-changelog-maven-plugin-release">Populating a release changelog directory</h3>
<div class="paragraph">
<p>You can use the <code>release</code> goal wrapping <a href="#log4j-changelog-qa-deploy-release"><code>ChangelogReleaser</code> to populate a release changelog directory</a>.
An example usage is shared below.</p>
</div>
<div class="listingblock">
<div class="title">Populate <code>src/changelog/2.19.0</code> from <code>src/changelog/.2.x.x</code></div>
<div class="content">
<pre class="CodeRay highlight"><code data-lang="bash">./mvnw -N log4j-changelog:release -Dlog4j.changelog.releaseVersion=2.19.0</code></pre>
</div>
</div>
<div class="paragraph">
<p>Note that above we are using <code>-N</code> (<code>--non-recursive</code>) to avoid visiting submodules, which also makes the run faster.</p>
</div>
<div class="paragraph">
<p><code>release</code> goal does not have default phase and accepts the following configuration parameters:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1"><code>changelogDirectory</code> (parameter)</dt>
<dd>
<p>Directory containing release folders composed of changelog entry XML files.
It defaults to <code>${project.basedir}/src/changelog</code> and can be set using the <code>log4j.changelog.directory</code> property.</p>
</dd>
<dt class="hdlist1"><code>releaseVersion</code> (parameter)</dt>
<dd>
<p>The version to be released.
It can be set using the <code>log4j.changelog.releaseVersion</code> property.</p>
</dd>
<dt class="hdlist1"><code>versionPattern</code> (parameter)</dt>
<dd>
<p>The regular expression pattern for parsing versions.
The pattern must provide the following named groups: <code>major</code>, <code>minor</code>, and <code>patch</code>.
It defaults to <code>^(?&lt;major&gt;0|[1-9]\d*)\.(?&lt;minor&gt;0|[1-9]\d*)\.(?&lt;patch&gt;0|[1-9]\d*(-[a-zA-Z][0-9a-zA-Z-]*)?)$</code> and can be set using the <code>log4j.changelog.versionPattern</code> property.</p>
</dd>
</dl>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="log4j-docgen">Log4j Docgen</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Log4j Docgen (Documentation Generation) bundles utility classes to generate documentation from Log4j plugins.
Given almost all Log4j functionality (layouts, appenders, etc.) is implemented in the form of plugins, this project aims the following goals:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Avoid the need to maintain documentation in multiple places</dt>
<dd>
<p>For instance, Log4j JSON Template Layout is composed of several plugins with sufficient Javadoc explaining their behaviour.
Next to this we also maintain a big <code>json-template-layout.adoc</code> page for the website, again, documenting each component.
By generating documentation from the source code, developers can precisely capture the behaviour of their components only in the very code itself that they change.</p>
</dd>
<dt class="hdlist1">Accurately capture the component configuration</dt>
<dd>
<p>It is pretty common that source code changes are not reflected to documentation.
By generating the documentation from the source code, this discrepancy gets removed.</p>
</dd>
</dl>
</div>
<div class="sect2">
<h3 id="log4j-docgen-dependencies">Dependencies</h3>
<div class="paragraph">
<p>You need to have the <code>org.apache.logging.log4j:log4j-docgen</code> dependency in your classpath:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="xml"><span class="tag">&lt;plugin&gt;</span>
<span class="tag">&lt;groupId&gt;</span>org.apache.logging.log4j<span class="tag">&lt;/groupId&gt;</span>
<span class="tag">&lt;artifactId&gt;</span>log4j-docgen<span class="tag">&lt;/artifactId&gt;</span>
<span class="tag">&lt;version&gt;</span>0.8.0<span class="tag">&lt;/version&gt;</span>
<span class="tag">&lt;/plugin&gt;</span></code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="log4j-docgen-descriptor-generator">Descriptor generator</h3>
<div class="paragraph">
<p><code>DescriptorGenerator</code> is an annotation processor that generates an XML file capturing all the metadata needed to document a plugin:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><strong>types</strong> – types it extends from, types it uses in its configuration, etc.</p>
</li>
<li>
<p><strong>configuration</strong> – extracts the necessary set of elements, attributes, etc. from builder classes, <code>@PluginFactory</code>-annotated methods, etc.</p>
</li>
<li>
<p><strong>documentation</strong> – extracts the Javadoc of each field and type, and converts it to AsciiDoc</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Users are recommended to integrate this annotation processor into their build:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="xml"><span class="tag">&lt;plugin&gt;</span>
<span class="tag">&lt;groupId&gt;</span>org.apache.maven.plugins<span class="tag">&lt;/groupId&gt;</span>
<span class="tag">&lt;artifactId&gt;</span>maven-compiler-plugin<span class="tag">&lt;/artifactId&gt;</span>
<span class="tag">&lt;configuration&gt;</span>
<span class="tag">&lt;annotationProcessorPaths</span> <span class="attribute-name">combine.children</span>=<span class="string"><span class="delimiter">&quot;</span><span class="content">append</span><span class="delimiter">&quot;</span></span><span class="tag">&gt;</span>
<span class="comment">&lt;!-- Include `org.apache.logging.log4j.docgen.processor.DescriptorGenerator` that generates `log4j-plugins.xml`.
`DescriptorGenerator` must precede `PluginProcessor`, since the latter *claims* the `@Plugin`.
Once claimed, `javac` doesn't pass those sources to other processors. --&gt;</span>
<span class="tag">&lt;path&gt;</span>
<span class="tag">&lt;groupId&gt;</span>org.apache.logging.log4j<span class="tag">&lt;/groupId&gt;</span>
<span class="tag">&lt;artifactId&gt;</span>log4j-docgen<span class="tag">&lt;/artifactId&gt;</span>
<span class="tag">&lt;version&gt;</span>0.8.0<span class="tag">&lt;/version&gt;</span>
<span class="tag">&lt;/path&gt;</span>
<span class="comment">&lt;!-- `org.apache.logging.log4j.core.config.plugins.processor.PluginProcessor` for generating `META-INF/org/apache/.../Log4j2Plugins.dat`: --&gt;</span>
<span class="tag">&lt;path&gt;</span>
<span class="tag">&lt;groupId&gt;</span>org.apache.logging.log4j<span class="tag">&lt;/groupId&gt;</span>
<span class="tag">&lt;artifactId&gt;</span>log4j-core<span class="tag">&lt;/artifactId&gt;</span>
<span class="tag">&lt;version&gt;</span>${project.version}<span class="tag">&lt;/version&gt;</span>
<span class="tag">&lt;/path&gt;</span>
<span class="tag">&lt;/annotationProcessorPaths&gt;</span>
<span class="tag">&lt;compilerArgs</span> <span class="attribute-name">combine.children</span>=<span class="string"><span class="delimiter">&quot;</span><span class="content">append</span><span class="delimiter">&quot;</span></span><span class="tag">&gt;</span>
<span class="comment">&lt;!-- Provide `org.apache.logging.log4j.docgen.processor.DescriptorGenerator` arguments: --&gt;</span>
<span class="tag">&lt;arg&gt;</span>-Alog4j.docgen.descriptorFilePath=${project.build.directory}/${project.artifactId}-plugins.xml<span class="tag">&lt;/arg&gt;</span>
<span class="tag">&lt;arg&gt;</span>-Alog4j.docgen.groupId=${project.groupId}<span class="tag">&lt;/arg&gt;</span>
<span class="tag">&lt;arg&gt;</span>-Alog4j.docgen.artifactId=${project.artifactId}<span class="tag">&lt;/arg&gt;</span>
<span class="tag">&lt;arg&gt;</span>-Alog4j.docgen.version=${project.version}<span class="tag">&lt;/arg&gt;</span>
<span class="tag">&lt;arg&gt;</span>-Alog4j.docgen.description=${project.description}<span class="tag">&lt;/arg&gt;</span>
<span class="tag">&lt;arg&gt;</span>-Alog4j.docgen.typeFilter.excludePattern=^java\..+<span class="tag">&lt;/arg&gt;</span>
<span class="tag">&lt;/compilerArgs&gt;</span>
<span class="tag">&lt;/configuration&gt;</span>
<span class="tag">&lt;/plugin&gt;</span></code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="log4j-docgen-documentation-generator">Documentation generator</h3>
<div class="paragraph">
<p><code>DocumentationGenerator</code> receives</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>plugin descriptors (generated by the <code>DescriptorGenerator</code>)</p>
</li>
<li>
<p>FreeMarker templates (to render the type hierarchy and each individual type)</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>as input arguments, and produces an AsciiDoc-formatted documentation that one can integrate into the website of a project.</p>
</div>
<div class="paragraph">
<p>Users are recommended to use <a href="#log4j-docgen-maven-plugin-generate-documentation">the <code>generate-documentation</code> goal of the <code>log4j-docgen-maven-plugin</code></a> instead.</p>
</div>
</div>
<div class="sect2">
<h3 id="log4j-docgen-schema-generator">Schema generator</h3>
<div class="paragraph">
<p><code>SchemaGenerator</code> receives plugin descriptors (generated by the <code>DescriptorGenerator</code>) as input, and produces an XSD describing the structure defined by the descriptors.</p>
</div>
<div class="paragraph">
<p>Users are recommended to use <a href="#log4j-docgen-maven-plugin-generate-schema">the <code>generate-schema</code> goal of the <code>log4j-docgen-maven-plugin</code></a> instead.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="log4j-docgen-maven-plugin">Log4j Docgen Maven Plugin</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Log4j Docgen Maven Plugin allows you to easily run Log4j Docgen <a href="#log4j-docgen-documentation-generator">documentation generator</a> and <a href="#log4j-docgen-schema-generator">schema generator</a> from your <code>pom.xml</code>.</p>
</div>
<div class="sect2">
<h3 id="log4j-docgen-maven-plugin-dependencies">Dependencies</h3>
<div class="paragraph">
<p>You need to have the <code>org.apache.logging.log4j:log4j-docgen-maven-plugin</code> dependency in your classpath:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="xml"><span class="tag">&lt;plugin&gt;</span>
<span class="tag">&lt;groupId&gt;</span>org.apache.logging.log4j<span class="tag">&lt;/groupId&gt;</span>
<span class="tag">&lt;artifactId&gt;</span>log4j-docgen-maven-plugin<span class="tag">&lt;/artifactId&gt;</span>
<span class="tag">&lt;version&gt;</span>0.8.0<span class="tag">&lt;/version&gt;</span>
<span class="tag">&lt;/plugin&gt;</span></code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="log4j-docgen-maven-plugin-generate-documentation">Generate documentation</h3>
<div class="paragraph">
<p>The <code>generate-documentation</code> goal generates an AsciiDoc-formatted documentation using FreeMarker templates that are fed with the types loaded from given descriptors:</p>
</div>
<div class="listingblock">
<div class="title">An example <code>log4j-docgen:generate-documentation</code> configuration</div>
<div class="content">
<pre class="CodeRay highlight"><code data-lang="xml"><span class="tag">&lt;configuration&gt;</span>
<span class="tag">&lt;descriptorFileMatchers&gt;</span>
<span class="tag">&lt;descriptorFileMatcher&gt;</span>
<span class="tag">&lt;baseDirectory&gt;</span>${project.build.directory}/plugin-descriptors<span class="tag">&lt;/baseDirectory&gt;</span>
<span class="tag">&lt;/descriptorFileMatcher&gt;</span>
<span class="tag">&lt;/descriptorFileMatchers&gt;</span>
<span class="tag">&lt;typeFilter&gt;</span>
<span class="tag">&lt;excludes&gt;</span>
<span class="tag">&lt;exclude&gt;</span>^java\..+<span class="tag">&lt;/exclude&gt;</span>
<span class="tag">&lt;/excludes&gt;</span>
<span class="tag">&lt;/typeFilter&gt;</span>
<span class="tag">&lt;templateDirectory&gt;</span>${project.basedir}/src/docgen-templates<span class="tag">&lt;/templateDirectory&gt;</span>
<span class="tag">&lt;indexTemplate&gt;</span>
<span class="tag">&lt;source&gt;</span>index.adoc.ftl<span class="tag">&lt;/source&gt;</span>
<span class="tag">&lt;target&gt;</span>${project.build.directory}/generated-site/asciidoc/plugin-reference/index.adoc<span class="tag">&lt;/target&gt;</span>
<span class="tag">&lt;/indexTemplate&gt;</span>
<span class="tag">&lt;typeTemplate&gt;</span>
<span class="tag">&lt;source&gt;</span>type.adoc.ftl<span class="tag">&lt;/source&gt;</span>
<span class="comment">&lt;!-- `target` must be in sync. with the `log4j-docgen-type-template-target` configuration of `log4j-docgen-asciidoctor-extension`! --&gt;</span>
<span class="tag">&lt;target&gt;</span>${project.build.directory}/generated-site/asciidoc/plugin-reference/%g/%a/%c.adoc<span class="tag">&lt;/target&gt;</span>
<span class="tag">&lt;/typeTemplate&gt;</span>
<span class="tag">&lt;/configuration&gt;</span></code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="log4j-docgen-maven-plugin-generate-schema">Generate schema</h3>
<div class="paragraph">
<p>The <code>generate-schema</code> goal generates an XSD derived from the types loaded using given descriptors:</p>
</div>
<div class="listingblock">
<div class="title">An example <code>log4j-docgen:generate-schema</code> configuration</div>
<div class="content">
<pre class="CodeRay highlight"><code data-lang="xml"><span class="tag">&lt;configuration&gt;</span>
<span class="tag">&lt;descriptorFileMatchers&gt;</span>
<span class="tag">&lt;descriptorFileMatcher&gt;</span>
<span class="tag">&lt;baseDirectory&gt;</span>${project.build.directory}/plugin-descriptors<span class="tag">&lt;/baseDirectory&gt;</span>
<span class="tag">&lt;/descriptorFileMatcher&gt;</span>
<span class="tag">&lt;/descriptorFileMatchers&gt;</span>
<span class="tag">&lt;typeFilter&gt;</span>
<span class="tag">&lt;excludes&gt;</span>
<span class="tag">&lt;exclude&gt;</span>^java\..+<span class="tag">&lt;/exclude&gt;</span>
<span class="tag">&lt;/excludes&gt;</span>
<span class="tag">&lt;/typeFilter&gt;</span>
<span class="tag">&lt;schemaFile&gt;</span>${project.build.directory}/generated-site/resources/config.xsd<span class="tag">&lt;/schemaFile&gt;</span>
<span class="tag">&lt;/configuration&gt;</span></code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="log4j-docgen-asciidoctor-extension">Log4j Docgen AsciiDoctor extension</h2>
<div class="sectionbody">
<div class="paragraph">
<p>While <a href="#log4j-docgen-descriptor-generator">the descriptor generator</a> converts Javadoc to AsciiDoc, it cannot resolve links.
That is, it cannot blindly replace a <code>{@link example.MyAppender foo}</code> Javadoc snippet with a <code>xref:MyAppender.adoc[foo]</code> AsciiDoc snippet instead.
This is because, the mapping of types to AsciiDoc files are not available to the descriptor generator, but <a href="#log4j-docgen-documentation-generator">the documentation generator</a>.
That is, the descriptor generator doesn&#8217;t know if the type will be mapped to <code>&lt;className&gt;.adoc</code> or <code>&lt;artifactId&gt;/&lt;className&gt;.adoc</code>.
As a matter of fact, it should not need to know this either: descriptors capture immutable metadata, whereas documentation file structure can always change.
To work around this, we convert <code>{@link example.MyAppender foo}</code> to <code>apiref:example.MyAppender[foo]</code> and provide an <code>apiref</code> inline AsciiDoc macro to resolve these while generating the documentation.</p>
</div>
<div class="paragraph">
<p><code>DocgenExtension</code> AsciiDoctor extension provides the <code>apiref</code> inline macro which can be configured using the below shared AsciiDoctor document attributes:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1"><code>log4j-docgen-descriptor-dot-files-included</code></dt>
<dd>
<p>Indicates if dot files (i.e., <code>.</code>-prefix file names) will be accepted in <a href="#log4j-docgen-asciidoctor-extension-attribute-descriptor-path-matcher">[log4j-docgen-asciidoctor-extension-attribute-descriptor-path-matcher]</a>.
This attribute defaults to <code>false</code>.</p>
</dd>
</dl>
</div>
<div id="log4j-docgen-asciidoctor-extension-attribute-descriptor-path-matcher" class="dlist">
<dl>
<dt class="hdlist1"><code>log4j-docgen-descriptor-path-matcher</code></dt>
<dd>
<p>The <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/nio/file/FileSystem.html#getPathMatcher(java.lang.String)">path pattern</a> (e.g., <code>glob:*<strong>/</strong>.xml</code>) to locate files produced by <a href="#log4j-docgen-descriptor-generator">the descriptor generator</a>.
This attribute is <strong>required</strong>.</p>
</dd>
<dt class="hdlist1"><code>log4j-docgen-type-filter-exclude-pattern</code></dt>
<dd>
<p>The regular expression to match against the types loaded from descriptors and determine if a type will be <em>excluded</em> to generate links.
This argument defaults to not exclude anything.</p>
</dd>
<dt class="hdlist1"><code>log4j-docgen-type-filter-include-pattern</code></dt>
<dd>
<p>The regular expression to match against the types loaded from descriptors and determine if a type will be <em>included</em> to generate links.
This argument defaults to <code>.*</code>, that is, all loaded types will be used to generate links.</p>
</dd>
<dt class="hdlist1"><code>log4j-docgen-package-name-stripped</code></dt>
<dd>
<p>Indicates if the package name will be stripped for unknown types.
That is, if <code>true</code>, <code>apiref:some.unknown.Class[]</code> will be converted to <code>&lt;code&gt;Class&lt;/code&gt;</code>; <code>&lt;code&gt;some.unknown.Class&lt;/code&gt;</code>, otherwise.
Note that this only applies to types where the label is not provided.
This flag is disabled by default.</p>
</dd>
<dt class="hdlist1"><code>log4j-docgen-type-template-target</code></dt>
<dd>
<p>The target file path of individual types documented, e.g., <code>../../%g/%a/%c.html</code>.
Certain directives are subject to substitution:</p>
<div class="ulist">
<ul>
<li>
<p><code>%a</code> – artifact ID, if the type is provided with an artifact origin; <code>unknown-artifactId</code>, otherwise</p>
</li>
<li>
<p><code>%c</code> – class name</p>
</li>
<li>
<p><code>%g</code> – group ID, if the type is provided with an artifact origin; <code>unknown-groupId</code>, otherwise</p>
</li>
<li>
<p><code>%v</code> – version, if the type is provided with an artifact origin; <code>unknown-version</code>, otherwise</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>This attribute is <strong>required</strong>.</p>
</div>
</dd>
</dl>
</div>
</div>
</div>
<div class="sect1">
<h2 id="development">Development</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Log4j Tools uses <a href="https://github.com/apache/logging-log4j-tools">GitHub</a> for source code management.</p>
</div>
<div class="paragraph">
<p>The project requires a Java compiler matching the <code>[17,18)</code> range and targets Java <code>8</code>.</p>
</div>
<div class="paragraph">
<p>You can build and verify sources using:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="bash">./mvnw verify</code></pre>
</div>
</div>
<div class="paragraph">
<p>You can build and view the website as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="bash">./mvnw -N site
python -m http.server -d target/site</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="distribution">Distribution</h2>
<div class="sectionbody">
<div class="paragraph">
<p>In accordance with the Apache Software Foundation&#8217;s release <a href="https://infra.apache.org/release-distribution.html">distribution policy</a> and <a href="https://infra.apache.org/release-publishing.html">creation process</a>, project artifacts are <em>officially</em> accessible from the following locations:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>ASF <a href="https://repository.apache.org/content/repositories/releases">Release</a> and <a href="https://repository.apache.org/content/repositories/snapshots">snapshot</a> repositories (mirrored to <a href="https://central.sonatype.dev/">the Maven Central Repository</a>)</p>
</li>
<li>
<p>ASF <a href="https://downloads.apache.org/logging/log4j-tools">Distribution directory</a></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>See <a href="#release-instructions">the release instructions</a> for details.</p>
</div>
<div class="sect2">
<h3 id="maven-bom">Maven Bill of Materials (BOM)</h3>
<div class="paragraph">
<p>To keep your Log4j Tools module versions aligned, a <a href="https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#bill-of-materials-bom-poms">Maven Bill of Materials (BOM) POM</a> is provided for your convenience.</p>
</div>
<div class="paragraph">
<p>To use this with Maven, add the dependency listed below to your <code>pom.xml</code> file.
Note that the <code>&lt;dependencyManagement&gt;</code> nesting and the <code>&lt;scope&gt;import&lt;/scope&gt;</code> instruction.
This will <em>import</em> all modules bundled with the associated Log4j release to your <code>dependencyManagement</code>.
As a result, you don&#8217;t have to specify versions of the imported modules (<code>log4j-changelog</code>, <code>log4j-docgen</code>, etc.) while using them as a <code>&lt;dependency&gt;</code>.</p>
</div>
<div class="listingblock">
<div class="title"><code>pom.xml</code> snippet importing <code>log4j-tools-bom</code></div>
<div class="content">
<pre class="CodeRay highlight"><code>&lt;dependencyManagement&gt;
&lt;dependencies&gt;
&lt;dependency&gt;
&lt;groupId&gt;org.apache.logging.log4j&lt;/groupId&gt;
&lt;artifactId&gt;log4j-tools-bom&lt;/artifactId&gt;
&lt;version&gt;0.8.0&lt;/version&gt;
&lt;scope&gt;import&lt;/scope&gt;
&lt;type&gt;pom&lt;/type&gt;
&lt;/dependency&gt;
&lt;/dependencies&gt;
&lt;/dependencyManagement&gt;</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="cyclonedx-sbom">CycloneDX Software Bill of Materials (SBOM)</h3>
<div class="paragraph">
<p>Starting with version <code>0.6.0</code>, Log4j Tools distributes <a href="https://cyclonedx.org/capabilities/sbom/">CyclenoDX Software Bill of Materials (SBOM)</a> along with each deployed artifact.
This is streamlined by <code>logging-parent</code>, see <a href="https://logging.apache.org/logging-parent/latest/#cyclonedx-sbom">its website</a> for details.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="support">Support</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Please keep in mind that this project is intended for internal usage only.
You can use GitHub Issues for feature requests and bug reports – not questions!
See <a href="https://logging.apache.org/log4j/2.x/support.html">the Log4j support policy</a> for details.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="security">Security</h2>
<div class="sectionbody">
<div class="paragraph">
<p>If you have encountered an unlisted security vulnerability or other unexpected behaviour that has security impact, please report them privately to <a href="mailto:security@logging.apache.org">the Log4j security mailing list</a>.
See <a href="https://logging.apache.org/log4j/2.x/security.html">the Log4j Security page</a> for further details.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="release-notes">Release Notes</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="release-notes-0-8-0">0.8.0</h3>
<div class="dlist">
<dl>
<dt class="hdlist1">Release date</dt>
<dd>
<p>2024-03-18</p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>This release delivers the first version of Log4j Docgen (Documentation Generator).
It is a set of tools to auto-generate the Log4j plugin documentation (to be integrated into the website) and the Log4j configuration XSD file (for assisting the configuration of the Log4j runtime, i.e., <code>log4j2.xml</code>) from the Log4j source code.
See the project website for details.</p>
</div>
<div class="sect3">
<h4 id="release-notes-0-8-0-added">Added</h4>
<div class="ulist">
<ul>
<li>
<p>Add the <code>log4j-docgen</code> et al. containing a universal XML model to document Log4j plugins</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="release-notes-0-8-0-changed">Changed</h4>
<div class="ulist">
<ul>
<li>
<p>Move Log4j Changelog XML namespace and schema location to <code><a href="https://logging.apache.org/xml/ns" class="bare">https://logging.apache.org/xml/ns</a></code> and <code><a href="https://logging.apache.org/xml/ns/log4j-changelog-0.xsd" class="bare">https://logging.apache.org/xml/ns/log4j-changelog-0.xsd</a></code>, respectively</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="release-notes-0-8-0-removed">Removed</h4>
<div class="ulist">
<ul>
<li>
<p>Remove <code>author</code> from Log4j Changelog.</p>
<div class="paragraph">
<p>It was yet another bit to maintain and created role-related (who did what) problems.
Many modern software projects use a VCS (e.g., Git) and support services (e.g., GitHub) which make it trivial to trace back the origin of a change using commit and issue IDs.</p>
</div>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="release-notes-0-8-0-updated">Updated</h4>
<div class="ulist">
<ul>
<li>
<p>Update <code>org.apache.logging:logging-parent</code> to version <code>10.6.0</code></p>
</li>
<li>
<p>Update <code>jakarta.inject:jakarta.inject-api</code> to version <code>2.0.1</code> (<a href="https://github.com/apache/logging-log4j-tools/pull/94">94</a>)</p>
</li>
<li>
<p>Update <code>org.apache.logging.log4j:log4j-core</code> to version <code>2.23.1</code> (<a href="https://github.com/apache/logging-log4j-tools/pull/108">108</a>)</p>
</li>
<li>
<p>Update <code>org.apache.logging.log4j:log4j-plugins</code> to version <code>3.0.0-beta2</code> (<a href="https://github.com/apache/logging-log4j-tools/pull/107">107</a>)</p>
</li>
<li>
<p>Update <code>org.apache.maven.plugin-tools:maven-plugin-annotations</code> to version <code>3.11.0</code> (<a href="https://github.com/apache/logging-log4j-tools/pull/98">98</a>)</p>
</li>
<li>
<p>Update <code>org.assertj:assertj-core</code> to version <code>3.25.3</code> (<a href="https://github.com/apache/logging-log4j-tools/pull/104">104</a>)</p>
</li>
<li>
<p>Update <code>org.codehaus.modello:modello-maven-plugin</code> to version <code>2.3.0</code> (<a href="https://github.com/apache/logging-log4j-tools/pull/105">105</a>)</p>
</li>
<li>
<p>Update <code>org.junit:junit-bom</code> to version <code>5.10.2</code> (<a href="https://github.com/apache/logging-log4j-tools/pull/103">103</a>)</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect2">
<h3 id="release-notes-0-7-0">0.7.0</h3>
<div class="dlist">
<dl>
<dt class="hdlist1">Release date</dt>
<dd>
<p>2023-12-14</p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>This minor release contains various bug fixes and improvements.</p>
</div>
<div class="sect3">
<h4 id="release-notes-0-7-0-added">Added</h4>
<div class="ulist">
<ul>
<li>
<p>Add the new <code>updated</code> changelog entry type and bump the XSD version to <code>0.1.3</code></p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="release-notes-0-7-0-fixed">Fixed</h4>
<div class="ulist">
<ul>
<li>
<p>Sort changelog entry types alphanumerically</p>
</li>
<li>
<p>Fix <code>log4j-changelog:release</code> failure on empty unreleased changelog directory (<a href="https://github.com/apache/logging-log4j-tools/issues/90">90</a>)</p>
</li>
<li>
<p>Fix parsing of patch versions in <code>log4j-changelog:release</code> goal (<a href="https://github.com/apache/logging-log4j-tools/issues/89">89</a>)</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="release-notes-0-7-0-updated">Updated</h4>
<div class="ulist">
<ul>
<li>
<p>Update <code>commons-io:commons-io</code> to version <code>2.15.1</code> (<a href="https://github.com/apache/logging-log4j-tools/pull/86">86</a>)</p>
</li>
<li>
<p>Update <code>org.apache.maven.plugin-tools:maven-plugin-annotations</code> to version <code>3.10.2</code> (<a href="https://github.com/apache/logging-log4j-tools/pull/87">87</a>)</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect2">
<h3 id="release-notes-0-6-0">0.6.0</h3>
<div class="dlist">
<dl>
<dt class="hdlist1">Release date</dt>
<dd>
<p>2023-11-17</p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>This minor release contains various bug fixes and improvements.</p>
</div>
<div class="sect3">
<h4 id="release-notes-0-6-0-added">Added</h4>
<div class="ulist">
<ul>
<li>
<p>Started generating CycloneDX SBOM with the recent update of <code>logging-parent</code> to version <code>10.4.0</code></p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="release-notes-0-6-0-fixed">Fixed</h4>
<div class="ulist">
<ul>
<li>
<p><code>log4j-tools-bom</code> was broken due to removed <code>parent</code> during flattening.
This is automatically fixed by the recent <code>logging-parent</code> version <code>10.4.0</code> update.</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="release-notes-0-6-0-updated">Updated</h4>
<div class="ulist">
<ul>
<li>
<p>Update <code>org.apache.logging:logging-parent</code> to version <code>10.4.0</code></p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect2">
<h3 id="release-notes-0-5-0">0.5.0</h3>
<div class="dlist">
<dl>
<dt class="hdlist1">Release date</dt>
<dd>
<p>2023-09-29</p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>This minor release contains various bug fixes and improvements.</p>
</div>
<div class="sect3">
<h4 id="release-notes-0-5-0-added">Added</h4>
<div class="ulist">
<ul>
<li>
<p>Added OSGi and JPMS support</p>
</li>
<li>
<p>Started publishing <a href="https://logging.apache.org/log4j/tools">the project website</a></p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="release-notes-0-5-0-changed">Changed</h4>
<div class="ulist">
<ul>
<li>
<p>Made <code>author</code> element optional and bumped the XML schema version to <code>0.1.2</code> (<a href="https://github.com/apache/logging-log4j-tools/issues/81">81</a>)</p>
</li>
<li>
<p>Make <code>log4j-changelog-maven-plugin</code> thread-safe (<a href="https://github.com/apache/logging-log4j-tools/issues/80">80</a>)</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="release-notes-0-5-0-updated">Updated</h4>
<div class="ulist">
<ul>
<li>
<p>Update <code>org.apache.logging:logging-parent</code> to version <code>10.1.1</code> (<a href="https://github.com/apache/logging-log4j-tools/pull/82">82</a>)</p>
</li>
<li>
<p>Update <code>org.junit.jupiter:junit-jupiter-engine</code> to version <code>5.10.0</code></p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect2">
<h3 id="release-notes-0-4-0">0.4.0</h3>
<div class="dlist">
<dl>
<dt class="hdlist1">Release date</dt>
<dd>
<p>2023-07-02</p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>This minor release contains small enhancements.
Most importantly, this marks the first release where the project uses itself to generate release notes!</p>
</div>
<div class="sect3">
<h4 id="release-notes-0-4-0-added">Added</h4>
<div class="ulist">
<ul>
<li>
<p>Add <code>versionPattern</code> (i.e., the regular expression pattern for parsing versions) parameter to the Maven <code>release</code> goal (<a href="https://github.com/apache/logging-log4j-tools/issues/63">63</a>)</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="release-notes-0-4-0-changed">Changed</h4>
<div class="ulist">
<ul>
<li>
<p>Change the default value of <code>outputDirectory</code> to <code>${project.build.directory}/generated-sources/site/changelog</code> for the Maven <code>export</code> goal</p>
</li>
<li>
<p>Migrate from <code>CHANGELOG.adoc</code> to using <code>log4j-changelog-maven-plugin</code></p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="release-notes-0-4-0-fixed">Fixed</h4>
<div class="ulist">
<ul>
<li>
<p>Improve Maven <code>release</code> goal to accommodate repetitive invocations</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect2">
<h3 id="release-notes-0-3-0">0.3.0</h3>
<div class="dlist">
<dl>
<dt class="hdlist1">Release date</dt>
<dd>
<p>2023-03-14</p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>This minor release contains various bug fixes and improvements.</p>
</div>
<div class="sect3">
<h4 id="release-notes-0-3-0-added">Added</h4>
<div class="ulist">
<ul>
<li>
<p>The changelog release models passed to the index template file (<code>.index.adoc.ftl</code>) is enriched with <code>changelogEntryCount</code> fields (<a href="https://github.com/apache/logging-log4j-tools/issues/37">37</a>)</p>
</li>
<li>
<p>Support multiple and formatting-agnostic template files (<a href="https://github.com/apache/logging-log4j-tools/issues/44">44</a>)</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="release-notes-0-3-0-changed">Changed</h4>
<div class="ulist">
<ul>
<li>
<p>Upgrade the compiler version to Java 17, yet still target Java 8</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect2">
<h3 id="release-notes-0-2-0">0.2.0</h3>
<div class="dlist">
<dl>
<dt class="hdlist1">Release date</dt>
<dd>
<p>2023-01-31</p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>This minor release contains various bug fixes and improvements.</p>
</div>
<div class="sect3">
<h4 id="release-notes-0-2-0-added">Added</h4>
<div class="ulist">
<ul>
<li>
<p>Add XSD for <code>log4j-changelog</code> XML files (<a href="https://github.com/apache/logging-log4j-tools/issues/13">13</a>)</p>
</li>
<li>
<p>Add <code>log4j-changelog-maven-plugin</code> module (<a href="https://github.com/apache/logging-log4j-tools/issues/20">20</a>)</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="release-notes-0-2-0-changed">Changed</h4>
<div class="ulist">
<ul>
<li>
<p>Rename <code>log4j.changelog.exporter.outputDirectory</code> property to <code>log4j.changelog.outputDirectory</code> (<a href="https://github.com/apache/logging-log4j-tools/issues/20">20</a>)</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="release-notes-0-2-0-fixed">Fixed</h4>
<div class="ulist">
<ul>
<li>
<p>Fix unreleased directory order in <code>ChangelogExporter</code> (<a href="https://github.com/apache/logging-log4j-tools/issues/17">17</a>)</p>
</li>
<li>
<p>Fix Windows compatibility (<a href="https://github.com/apache/logging-log4j-tools/issues/19">19</a>)</p>
</li>
</ul>
</div>
</div>
<div class="sect3">
<h4 id="release-notes-0-2-0-removed">Removed</h4>
<div class="ulist">
<ul>
<li>
<p>Remove <code>security</code> as a change type from <code>log4j-changelog</code> (<a href="https://github.com/apache/logging-log4j-tools/issues/14">14</a>)</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect2">
<h3 id="release-notes-0-1-0">0.1.0</h3>
<div class="dlist">
<dl>
<dt class="hdlist1">Release date</dt>
<dd>
<p>2023-01-10</p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>This is the first release, aimed to assist [the Apache Log4j 2](<a href="https://logging.apache.org/log4j/2.x/" class="bare">https://logging.apache.org/log4j/2.x/</a>) on generating release notes.</p>
</div>
<div class="sect3">
<h4 id="release-notes-0-1-0-added">Added</h4>
<div class="ulist">
<ul>
<li>
<p>Add <code>log4j-tools-bom</code> and <code>log4j-changelog</code> modules (<a href="https://issues.apache.org/jira/browse/LOG4J2-3628">LOG4J2-3628</a>)</p>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="release-instructions">Release instructions</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Log4j Tools employs the CI/CD foundation provided by the <a href="https://logging.apache.org/logging-parent"><code>logging-parent</code></a>.
You can simply use its release instructions.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="license">License</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.
See <code>NOTICE.txt</code> 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 <a href="https://www.apache.org/licenses/LICENSE-2.0" class="bare">https://www.apache.org/licenses/LICENSE-2.0</a>.</p>
</div>
<div class="paragraph">
<p>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.</p>
</div>
</div>
</div>
</div>
<div id="footer">
<div id="footer-text">
Last updated 2024-03-18 20:40:37 UTC
</div>
</div>
</body>
</html>