////
    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.
////
= Markers

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:

[source,java]
----
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();
    }
}
----

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.

Some important rules about Markers must be considered when using them.

1.  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.
2.  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.
3.  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.
