vy commented on code in PR #2584: URL: https://github.com/apache/logging-log4j2/pull/2584#discussion_r1603263563
########## src/site/antora/modules/ROOT/pages/manual/markers.adoc: ########## @@ -16,85 +16,111 @@ //// = 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] +Markers allow "tag" log statements with a Marker object, labeling them +as belonging to a specific type. For example, developers can use Markers to tag +log statements related to a particular subsystem or functionality. + +By using Markers, it is possible to filter log statements based on the Marker +and display only those log statements that are of interest, such as those +related to XML processing or SQL queries. + +Markers offer more fine-grained control over log filtering beyond log levels or package names. + +== Creating Markers + +To create a Marker, use the MarkerManager class. The MarkerManager class provides +a factory method to create a Marker object is used to tag log statements. + +[source, java] +---- +Marker SQL_MARKER = MarkerManager.getMarker("SQL"); +---- + +Since a Marker is reusable across multiple log statements, it makes sense +to store the Marker in a static final field and make it a constant. +Once done, use it as the first argument in the log statement. + +[source, java] +---- +logger.debug(SQL_MARKER, "Here is my SQL related message"); +---- + +A complete example is shown below. It creates the Marker as the constant +and then uses it to tag a log statement. The log method works "as usual," +but the marker needs to be added as the first argument. + +[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(); + private static final Marker SQL_MARKER = MarkerManager.getMarker("MY_APP_SQL"); <1> + + public void doQuery(String table) { + // do business logic here - 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); + logger.debug(SQL_MARKER, "SELECT * FROM {}", table); <2> + } +} +---- +<1> The marker is created and stored as a constant +<2> Using the marker to tag a log statement - public String doQuery(String table) { - logger.traceEntry(); +You must create a configuration file to write log statements tagged with the "SQL" marker to the console. +This file uses the `<MarkerFilter>` element to accept or deny log statements +based on the marker. - logger.debug(QUERY_MARKER, "SELECT * FROM {}", table); +The following code shows how the MarkerFilter is used in the configuration file. +It assumes that the Console appender is defined in the configuration file. - String result = ... +[source, xml] +---- +<Logger name="com.example" level="all" additivity="false"> + <AppenderRef ref="Console"> + <Filters> + <MarkerFilter marker="MY_APP_SQL" onMatch="ACCEPT" onMismatch="DENY"/> <1> + </Filters> + </AppenderRef> +</Logger> +---- +<1> The MarkerFilter is used to accept only SQL markers but deny others Review Comment: I think it is always nice to share complete examples, granted they don't blur the main message to be communicated with irrelevant details. ```suggestion Once a log event is tagged with a marker, we can apply specialized configuration on that particular marker. For instance, we can use a xref:manual/filters.adoc#MarkerFilter[`MarkerFilter`] to redirect log events whose marker matches a certain name to a dedicated SQL log file. In the example below, all log messages whose level is equal to or less-specific than `WARN` will be written to the console. If these matching messages are also `MY_SQL_APP`-marked, they will additionally be written to the `sql.log` file. [source,xml] ---- <?xml version="1.0" encoding="UTF-8"?> <Configuration xmlns="https://logging.apache.org/xml/ns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" https://logging.apache.org/xml/ns https://logging.apache.org/xml/ns/log4j-config-2.xsd"> <appenders> <Console name="CONSOLE"> <PatternLayout/> </Console> <File name="SQL_LOG" fileName="sql.log"> <MarkerFilter marker="MY_SQL_APP" onMatch="ACCEPT" onMismatch="DENY"/><!--2--> <JsonTemplateLayout/> </File> </appenders> <loggers> <root level="WARN"><!--1--> <AppenderRef ref="CONSOLE"/> <AppenderRef ref="SQL_LOG"/> </root> </loggers> </Configuration> ---- <1> Root logger definition stating that all log messages whose level is equal to or less-specific than `WARN` will be accepted and forwarded to `CONSOLE` and `SQL_LOG` appenders <2> `MarkFilter` only allowing `MY_SQL_APP`-marked messages for the `SQL_LOG` appender ``` ########## src/site/antora/modules/ROOT/pages/manual/markers.adoc: ########## @@ -16,85 +16,111 @@ //// = 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] +Markers allow "tag" log statements with a Marker object, labeling them +as belonging to a specific type. For example, developers can use Markers to tag +log statements related to a particular subsystem or functionality. + +By using Markers, it is possible to filter log statements based on the Marker +and display only those log statements that are of interest, such as those +related to XML processing or SQL queries. + +Markers offer more fine-grained control over log filtering beyond log levels or package names. + +== Creating Markers + +To create a Marker, use the MarkerManager class. The MarkerManager class provides +a factory method to create a Marker object is used to tag log statements. + +[source, java] +---- +Marker SQL_MARKER = MarkerManager.getMarker("SQL"); +---- + +Since a Marker is reusable across multiple log statements, it makes sense +to store the Marker in a static final field and make it a constant. +Once done, use it as the first argument in the log statement. + +[source, java] +---- +logger.debug(SQL_MARKER, "Here is my SQL related message"); +---- + +A complete example is shown below. It creates the Marker as the constant +and then uses it to tag a log statement. The log method works "as usual," +but the marker needs to be added as the first argument. + +[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(); + private static final Marker SQL_MARKER = MarkerManager.getMarker("MY_APP_SQL"); <1> + + public void doQuery(String table) { + // do business logic here - 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); + logger.debug(SQL_MARKER, "SELECT * FROM {}", table); <2> + } +} +---- +<1> The marker is created and stored as a constant +<2> Using the marker to tag a log statement - public String doQuery(String table) { - logger.traceEntry(); +You must create a configuration file to write log statements tagged with the "SQL" marker to the console. +This file uses the `<MarkerFilter>` element to accept or deny log statements +based on the marker. - logger.debug(QUERY_MARKER, "SELECT * FROM {}", table); +The following code shows how the MarkerFilter is used in the configuration file. +It assumes that the Console appender is defined in the configuration file. Review Comment: I rewrite the example below, hence truncating this paragraph. (Sorry, I cannot add a comment to this entire block, hence I add comments to each paragraph individually.) ```suggestion ``` ########## src/site/antora/modules/ROOT/pages/manual/markers.adoc: ########## @@ -16,85 +16,111 @@ //// = 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] +Markers allow "tag" log statements with a Marker object, labeling them +as belonging to a specific type. For example, developers can use Markers to tag +log statements related to a particular subsystem or functionality. + +By using Markers, it is possible to filter log statements based on the Marker +and display only those log statements that are of interest, such as those +related to XML processing or SQL queries. + +Markers offer more fine-grained control over log filtering beyond log levels or package names. + +== Creating Markers + +To create a Marker, use the MarkerManager class. The MarkerManager class provides +a factory method to create a Marker object is used to tag log statements. + +[source, java] +---- +Marker SQL_MARKER = MarkerManager.getMarker("SQL"); +---- + +Since a Marker is reusable across multiple log statements, it makes sense +to store the Marker in a static final field and make it a constant. +Once done, use it as the first argument in the log statement. + +[source, java] +---- +logger.debug(SQL_MARKER, "Here is my SQL related message"); +---- + +A complete example is shown below. It creates the Marker as the constant +and then uses it to tag a log statement. The log method works "as usual," +but the marker needs to be added as the first argument. + +[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(); + private static final Marker SQL_MARKER = MarkerManager.getMarker("MY_APP_SQL"); <1> + + public void doQuery(String table) { + // do business logic here - 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); + logger.debug(SQL_MARKER, "SELECT * FROM {}", table); <2> + } +} +---- +<1> The marker is created and stored as a constant +<2> Using the marker to tag a log statement - public String doQuery(String table) { - logger.traceEntry(); +You must create a configuration file to write log statements tagged with the "SQL" marker to the console. +This file uses the `<MarkerFilter>` element to accept or deny log statements +based on the marker. - logger.debug(QUERY_MARKER, "SELECT * FROM {}", table); +The following code shows how the MarkerFilter is used in the configuration file. +It assumes that the Console appender is defined in the configuration file. - String result = ... +[source, xml] +---- +<Logger name="com.example" level="all" additivity="false"> + <AppenderRef ref="Console"> + <Filters> + <MarkerFilter marker="MY_APP_SQL" onMatch="ACCEPT" onMismatch="DENY"/> <1> + </Filters> + </AppenderRef> +</Logger> +---- +<1> The MarkerFilter is used to accept only SQL markers but deny others - return logger.traceExit(result); - } +== Parent and child Markers Review Comment: ```suggestion [#hierarchy] == Parent and child markers ``` ########## src/site/antora/modules/ROOT/pages/manual/markers.adoc: ########## @@ -16,85 +16,111 @@ //// = 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] +Markers allow "tag" log statements with a Marker object, labeling them +as belonging to a specific type. For example, developers can use Markers to tag +log statements related to a particular subsystem or functionality. + +By using Markers, it is possible to filter log statements based on the Marker +and display only those log statements that are of interest, such as those +related to XML processing or SQL queries. + +Markers offer more fine-grained control over log filtering beyond log levels or package names. + +== Creating Markers Review Comment: ```suggestion [#create] == Creating Markers ``` ########## src/site/antora/modules/ROOT/pages/manual/markers.adoc: ########## @@ -16,85 +16,111 @@ //// = 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] +Markers allow "tag" log statements with a Marker object, labeling them +as belonging to a specific type. For example, developers can use Markers to tag +log statements related to a particular subsystem or functionality. + +By using Markers, it is possible to filter log statements based on the Marker +and display only those log statements that are of interest, such as those +related to XML processing or SQL queries. + +Markers offer more fine-grained control over log filtering beyond log levels or package names. + +== Creating Markers + +To create a Marker, use the MarkerManager class. The MarkerManager class provides +a factory method to create a Marker object is used to tag log statements. + +[source, java] +---- +Marker SQL_MARKER = MarkerManager.getMarker("SQL"); +---- + +Since a Marker is reusable across multiple log statements, it makes sense +to store the Marker in a static final field and make it a constant. +Once done, use it as the first argument in the log statement. + +[source, java] +---- +logger.debug(SQL_MARKER, "Here is my SQL related message"); +---- + +A complete example is shown below. It creates the Marker as the constant +and then uses it to tag a log statement. The log method works "as usual," +but the marker needs to be added as the first argument. + +[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(); + private static final Marker SQL_MARKER = MarkerManager.getMarker("MY_APP_SQL"); <1> + + public void doQuery(String table) { + // do business logic here - 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); + logger.debug(SQL_MARKER, "SELECT * FROM {}", table); <2> + } +} +---- +<1> The marker is created and stored as a constant +<2> Using the marker to tag a log statement - public String doQuery(String table) { - logger.traceEntry(); +You must create a configuration file to write log statements tagged with the "SQL" marker to the console. +This file uses the `<MarkerFilter>` element to accept or deny log statements +based on the marker. - logger.debug(QUERY_MARKER, "SELECT * FROM {}", table); +The following code shows how the MarkerFilter is used in the configuration file. +It assumes that the Console appender is defined in the configuration file. - String result = ... +[source, xml] +---- +<Logger name="com.example" level="all" additivity="false"> + <AppenderRef ref="Console"> + <Filters> + <MarkerFilter marker="MY_APP_SQL" onMatch="ACCEPT" onMismatch="DENY"/> <1> + </Filters> + </AppenderRef> +</Logger> +---- +<1> The MarkerFilter is used to accept only SQL markers but deny others - return logger.traceExit(result); - } +== Parent and child Markers - public String doUpdate(String table, Map<String, String> params) { - logger.traceEntry(); +A Marker can have zero or more parent Markers. This allows for a hierarchy of Markers. +To create such a hierarchy, you must use the `setParents` method on the Marker object +after you create the child marker. This method will connect both markers. - if (logger.isDebugEnabled()) { - logger.debug(UPDATE_MARKER, "UPDATE {} SET {}", table, formatCols()); - } - - String result = ... +[source, java] +---- +Marker SQL_MARKER = MarkerManager.getMarker("MY_APP_SQL"); <1> +Marker UPDATE_MARKER = MarkerManager.getMarker("MY_APP_SQL_UPDATE").setParents(SQL_MARKER); <2> +---- +<1> Creating the parent marker +<2> Creating the child marker and connecting it to the parent marker - return logger.traceExit(result); - } +The child marker works as expected by adding to the log method as the first argument. - 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(); - } -} +[source, java] ---- +logger.debug(UPDATE_MARKER, "UPDATE {} SET {}", table, values); +---- + +However, it is now possible to filter for the parent, of more fine-grained, for the child marker. Review Comment: I think this is what you tried to mean: ```suggestion It is now possible to either filter for the parent, or, be more specific, and filter only for the child marker. ``` ########## src/site/antora/modules/ROOT/pages/manual/markers.adoc: ########## @@ -16,85 +16,111 @@ //// = 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] +Markers allow "tag" log statements with a Marker object, labeling them +as belonging to a specific type. For example, developers can use Markers to tag +log statements related to a particular subsystem or functionality. + +By using Markers, it is possible to filter log statements based on the Marker +and display only those log statements that are of interest, such as those +related to XML processing or SQL queries. + +Markers offer more fine-grained control over log filtering beyond log levels or package names. + +== Creating Markers + +To create a Marker, use the MarkerManager class. The MarkerManager class provides +a factory method to create a Marker object is used to tag log statements. + +[source, java] +---- +Marker SQL_MARKER = MarkerManager.getMarker("SQL"); +---- + +Since a Marker is reusable across multiple log statements, it makes sense +to store the Marker in a static final field and make it a constant. +Once done, use it as the first argument in the log statement. + +[source, java] +---- +logger.debug(SQL_MARKER, "Here is my SQL related message"); +---- + +A complete example is shown below. It creates the Marker as the constant +and then uses it to tag a log statement. The log method works "as usual," +but the marker needs to be added as the first argument. + +[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(); Review Comment: Adhering to the syntax we suggest users to use above (i.e., use `static final`) and in `5min.adoc`: ```suggestion private static final Logger LOGGER = LogManager.getLogger(); ``` ########## src/site/antora/modules/ROOT/pages/manual/markers.adoc: ########## @@ -16,85 +16,111 @@ //// = 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] +Markers allow "tag" log statements with a Marker object, labeling them +as belonging to a specific type. For example, developers can use Markers to tag +log statements related to a particular subsystem or functionality. + +By using Markers, it is possible to filter log statements based on the Marker +and display only those log statements that are of interest, such as those +related to XML processing or SQL queries. + +Markers offer more fine-grained control over log filtering beyond log levels or package names. + +== Creating Markers + +To create a Marker, use the MarkerManager class. The MarkerManager class provides +a factory method to create a Marker object is used to tag log statements. + +[source, java] +---- +Marker SQL_MARKER = MarkerManager.getMarker("SQL"); +---- + +Since a Marker is reusable across multiple log statements, it makes sense +to store the Marker in a static final field and make it a constant. +Once done, use it as the first argument in the log statement. Review Comment: ```suggestion Since a `Marker` is reusable across multiple log statements, it makes sense to store the `Marker` in a `static final` field and make it a constant. Once created, use it as the first argument in the log statement: ``` ########## src/site/antora/modules/ROOT/pages/manual/markers.adoc: ########## @@ -16,85 +16,111 @@ //// = 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] +Markers allow "tag" log statements with a Marker object, labeling them +as belonging to a specific type. For example, developers can use Markers to tag +log statements related to a particular subsystem or functionality. + +By using Markers, it is possible to filter log statements based on the Marker +and display only those log statements that are of interest, such as those +related to XML processing or SQL queries. + +Markers offer more fine-grained control over log filtering beyond log levels or package names. + +== Creating Markers + +To create a Marker, use the MarkerManager class. The MarkerManager class provides +a factory method to create a Marker object is used to tag log statements. + +[source, java] +---- +Marker SQL_MARKER = MarkerManager.getMarker("SQL"); +---- + +Since a Marker is reusable across multiple log statements, it makes sense +to store the Marker in a static final field and make it a constant. +Once done, use it as the first argument in the log statement. + +[source, java] +---- +logger.debug(SQL_MARKER, "Here is my SQL related message"); +---- + +A complete example is shown below. It creates the Marker as the constant +and then uses it to tag a log statement. The log method works "as usual," +but the marker needs to be added as the first argument. + +[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(); + private static final Marker SQL_MARKER = MarkerManager.getMarker("MY_APP_SQL"); <1> + + public void doQuery(String table) { + // do business logic here - 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); + logger.debug(SQL_MARKER, "SELECT * FROM {}", table); <2> Review Comment: ```suggestion LOGGER.debug(SQL_MARKER, "SELECT * FROM {}", table); <2> ``` ########## src/site/antora/modules/ROOT/pages/manual/markers.adoc: ########## @@ -16,85 +16,111 @@ //// = 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] +Markers allow "tag" log statements with a Marker object, labeling them +as belonging to a specific type. For example, developers can use Markers to tag +log statements related to a particular subsystem or functionality. + +By using Markers, it is possible to filter log statements based on the Marker +and display only those log statements that are of interest, such as those +related to XML processing or SQL queries. + +Markers offer more fine-grained control over log filtering beyond log levels or package names. + +== Creating Markers + +To create a Marker, use the MarkerManager class. The MarkerManager class provides +a factory method to create a Marker object is used to tag log statements. + +[source, java] +---- +Marker SQL_MARKER = MarkerManager.getMarker("SQL"); +---- + +Since a Marker is reusable across multiple log statements, it makes sense +to store the Marker in a static final field and make it a constant. +Once done, use it as the first argument in the log statement. + +[source, java] +---- +logger.debug(SQL_MARKER, "Here is my SQL related message"); +---- + +A complete example is shown below. It creates the Marker as the constant +and then uses it to tag a log statement. The log method works "as usual," +but the marker needs to be added as the first argument. + +[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(); + private static final Marker SQL_MARKER = MarkerManager.getMarker("MY_APP_SQL"); <1> + + public void doQuery(String table) { + // do business logic here - 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); + logger.debug(SQL_MARKER, "SELECT * FROM {}", table); <2> + } +} +---- +<1> The marker is created and stored as a constant +<2> Using the marker to tag a log statement - public String doQuery(String table) { - logger.traceEntry(); +You must create a configuration file to write log statements tagged with the "SQL" marker to the console. +This file uses the `<MarkerFilter>` element to accept or deny log statements +based on the marker. Review Comment: I rewrite the example below, hence truncating this paragraph. (Sorry, I cannot add a comment to this entire block, hence I add comments to each paragraph individually.) ```suggestion ``` ########## src/site/antora/modules/ROOT/pages/manual/markers.adoc: ########## @@ -16,85 +16,111 @@ //// = 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] +Markers allow "tag" log statements with a Marker object, labeling them +as belonging to a specific type. For example, developers can use Markers to tag +log statements related to a particular subsystem or functionality. + +By using Markers, it is possible to filter log statements based on the Marker +and display only those log statements that are of interest, such as those +related to XML processing or SQL queries. + +Markers offer more fine-grained control over log filtering beyond log levels or package names. + +== Creating Markers + +To create a Marker, use the MarkerManager class. The MarkerManager class provides +a factory method to create a Marker object is used to tag log statements. + +[source, java] +---- +Marker SQL_MARKER = MarkerManager.getMarker("SQL"); +---- + +Since a Marker is reusable across multiple log statements, it makes sense +to store the Marker in a static final field and make it a constant. +Once done, use it as the first argument in the log statement. + +[source, java] +---- +logger.debug(SQL_MARKER, "Here is my SQL related message"); +---- + +A complete example is shown below. It creates the Marker as the constant +and then uses it to tag a log statement. The log method works "as usual," +but the marker needs to be added as the first argument. Review Comment: ```suggestion A complete example is shown below. It creates the marker as the constant and then uses it to tag a log statement. The log method works _as usual_, but the marker needs to be added as the first argument: ``` ########## src/site/antora/modules/ROOT/pages/manual/markers.adoc: ########## @@ -16,85 +16,111 @@ //// = 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] +Markers allow "tag" log statements with a Marker object, labeling them +as belonging to a specific type. For example, developers can use Markers to tag +log statements related to a particular subsystem or functionality. + +By using Markers, it is possible to filter log statements based on the Marker +and display only those log statements that are of interest, such as those +related to XML processing or SQL queries. + +Markers offer more fine-grained control over log filtering beyond log levels or package names. + +== Creating Markers + +To create a Marker, use the MarkerManager class. The MarkerManager class provides +a factory method to create a Marker object is used to tag log statements. + +[source, java] +---- +Marker SQL_MARKER = MarkerManager.getMarker("SQL"); +---- + +Since a Marker is reusable across multiple log statements, it makes sense +to store the Marker in a static final field and make it a constant. +Once done, use it as the first argument in the log statement. + +[source, java] +---- +logger.debug(SQL_MARKER, "Here is my SQL related message"); +---- + +A complete example is shown below. It creates the Marker as the constant +and then uses it to tag a log statement. The log method works "as usual," +but the marker needs to be added as the first argument. + +[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(); + private static final Marker SQL_MARKER = MarkerManager.getMarker("MY_APP_SQL"); <1> + + public void doQuery(String table) { + // do business logic here - 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); + logger.debug(SQL_MARKER, "SELECT * FROM {}", table); <2> + } +} +---- +<1> The marker is created and stored as a constant +<2> Using the marker to tag a log statement - public String doQuery(String table) { - logger.traceEntry(); +You must create a configuration file to write log statements tagged with the "SQL" marker to the console. +This file uses the `<MarkerFilter>` element to accept or deny log statements +based on the marker. - logger.debug(QUERY_MARKER, "SELECT * FROM {}", table); +The following code shows how the MarkerFilter is used in the configuration file. +It assumes that the Console appender is defined in the configuration file. - String result = ... +[source, xml] +---- +<Logger name="com.example" level="all" additivity="false"> + <AppenderRef ref="Console"> + <Filters> + <MarkerFilter marker="MY_APP_SQL" onMatch="ACCEPT" onMismatch="DENY"/> <1> + </Filters> + </AppenderRef> +</Logger> +---- +<1> The MarkerFilter is used to accept only SQL markers but deny others - return logger.traceExit(result); - } +== Parent and child Markers - public String doUpdate(String table, Map<String, String> params) { - logger.traceEntry(); +A Marker can have zero or more parent Markers. This allows for a hierarchy of Markers. +To create such a hierarchy, you must use the `setParents` method on the Marker object +after you create the child marker. This method will connect both markers. - if (logger.isDebugEnabled()) { - logger.debug(UPDATE_MARKER, "UPDATE {} SET {}", table, formatCols()); - } - - String result = ... +[source, java] +---- +Marker SQL_MARKER = MarkerManager.getMarker("MY_APP_SQL"); <1> +Marker UPDATE_MARKER = MarkerManager.getMarker("MY_APP_SQL_UPDATE").setParents(SQL_MARKER); <2> Review Comment: ```suggestion Marker SQL_MARKER = MarkerManager.getMarker("MY_APP_SQL"); // <1> Marker UPDATE_MARKER = MarkerManager.getMarker("MY_APP_SQL_UPDATE").setParents(SQL_MARKER); // <2> ``` ########## src/site/antora/modules/ROOT/pages/manual/markers.adoc: ########## @@ -16,85 +16,111 @@ //// = 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] +Markers allow "tag" log statements with a Marker object, labeling them +as belonging to a specific type. For example, developers can use Markers to tag +log statements related to a particular subsystem or functionality. + +By using Markers, it is possible to filter log statements based on the Marker +and display only those log statements that are of interest, such as those +related to XML processing or SQL queries. + +Markers offer more fine-grained control over log filtering beyond log levels or package names. + +== Creating Markers + +To create a Marker, use the MarkerManager class. The MarkerManager class provides +a factory method to create a Marker object is used to tag log statements. + +[source, java] +---- +Marker SQL_MARKER = MarkerManager.getMarker("SQL"); +---- + +Since a Marker is reusable across multiple log statements, it makes sense +to store the Marker in a static final field and make it a constant. +Once done, use it as the first argument in the log statement. + +[source, java] +---- +logger.debug(SQL_MARKER, "Here is my SQL related message"); +---- + +A complete example is shown below. It creates the Marker as the constant +and then uses it to tag a log statement. The log method works "as usual," +but the marker needs to be added as the first argument. + +[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(); + private static final Marker SQL_MARKER = MarkerManager.getMarker("MY_APP_SQL"); <1> + + public void doQuery(String table) { + // do business logic here - 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); + logger.debug(SQL_MARKER, "SELECT * FROM {}", table); <2> + } +} +---- +<1> The marker is created and stored as a constant +<2> Using the marker to tag a log statement - public String doQuery(String table) { - logger.traceEntry(); +You must create a configuration file to write log statements tagged with the "SQL" marker to the console. +This file uses the `<MarkerFilter>` element to accept or deny log statements +based on the marker. - logger.debug(QUERY_MARKER, "SELECT * FROM {}", table); +The following code shows how the MarkerFilter is used in the configuration file. +It assumes that the Console appender is defined in the configuration file. - String result = ... +[source, xml] +---- +<Logger name="com.example" level="all" additivity="false"> + <AppenderRef ref="Console"> + <Filters> + <MarkerFilter marker="MY_APP_SQL" onMatch="ACCEPT" onMismatch="DENY"/> <1> + </Filters> + </AppenderRef> +</Logger> +---- +<1> The MarkerFilter is used to accept only SQL markers but deny others - return logger.traceExit(result); - } +== Parent and child Markers - public String doUpdate(String table, Map<String, String> params) { - logger.traceEntry(); +A Marker can have zero or more parent Markers. This allows for a hierarchy of Markers. +To create such a hierarchy, you must use the `setParents` method on the Marker object +after you create the child marker. This method will connect both markers. - if (logger.isDebugEnabled()) { - logger.debug(UPDATE_MARKER, "UPDATE {} SET {}", table, formatCols()); - } - - String result = ... +[source, java] +---- +Marker SQL_MARKER = MarkerManager.getMarker("MY_APP_SQL"); <1> +Marker UPDATE_MARKER = MarkerManager.getMarker("MY_APP_SQL_UPDATE").setParents(SQL_MARKER); <2> +---- +<1> Creating the parent marker +<2> Creating the child marker and connecting it to the parent marker - return logger.traceExit(result); - } +The child marker works as expected by adding to the log method as the first argument. - 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(); - } -} +[source, java] ---- +logger.debug(UPDATE_MARKER, "UPDATE {} SET {}", table, values); +---- + +However, it is now possible to filter for the parent, of more fine-grained, for the child marker. + +== Pitfalls Review Comment: ```suggestion [#pitfalls] == Pitfalls ``` ########## src/site/antora/modules/ROOT/pages/manual/markers.adoc: ########## @@ -16,85 +16,111 @@ //// = 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] +Markers allow "tag" log statements with a Marker object, labeling them +as belonging to a specific type. For example, developers can use Markers to tag +log statements related to a particular subsystem or functionality. + +By using Markers, it is possible to filter log statements based on the Marker +and display only those log statements that are of interest, such as those +related to XML processing or SQL queries. + +Markers offer more fine-grained control over log filtering beyond log levels or package names. + +== Creating Markers + +To create a Marker, use the MarkerManager class. The MarkerManager class provides +a factory method to create a Marker object is used to tag log statements. Review Comment: ```suggestion To create a `Marker`, use the `MarkerManager` class as follows: ``` -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: notifications-unsubscr...@logging.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org