| <?xml version="1.0"?> |
| <!-- |
| Licensed to the Apache Software Foundation (ASF) under one or more |
| contributor license agreements. See the NOTICE file distributed with |
| this work for additional information regarding copyright ownership. |
| The ASF licenses this file to You under the Apache License, Version 2.0 |
| (the "License"); you may not use this file except in compliance with |
| the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| --> |
| |
| <document xmlns="http://maven.apache.org/XDOC/2.0" |
| xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| xsi:schemaLocation="http://maven.apache.org/XDOC/2.0 http://maven.apache.org/xsd/xdoc-2.0.xsd"> |
| <properties> |
| <title>Log4j 2 API</title> |
| <author email="rgoers@apache.org">Ralph Goers</author> |
| </properties> |
| |
| <body> |
| <section name="Log4j 2 API"> |
| <subsection name="Markers"> |
| <a name="Markers"/> |
| <p> |
| One of the primary purpose of a logging framework is to provide the means to generate debugging and |
| diagnostic information only when it is needed, and to allow filtering of that information so that it |
| does not overwhelm the system or the individuals who need to make use of it. As an example, an |
| application desires to log its entry, exit and other operations separately from SQL statements |
| being executed, and wishes to be able to log queries separate from updates. One way to accomplish |
| this is shown below: |
| </p> |
| <pre class="prettyprint linenums"><![CDATA[ |
| import org.apache.logging.log4j.Logger; |
| import org.apache.logging.log4j.LogManager; |
| import org.apache.logging.log4j.MarkerManager; |
| import java.util.Map; |
| |
| public class MyApp { |
| |
| private Logger logger = LogManager.getLogger(MyApp.class.getName()); |
| private static final Marker SQL_MARKER = MarkerManager.getMarker("SQL"); |
| private static final Marker UPDATE_MARKER = MarkerManager.getMarker("SQL_UPDATE").setParents(SQL_MARKER); |
| private static final Marker QUERY_MARKER = MarkerManager.getMarker("SQL_QUERY").setParents(SQL_MARKER); |
| |
| public String doQuery(String table) { |
| logger.traceEntry(); |
| |
| logger.debug(QUERY_MARKER, "SELECT * FROM {}", table); |
| |
| String result = ... |
| |
| return logger.traceExit(result); |
| } |
| |
| public String doUpdate(String table, Map<String, String> params) { |
| logger.traceEntry(); |
| |
| if (logger.isDebugEnabled()) { |
| logger.debug(UPDATE_MARKER, "UPDATE {} SET {}", table, formatCols()); |
| } |
| |
| String result = ... |
| |
| return logger.traceExit(result); |
| } |
| |
| private String formatCols(Map<String, String> cols) { |
| StringBuilder sb = new StringBuilder(); |
| boolean first = true; |
| for (Map.Entry<String, String> entry : cols.entrySet()) { |
| if (!first) { |
| sb.append(", "); |
| } |
| sb.append(entry.getKey()).append("=").append(entry.getValue()); |
| first = false; |
| } |
| return sb.toString(); |
| } |
| }]]></pre> |
| <p> |
| In the example above it is now possible to add MarkerFilters to only allow SQL update operations |
| to be logged, all SQL updates to be logged or to log everything in MyApp. |
| </p> |
| <p> |
| Some important rules about Markers must be considered when using them. |
| </p> |
| <ol> |
| <li>Markers must be unique. They are permanently registered by name so care should be taken |
| to insure that Markers used in your application are distinct from those in the application's |
| dependencies, unless that is what is desired.</li> |
| <li>Parent Markers can be added or removed dynamically. However, this is fairly expensive to do. |
| Instead, it is recommended that the parents be identified when obtaining the Marker the first time |
| as shown in the examples above. Specifically, the set method replaces all the markers in |
| a single operation while add and remove act on only a single Marker at a time.</li> |
| <li>Evaluating Markers with multiple ancestors is much more expensive than Markers with no parents. |
| For example, in one set of tests to evaluate whether a Marker matched its grandparent took 3 |
| times longer than evaluating the Marker itself. Even then though, evaluating Markers is |
| inexpensive compared to resolving the callers class name or line number.</li> |
| </ol> |
| </subsection> |
| </section> |
| </body> |
| </document> |