View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements. See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache license, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License. You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the license for the specific language governing permissions and
15   * limitations under the license.
16   */
17  
18  package org.apache.logging.log4j.core.tools;
19  
20  import java.io.PrintStream;
21  import java.util.ArrayList;
22  import java.util.Arrays;
23  import java.util.List;
24  
25  /**
26   * Generates source code for custom or extended logger wrappers.
27   * <p>
28   * Usage:
29   * <p>
30   * To generate source code for an extended logger that adds custom log levels to the existing ones: <br>
31   * {@code java org.apache.logging.log4j.core.tools.Generate$ExtendedLogger <logger.class.name> <CUSTOMLEVEL>=<WEIGHT>
32   * [CUSTOMLEVEL2=WEIGHT2 [CUSTOMLEVEL3=WEIGHT3] ...]}
33   * <p>
34   * Example of creating an extended logger:<br>
35   * {@code java org.apache.logging.log4j.core.tools.Generate$ExtendedLogger com.mycomp.ExtLogger DIAG=350 NOTICE=450
36   * VERBOSE=550}
37   * <p>
38   * To generate source code for a custom logger that replaces the existing log levels with custom ones: <br>
39   * {@code java org.apache.logging.log4j.core.tools.Generate$CustomLogger <logger.class.name> <CUSTOMLEVEL>=<WEIGHT>
40   * [CUSTOMLEVEL2=WEIGHT2 [CUSTOMLEVEL3=WEIGHT3] ...]}
41   * <p>
42   * Example of creating a custom logger:<br>
43   * {@code java org.apache.logging.log4j.core.tools.Generate$CustomLogger com.mycomp.MyLogger DEFCON1=350 DEFCON2=450
44   * DEFCON3=550}
45   */
46  public final class Generate {
47      // Implementation note:
48      // The generated code is in the user's namespace which has its own versioning scheme, so
49      // any @since tags in the generated code deliberately mention "Log4j-2.x" rather than just the log4j version number.
50  
51      static final String PACKAGE_DECLARATION = "package %s;%n%n";
52  
53      static enum Type {
54          CUSTOM {
55              @Override
56              String imports() {
57                  //@formatter:off
58                  return ""
59                          + "import java.io.Serializable;%n"
60                          + "import org.apache.logging.log4j.Level;%n"
61                          + "import org.apache.logging.log4j.LogManager;%n"
62                          + "import org.apache.logging.log4j.Logger;%n"
63                          + "import org.apache.logging.log4j.Marker;%n"
64                          + "import org.apache.logging.log4j.message.Message;%n"
65                          + "import org.apache.logging.log4j.message.MessageFactory;%n"
66                          + "import org.apache.logging.log4j.spi.AbstractLogger;%n"
67                          + "import org.apache.logging.log4j.spi.ExtendedLoggerWrapper;%n"
68                          + "import org.apache.logging.log4j.util.MessageSupplier;%n"
69                          + "import org.apache.logging.log4j.util.Supplier;%n"
70                          + "%n";
71                  //@formatter:on
72              }
73  
74              @Override
75              String declaration() {
76                  //@formatter:off
77                  return ""
78                          + "/**%n"
79                          + " * Custom Logger interface with convenience methods for%n"
80                          + " * %s%n"
81                          + " * <p>Compatible with Log4j 2.6 or higher.</p>%n"
82                          + " */%n"
83                          + "public final class %s implements Serializable {%n"
84                          + "    private static final long serialVersionUID = " + System.nanoTime() + "L;%n"
85                          + "    private final ExtendedLoggerWrapper logger;%n"
86                          + "%n";
87                  //@formatter:on
88              }
89  
90              @Override
91              String constructor() {
92                  //@formatter:off
93                  return ""
94                          + "%n"
95                          + "    private %s(final Logger logger) {%n"
96                          + "        this.logger = new ExtendedLoggerWrapper((AbstractLogger) logger, logger.getName(), "
97                          + "logger.getMessageFactory());%n"
98                          + "    }%n";
99                  //@formatter:on
100             }
101 
102             @Override
103             Class<?> generator() {
104                 return CustomLogger.class;
105             }
106         },
107         EXTEND {
108             @Override
109             String imports() {
110                 //@formatter:off
111                 return ""
112                         + "import org.apache.logging.log4j.Level;%n"
113                         + "import org.apache.logging.log4j.LogManager;%n"
114                         + "import org.apache.logging.log4j.Logger;%n"
115                         + "import org.apache.logging.log4j.Marker;%n"
116                         + "import org.apache.logging.log4j.message.Message;%n"
117                         + "import org.apache.logging.log4j.message.MessageFactory;%n"
118                         + "import org.apache.logging.log4j.spi.AbstractLogger;%n"
119                         + "import org.apache.logging.log4j.spi.ExtendedLoggerWrapper;%n"
120                         + "import org.apache.logging.log4j.util.MessageSupplier;%n"
121                         + "import org.apache.logging.log4j.util.Supplier;%n"
122                         + "%n";
123                 //@formatter:on
124             }
125 
126             @Override
127             String declaration() {
128                 //@formatter:off
129                 return ""
130                         + "/**%n"
131                         + " * Extended Logger interface with convenience methods for%n"
132                         + " * %s%n"
133                         + " * <p>Compatible with Log4j 2.6 or higher.</p>%n"
134                         + " */%n"
135                         + "public final class %s extends ExtendedLoggerWrapper {%n"
136                         + "    private static final long serialVersionUID = " + System.nanoTime() + "L;%n"
137                         + "    private final ExtendedLoggerWrapper logger;%n"
138                         + "%n";
139                 //@formatter:on
140             }
141 
142             @Override
143             String constructor() {
144                 //@formatter:off
145                 return ""
146                         + "%n"
147                         + "    private %s(final Logger logger) {%n"
148                         + "        super((AbstractLogger) logger, logger.getName(), logger.getMessageFactory());%n"
149                         + "        this.logger = this;%n"
150                         + "    }%n";
151                 //@formatter:on
152             }
153 
154             @Override
155             Class<?> generator() {
156                 return ExtendedLogger.class;
157             }
158         };
159         abstract String imports();
160 
161         abstract String declaration();
162 
163         abstract String constructor();
164 
165         abstract Class<?> generator();
166     }
167 
168     static final String FQCN_FIELD = ""
169             + "    private static final String FQCN = %s.class.getName();%n";
170 
171     static final String LEVEL_FIELD = ""
172             + "    private static final Level %s = Level.forName(\"%s\", %d);%n";
173 
174     static final String FACTORY_METHODS = ""
175             //@formatter:off
176             + "%n"
177             + "    /**%n"
178             + "     * Returns a custom Logger with the name of the calling class.%n"
179             + "     * %n"
180             + "     * @return The custom Logger for the calling class.%n"
181             + "     */%n"
182             + "    public static CLASSNAME create() {%n"
183             + "        final Logger wrapped = LogManager.getLogger();%n"
184             + "        return new CLASSNAME(wrapped);%n"
185             + "    }%n"
186             + "%n"
187             + "    /**%n"
188             + "     * Returns a custom Logger using the fully qualified name of the Class as%n"
189             + "     * the Logger name.%n"
190             + "     * %n"
191             + "     * @param loggerName The Class whose name should be used as the Logger name.%n"
192             + "     *            If null it will default to the calling class.%n"
193             + "     * @return The custom Logger.%n"
194             + "     */%n"
195             + "    public static CLASSNAME create(final Class<?> loggerName) {%n"
196             + "        final Logger wrapped = LogManager.getLogger(loggerName);%n"
197             + "        return new CLASSNAME(wrapped);%n"
198             + "    }%n"
199             + "%n"
200             + "    /**%n"
201             + "     * Returns a custom Logger using the fully qualified name of the Class as%n"
202             + "     * the Logger name.%n"
203             + "     * %n"
204             + "     * @param loggerName The Class whose name should be used as the Logger name.%n"
205             + "     *            If null it will default to the calling class.%n"
206             + "     * @param messageFactory The message factory is used only when creating a%n"
207             + "     *            logger, subsequent use does not change the logger but will log%n"
208             + "     *            a warning if mismatched.%n"
209             + "     * @return The custom Logger.%n"
210             + "     */%n"
211             + "    public static CLASSNAME create(final Class<?> loggerName, final MessageFactory"
212             + " messageFactory) {%n"
213             + "        final Logger wrapped = LogManager.getLogger(loggerName, messageFactory);%n"
214             + "        return new CLASSNAME(wrapped);%n"
215             + "    }%n"
216             + "%n"
217             + "    /**%n"
218             + "     * Returns a custom Logger using the fully qualified class name of the value%n"
219             + "     * as the Logger name.%n"
220             + "     * %n"
221             + "     * @param value The value whose class name should be used as the Logger%n"
222             + "     *            name. If null the name of the calling class will be used as%n"
223             + "     *            the logger name.%n"
224             + "     * @return The custom Logger.%n"
225             + "     */%n"
226             + "    public static CLASSNAME create(final Object value) {%n"
227             + "        final Logger wrapped = LogManager.getLogger(value);%n"
228             + "        return new CLASSNAME(wrapped);%n"
229             + "    }%n"
230             + "%n"
231             + "    /**%n"
232             + "     * Returns a custom Logger using the fully qualified class name of the value%n"
233             + "     * as the Logger name.%n"
234             + "     * %n"
235             + "     * @param value The value whose class name should be used as the Logger%n"
236             + "     *            name. If null the name of the calling class will be used as%n"
237             + "     *            the logger name.%n"
238             + "     * @param messageFactory The message factory is used only when creating a%n"
239             + "     *            logger, subsequent use does not change the logger but will log%n"
240             + "     *            a warning if mismatched.%n"
241             + "     * @return The custom Logger.%n"
242             + "     */%n"
243             + "    public static CLASSNAME create(final Object value, final MessageFactory messageFactory) {%n"
244             + "        final Logger wrapped = LogManager.getLogger(value, messageFactory);%n"
245             + "        return new CLASSNAME(wrapped);%n"
246             + "    }%n"
247             + "%n"
248             + "    /**%n"
249             + "     * Returns a custom Logger with the specified name.%n"
250             + "     * %n"
251             + "     * @param name The logger name. If null the name of the calling class will%n"
252             + "     *            be used.%n"
253             + "     * @return The custom Logger.%n"
254             + "     */%n"
255             + "    public static CLASSNAME create(final String name) {%n"
256             + "        final Logger wrapped = LogManager.getLogger(name);%n"
257             + "        return new CLASSNAME(wrapped);%n"
258             + "    }%n"
259             + "%n"
260             + "    /**%n"
261             + "     * Returns a custom Logger with the specified name.%n"
262             + "     * %n"
263             + "     * @param name The logger name. If null the name of the calling class will%n"
264             + "     *            be used.%n"
265             + "     * @param messageFactory The message factory is used only when creating a%n"
266             + "     *            logger, subsequent use does not change the logger but will log%n"
267             + "     *            a warning if mismatched.%n"
268             + "     * @return The custom Logger.%n"
269             + "     */%n"
270             + "    public static CLASSNAME create(final String name, final MessageFactory messageFactory) {%n"
271             + "        final Logger wrapped = LogManager.getLogger(name, messageFactory);%n"
272             + "        return new CLASSNAME(wrapped);%n"
273             + "    }%n";
274             //@formatter:on
275 
276     static final String METHODS = ""
277             //@formatter:off
278             + "%n"
279             + "    /**%n"
280             + "     * Logs a message with the specific Marker at the {@code CUSTOM_LEVEL} level.%n"
281             + "     * %n"
282             + "     * @param marker the marker data specific to this log statement%n"
283             + "     * @param msg the message string to be logged%n"
284             + "     */%n"
285             + "    public void methodName(final Marker marker, final Message msg) {%n"
286             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, marker, msg, (Throwable) null);%n"
287             + "    }%n"
288             + "%n"
289             + "    /**%n"
290             + "     * Logs a message with the specific Marker at the {@code CUSTOM_LEVEL} level.%n"
291             + "     * %n"
292             + "     * @param marker the marker data specific to this log statement%n"
293             + "     * @param msg the message string to be logged%n"
294             + "     * @param t A Throwable or null.%n"
295             + "     */%n"
296             + "    public void methodName(final Marker marker, final Message msg, final Throwable t) {%n"
297             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, marker, msg, t);%n"
298             + "    }%n"
299             + "%n"
300             + "    /**%n"
301             + "     * Logs a message object with the {@code CUSTOM_LEVEL} level.%n"
302             + "     * %n"
303             + "     * @param marker the marker data specific to this log statement%n"
304             + "     * @param message the message object to log.%n"
305             + "     */%n"
306             + "    public void methodName(final Marker marker, final Object message) {%n"
307             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, marker, message, (Throwable) null);%n"
308             + "    }%n"
309             + "%n"
310             + "    /**%n"
311             + "     * Logs a message CharSequence with the {@code CUSTOM_LEVEL} level.%n"
312             + "     * %n"
313             + "     * @param marker the marker data specific to this log statement%n"
314             + "     * @param message the message CharSequence to log.%n"
315             + "     * @since Log4j-2.6%n"
316             + "     */%n"
317             + "    public void methodName(final Marker marker, final CharSequence message) {%n"
318             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, marker, message, (Throwable) null);%n"
319             + "    }%n"
320             + "%n"
321             + "    /**%n"
322             + "     * Logs a message at the {@code CUSTOM_LEVEL} level including the stack trace of%n"
323             + "     * the {@link Throwable} {@code t} passed as parameter.%n"
324             + "     * %n"
325             + "     * @param marker the marker data specific to this log statement%n"
326             + "     * @param message the message to log.%n"
327             + "     * @param t the exception to log, including its stack trace.%n"
328             + "     */%n"
329             + "    public void methodName(final Marker marker, final Object message, final Throwable t) {%n"
330             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, marker, message, t);%n"
331             + "    }%n"
332             + "%n"
333             + "    /**%n"
334             + "     * Logs a message at the {@code CUSTOM_LEVEL} level including the stack trace of%n"
335             + "     * the {@link Throwable} {@code t} passed as parameter.%n"
336             + "     * %n"
337             + "     * @param marker the marker data specific to this log statement%n"
338             + "     * @param message the CharSequence to log.%n"
339             + "     * @param t the exception to log, including its stack trace.%n"
340             + "     * @since Log4j-2.6%n"
341             + "     */%n"
342             + "    public void methodName(final Marker marker, final CharSequence message, final Throwable t) {%n"
343             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, marker, message, t);%n"
344             + "    }%n"
345             + "%n"
346             + "    /**%n"
347             + "     * Logs a message object with the {@code CUSTOM_LEVEL} level.%n"
348             + "     * %n"
349             + "     * @param marker the marker data specific to this log statement%n"
350             + "     * @param message the message object to log.%n"
351             + "     */%n"
352             + "    public void methodName(final Marker marker, final String message) {%n"
353             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, marker, message, (Throwable) null);%n"
354             + "    }%n"
355             + "%n"
356             + "    /**%n"
357             + "     * Logs a message with parameters at the {@code CUSTOM_LEVEL} level.%n"
358             + "     * %n"
359             + "     * @param marker the marker data specific to this log statement%n"
360             + "     * @param message the message to log; the format depends on the message factory.%n"
361             + "     * @param params parameters to the message.%n"
362             + "     * @see #getMessageFactory()%n"
363             + "     */%n"
364             + "    public void methodName(final Marker marker, final String message, final Object... params) {%n"
365             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, marker, message, params);%n"
366             + "    }%n"
367             + "%n"
368             + "    /**%n"
369             + "     * Logs a message with parameters at the {@code CUSTOM_LEVEL} level.%n"
370             + "     * %n"
371             + "     * @param marker the marker data specific to this log statement%n"
372             + "     * @param message the message to log; the format depends on the message factory.%n"
373             + "     * @param p0 parameter to the message.%n"
374             + "     * @see #getMessageFactory()%n"
375             + "     * @since Log4j-2.6%n"
376             + "     */%n"
377             + "    public void methodName(final Marker marker, final String message, final Object p0) {%n"
378             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, marker, message, p0);%n"
379             + "    }%n"
380             + "%n"
381             + "    /**%n"
382             + "     * Logs a message with parameters at the {@code CUSTOM_LEVEL} level.%n"
383             + "     * %n"
384             + "     * @param marker the marker data specific to this log statement%n"
385             + "     * @param message the message to log; the format depends on the message factory.%n"
386             + "     * @param p0 parameter to the message.%n"
387             + "     * @param p1 parameter to the message.%n"
388             + "     * @see #getMessageFactory()%n"
389             + "     * @since Log4j-2.6%n"
390             + "     */%n"
391             + "    public void methodName(final Marker marker, final String message, final Object p0, "
392             + "final Object p1) {%n"
393             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, marker, message, p0, p1);%n"
394             + "    }%n"
395             + "%n"
396             + "    /**%n"
397             + "     * Logs a message with parameters at the {@code CUSTOM_LEVEL} level.%n"
398             + "     * %n"
399             + "     * @param marker the marker data specific to this log statement%n"
400             + "     * @param message the message to log; the format depends on the message factory.%n"
401             + "     * @param p0 parameter to the message.%n"
402             + "     * @param p1 parameter to the message.%n"
403             + "     * @param p2 parameter to the message.%n"
404             + "     * @see #getMessageFactory()%n"
405             + "     * @since Log4j-2.6%n"
406             + "     */%n"
407             + "    public void methodName(final Marker marker, final String message, final Object p0, "
408             + "final Object p1, final Object p2) {%n"
409             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, marker, message, p0, p1, p2);%n"
410             + "    }%n"
411             + "%n"
412             + "    /**%n"
413             + "     * Logs a message with parameters at the {@code CUSTOM_LEVEL} level.%n"
414             + "     * %n"
415             + "     * @param marker the marker data specific to this log statement%n"
416             + "     * @param message the message to log; the format depends on the message factory.%n"
417             + "     * @param p0 parameter to the message.%n"
418             + "     * @param p1 parameter to the message.%n"
419             + "     * @param p2 parameter to the message.%n"
420             + "     * @param p3 parameter to the message.%n"
421             + "     * @see #getMessageFactory()%n"
422             + "     * @since Log4j-2.6%n"
423             + "     */%n"
424             + "    public void methodName(final Marker marker, final String message, final Object p0, "
425             + "final Object p1, final Object p2,%n"
426             + "            final Object p3) {%n"
427             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, marker, message, p0, p1, p2, p3);%n"
428             + "    }%n"
429             + "%n"
430             + "    /**%n"
431             + "     * Logs a message with parameters at the {@code CUSTOM_LEVEL} level.%n"
432             + "     * %n"
433             + "     * @param marker the marker data specific to this log statement%n"
434             + "     * @param message the message to log; the format depends on the message factory.%n"
435             + "     * @param p0 parameter to the message.%n"
436             + "     * @param p1 parameter to the message.%n"
437             + "     * @param p2 parameter to the message.%n"
438             + "     * @param p3 parameter to the message.%n"
439             + "     * @param p4 parameter to the message.%n"
440             + "     * @see #getMessageFactory()%n"
441             + "     * @since Log4j-2.6%n"
442             + "     */%n"
443             + "    public void methodName(final Marker marker, final String message, final Object p0, "
444             + "final Object p1, final Object p2,%n"
445             + "            final Object p3, final Object p4) {%n"
446             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, marker, message, p0, p1, p2, p3, p4);%n"
447             + "    }%n"
448             + "%n"
449             + "    /**%n"
450             + "     * Logs a message with parameters at the {@code CUSTOM_LEVEL} level.%n"
451             + "     * %n"
452             + "     * @param marker the marker data specific to this log statement%n"
453             + "     * @param message the message to log; the format depends on the message factory.%n"
454             + "     * @param p0 parameter to the message.%n"
455             + "     * @param p1 parameter to the message.%n"
456             + "     * @param p2 parameter to the message.%n"
457             + "     * @param p3 parameter to the message.%n"
458             + "     * @param p4 parameter to the message.%n"
459             + "     * @param p5 parameter to the message.%n"
460             + "     * @see #getMessageFactory()%n"
461             + "     * @since Log4j-2.6%n"
462             + "     */%n"
463             + "    public void methodName(final Marker marker, final String message, final Object p0, "
464             + "final Object p1, final Object p2,%n"
465             + "            final Object p3, final Object p4, final Object p5) {%n"
466             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, marker, message, p0, p1, p2, p3, p4, p5);%n"
467             + "    }%n"
468             + "%n"
469             + "    /**%n"
470             + "     * Logs a message with parameters at the {@code CUSTOM_LEVEL} level.%n"
471             + "     * %n"
472             + "     * @param marker the marker data specific to this log statement%n"
473             + "     * @param message the message to log; the format depends on the message factory.%n"
474             + "     * @param p0 parameter to the message.%n"
475             + "     * @param p1 parameter to the message.%n"
476             + "     * @param p2 parameter to the message.%n"
477             + "     * @param p3 parameter to the message.%n"
478             + "     * @param p4 parameter to the message.%n"
479             + "     * @param p5 parameter to the message.%n"
480             + "     * @param p6 parameter to the message.%n"
481             + "     * @see #getMessageFactory()%n"
482             + "     * @since Log4j-2.6%n"
483             + "     */%n"
484             + "    public void methodName(final Marker marker, final String message, final Object p0, "
485             + "final Object p1, final Object p2,%n"
486             + "            final Object p3, final Object p4, final Object p5, final Object p6) {%n"
487             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, marker, message, p0, p1, p2, p3, p4, p5, p6);%n"
488             + "    }%n"
489             + "%n"
490             + "    /**%n"
491             + "     * Logs a message with parameters at the {@code CUSTOM_LEVEL} level.%n"
492             + "     * %n"
493             + "     * @param marker the marker data specific to this log statement%n"
494             + "     * @param message the message to log; the format depends on the message factory.%n"
495             + "     * @param p0 parameter to the message.%n"
496             + "     * @param p1 parameter to the message.%n"
497             + "     * @param p2 parameter to the message.%n"
498             + "     * @param p3 parameter to the message.%n"
499             + "     * @param p4 parameter to the message.%n"
500             + "     * @param p5 parameter to the message.%n"
501             + "     * @param p6 parameter to the message.%n"
502             + "     * @param p7 parameter to the message.%n"
503             + "     * @see #getMessageFactory()%n"
504             + "     * @since Log4j-2.6%n"
505             + "     */%n"
506             + "    public void methodName(final Marker marker, final String message, final Object p0, "
507             + "final Object p1, final Object p2,%n"
508             + "            final Object p3, final Object p4, final Object p5, final Object p6,%n"
509             + "            final Object p7) {%n"
510             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, marker, message, p0, p1, p2, p3, p4, p5, p6, p7);%n"
511             + "    }%n"
512             + "%n"
513             + "    /**%n"
514             + "     * Logs a message with parameters at the {@code CUSTOM_LEVEL} level.%n"
515             + "     * %n"
516             + "     * @param marker the marker data specific to this log statement%n"
517             + "     * @param message the message to log; the format depends on the message factory.%n"
518             + "     * @param p0 parameter to the message.%n"
519             + "     * @param p1 parameter to the message.%n"
520             + "     * @param p2 parameter to the message.%n"
521             + "     * @param p3 parameter to the message.%n"
522             + "     * @param p4 parameter to the message.%n"
523             + "     * @param p5 parameter to the message.%n"
524             + "     * @param p6 parameter to the message.%n"
525             + "     * @param p7 parameter to the message.%n"
526             + "     * @param p8 parameter to the message.%n"
527             + "     * @see #getMessageFactory()%n"
528             + "     * @since Log4j-2.6%n"
529             + "     */%n"
530             + "    public void methodName(final Marker marker, final String message, final Object p0, "
531             + "final Object p1, final Object p2,%n"
532             + "            final Object p3, final Object p4, final Object p5, final Object p6,%n"
533             + "            final Object p7, final Object p8) {%n"
534             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, marker, message, p0, p1, p2, p3, p4, p5, p6, p7, "
535             + "p8);%n"
536             + "    }%n"
537             + "%n"
538             + "    /**%n"
539             + "     * Logs a message with parameters at the {@code CUSTOM_LEVEL} level.%n"
540             + "     * %n"
541             + "     * @param marker the marker data specific to this log statement%n"
542             + "     * @param message the message to log; the format depends on the message factory.%n"
543             + "     * @param p0 parameter to the message.%n"
544             + "     * @param p1 parameter to the message.%n"
545             + "     * @param p2 parameter to the message.%n"
546             + "     * @param p3 parameter to the message.%n"
547             + "     * @param p4 parameter to the message.%n"
548             + "     * @param p5 parameter to the message.%n"
549             + "     * @param p6 parameter to the message.%n"
550             + "     * @param p7 parameter to the message.%n"
551             + "     * @param p8 parameter to the message.%n"
552             + "     * @param p9 parameter to the message.%n"
553             + "     * @see #getMessageFactory()%n"
554             + "     * @since Log4j-2.6%n"
555             + "     */%n"
556             + "    public void methodName(final Marker marker, final String message, final Object p0, "
557             + "final Object p1, final Object p2,%n"
558             + "            final Object p3, final Object p4, final Object p5, final Object p6,%n"
559             + "            final Object p7, final Object p8, final Object p9) {%n"
560             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, marker, message, p0, p1, p2, p3, p4, p5, p6, p7, "
561             + "p8, p9);%n"
562             + "    }%n"
563             + "%n"
564             + "    /**%n"
565             + "     * Logs a message at the {@code CUSTOM_LEVEL} level including the stack trace of%n"
566             + "     * the {@link Throwable} {@code t} passed as parameter.%n"
567             + "     * %n"
568             + "     * @param marker the marker data specific to this log statement%n"
569             + "     * @param message the message to log.%n"
570             + "     * @param t the exception to log, including its stack trace.%n"
571             + "     */%n"
572             + "    public void methodName(final Marker marker, final String message, final Throwable t) {%n"
573             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, marker, message, t);%n"
574             + "    }%n"
575             + "%n"
576             + "    /**%n"
577             + "     * Logs the specified Message at the {@code CUSTOM_LEVEL} level.%n"
578             + "     * %n"
579             + "     * @param msg the message string to be logged%n"
580             + "     */%n"
581             + "    public void methodName(final Message msg) {%n"
582             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, null, msg, (Throwable) null);%n"
583             + "    }%n"
584             + "%n"
585             + "    /**%n"
586             + "     * Logs the specified Message at the {@code CUSTOM_LEVEL} level.%n"
587             + "     * %n"
588             + "     * @param msg the message string to be logged%n"
589             + "     * @param t A Throwable or null.%n"
590             + "     */%n"
591             + "    public void methodName(final Message msg, final Throwable t) {%n"
592             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, null, msg, t);%n"
593             + "    }%n"
594             + "%n"
595             + "    /**%n"
596             + "     * Logs a message object with the {@code CUSTOM_LEVEL} level.%n"
597             + "     * %n"
598             + "     * @param message the message object to log.%n"
599             + "     */%n"
600             + "    public void methodName(final Object message) {%n"
601             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, null, message, (Throwable) null);%n"
602             + "    }%n"
603             + "%n"
604             + "    /**%n"
605             + "     * Logs a message at the {@code CUSTOM_LEVEL} level including the stack trace of%n"
606             + "     * the {@link Throwable} {@code t} passed as parameter.%n"
607             + "     * %n"
608             + "     * @param message the message to log.%n"
609             + "     * @param t the exception to log, including its stack trace.%n"
610             + "     */%n"
611             + "    public void methodName(final Object message, final Throwable t) {%n"
612             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, null, message, t);%n"
613             + "    }%n"
614             + "%n"
615             + "    /**%n"
616             + "     * Logs a message CharSequence with the {@code CUSTOM_LEVEL} level.%n"
617             + "     * %n"
618             + "     * @param message the message CharSequence to log.%n"
619             + "     * @since Log4j-2.6%n"
620             + "     */%n"
621             + "    public void methodName(final CharSequence message) {%n"
622             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, null, message, (Throwable) null);%n"
623             + "    }%n"
624             + "%n"
625             + "    /**%n"
626             + "     * Logs a CharSequence at the {@code CUSTOM_LEVEL} level including the stack trace of%n"
627             + "     * the {@link Throwable} {@code t} passed as parameter.%n"
628             + "     * %n"
629             + "     * @param message the CharSequence to log.%n"
630             + "     * @param t the exception to log, including its stack trace.%n"
631             + "     * @since Log4j-2.6%n"
632             + "     */%n"
633             + "    public void methodName(final CharSequence message, final Throwable t) {%n"
634             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, null, message, t);%n"
635             + "    }%n"
636             + "%n"
637             + "    /**%n"
638             + "     * Logs a message object with the {@code CUSTOM_LEVEL} level.%n"
639             + "     * %n"
640             + "     * @param message the message object to log.%n"
641             + "     */%n"
642             + "    public void methodName(final String message) {%n"
643             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, null, message, (Throwable) null);%n"
644             + "    }%n"
645             + "%n"
646             + "    /**%n"
647             + "     * Logs a message with parameters at the {@code CUSTOM_LEVEL} level.%n"
648             + "     * %n"
649             + "     * @param message the message to log; the format depends on the message factory.%n"
650             + "     * @param params parameters to the message.%n"
651             + "     * @see #getMessageFactory()%n"
652             + "     */%n"
653             + "    public void methodName(final String message, final Object... params) {%n"
654             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, null, message, params);%n"
655             + "    }%n"
656             + "%n"
657             + "    /**%n"
658             + "     * Logs a message with parameters at the {@code CUSTOM_LEVEL} level.%n"
659             + "     * %n"
660             + "     * @param message the message to log; the format depends on the message factory.%n"
661             + "     * @param p0 parameter to the message.%n"
662             + "     * @see #getMessageFactory()%n"
663             + "     * @since Log4j-2.6%n"
664             + "     */%n"
665             + "    public void methodName(final String message, final Object p0) {%n"
666             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, null, message, p0);%n"
667             + "    }%n"
668             + "%n"
669             + "    /**%n"
670             + "     * Logs a message with parameters at the {@code CUSTOM_LEVEL} level.%n"
671             + "     * %n"
672             + "     * @param message the message to log; the format depends on the message factory.%n"
673             + "     * @param p0 parameter to the message.%n"
674             + "     * @param p1 parameter to the message.%n"
675             + "     * @see #getMessageFactory()%n"
676             + "     * @since Log4j-2.6%n"
677             + "     */%n"
678             + "    public void methodName(final String message, final Object p0, "
679             + "final Object p1) {%n"
680             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, null, message, p0, p1);%n"
681             + "    }%n"
682             + "%n"
683             + "    /**%n"
684             + "     * Logs a message with parameters at the {@code CUSTOM_LEVEL} level.%n"
685             + "     * %n"
686             + "     * @param message the message to log; the format depends on the message factory.%n"
687             + "     * @param p0 parameter to the message.%n"
688             + "     * @param p1 parameter to the message.%n"
689             + "     * @param p2 parameter to the message.%n"
690             + "     * @see #getMessageFactory()%n"
691             + "     * @since Log4j-2.6%n"
692             + "     */%n"
693             + "    public void methodName(final String message, final Object p0, "
694             + "final Object p1, final Object p2) {%n"
695             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, null, message, p0, p1, p2);%n"
696             + "    }%n"
697             + "%n"
698             + "    /**%n"
699             + "     * Logs a message with parameters at the {@code CUSTOM_LEVEL} level.%n"
700             + "     * %n"
701             + "     * @param message the message to log; the format depends on the message factory.%n"
702             + "     * @param p0 parameter to the message.%n"
703             + "     * @param p1 parameter to the message.%n"
704             + "     * @param p2 parameter to the message.%n"
705             + "     * @param p3 parameter to the message.%n"
706             + "     * @see #getMessageFactory()%n"
707             + "     * @since Log4j-2.6%n"
708             + "     */%n"
709             + "    public void methodName(final String message, final Object p0, "
710             + "final Object p1, final Object p2,%n"
711             + "            final Object p3) {%n"
712             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, null, message, p0, p1, p2, p3);%n"
713             + "    }%n"
714             + "%n"
715             + "    /**%n"
716             + "     * Logs a message with parameters at the {@code CUSTOM_LEVEL} level.%n"
717             + "     * %n"
718             + "     * @param message the message to log; the format depends on the message factory.%n"
719             + "     * @param p0 parameter to the message.%n"
720             + "     * @param p1 parameter to the message.%n"
721             + "     * @param p2 parameter to the message.%n"
722             + "     * @param p3 parameter to the message.%n"
723             + "     * @param p4 parameter to the message.%n"
724             + "     * @see #getMessageFactory()%n"
725             + "     * @since Log4j-2.6%n"
726             + "     */%n"
727             + "    public void methodName(final String message, final Object p0, "
728             + "final Object p1, final Object p2,%n"
729             + "            final Object p3, final Object p4) {%n"
730             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, null, message, p0, p1, p2, p3, p4);%n"
731             + "    }%n"
732             + "%n"
733             + "    /**%n"
734             + "     * Logs a message with parameters at the {@code CUSTOM_LEVEL} level.%n"
735             + "     * %n"
736             + "     * @param message the message to log; the format depends on the message factory.%n"
737             + "     * @param p0 parameter to the message.%n"
738             + "     * @param p1 parameter to the message.%n"
739             + "     * @param p2 parameter to the message.%n"
740             + "     * @param p3 parameter to the message.%n"
741             + "     * @param p4 parameter to the message.%n"
742             + "     * @param p5 parameter to the message.%n"
743             + "     * @see #getMessageFactory()%n"
744             + "     * @since Log4j-2.6%n"
745             + "     */%n"
746             + "    public void methodName(final String message, final Object p0, "
747             + "final Object p1, final Object p2,%n"
748             + "            final Object p3, final Object p4, final Object p5) {%n"
749             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, null, message, p0, p1, p2, p3, p4, p5);%n"
750             + "    }%n"
751             + "%n"
752             + "    /**%n"
753             + "     * Logs a message with parameters at the {@code CUSTOM_LEVEL} level.%n"
754             + "     * %n"
755             + "     * @param message the message to log; the format depends on the message factory.%n"
756             + "     * @param p0 parameter to the message.%n"
757             + "     * @param p1 parameter to the message.%n"
758             + "     * @param p2 parameter to the message.%n"
759             + "     * @param p3 parameter to the message.%n"
760             + "     * @param p4 parameter to the message.%n"
761             + "     * @param p5 parameter to the message.%n"
762             + "     * @param p6 parameter to the message.%n"
763             + "     * @see #getMessageFactory()%n"
764             + "     * @since Log4j-2.6%n"
765             + "     */%n"
766             + "    public void methodName(final String message, final Object p0, "
767             + "final Object p1, final Object p2,%n"
768             + "            final Object p3, final Object p4, final Object p5, final Object p6) {%n"
769             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, null, message, p0, p1, p2, p3, p4, p5, p6);%n"
770             + "    }%n"
771             + "%n"
772             + "    /**%n"
773             + "     * Logs a message with parameters at the {@code CUSTOM_LEVEL} level.%n"
774             + "     * %n"
775             + "     * @param message the message to log; the format depends on the message factory.%n"
776             + "     * @param p0 parameter to the message.%n"
777             + "     * @param p1 parameter to the message.%n"
778             + "     * @param p2 parameter to the message.%n"
779             + "     * @param p3 parameter to the message.%n"
780             + "     * @param p4 parameter to the message.%n"
781             + "     * @param p5 parameter to the message.%n"
782             + "     * @param p6 parameter to the message.%n"
783             + "     * @param p7 parameter to the message.%n"
784             + "     * @see #getMessageFactory()%n"
785             + "     * @since Log4j-2.6%n"
786             + "     */%n"
787             + "    public void methodName(final String message, final Object p0, "
788             + "final Object p1, final Object p2,%n"
789             + "            final Object p3, final Object p4, final Object p5, final Object p6,%n"
790             + "            final Object p7) {%n"
791             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, null, message, p0, p1, p2, p3, p4, p5, p6, p7);%n"
792             + "    }%n"
793             + "%n"
794             + "    /**%n"
795             + "     * Logs a message with parameters at the {@code CUSTOM_LEVEL} level.%n"
796             + "     * %n"
797             + "     * @param message the message to log; the format depends on the message factory.%n"
798             + "     * @param p0 parameter to the message.%n"
799             + "     * @param p1 parameter to the message.%n"
800             + "     * @param p2 parameter to the message.%n"
801             + "     * @param p3 parameter to the message.%n"
802             + "     * @param p4 parameter to the message.%n"
803             + "     * @param p5 parameter to the message.%n"
804             + "     * @param p6 parameter to the message.%n"
805             + "     * @param p7 parameter to the message.%n"
806             + "     * @param p8 parameter to the message.%n"
807             + "     * @see #getMessageFactory()%n"
808             + "     * @since Log4j-2.6%n"
809             + "     */%n"
810             + "    public void methodName(final String message, final Object p0, "
811             + "final Object p1, final Object p2,%n"
812             + "            final Object p3, final Object p4, final Object p5, final Object p6,%n"
813             + "            final Object p7, final Object p8) {%n"
814             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, null, message, p0, p1, p2, p3, p4, p5, p6, p7, "
815             + "p8);%n"
816             + "    }%n"
817             + "%n"
818             + "    /**%n"
819             + "     * Logs a message with parameters at the {@code CUSTOM_LEVEL} level.%n"
820             + "     * %n"
821             + "     * @param message the message to log; the format depends on the message factory.%n"
822             + "     * @param p0 parameter to the message.%n"
823             + "     * @param p1 parameter to the message.%n"
824             + "     * @param p2 parameter to the message.%n"
825             + "     * @param p3 parameter to the message.%n"
826             + "     * @param p4 parameter to the message.%n"
827             + "     * @param p5 parameter to the message.%n"
828             + "     * @param p6 parameter to the message.%n"
829             + "     * @param p7 parameter to the message.%n"
830             + "     * @param p8 parameter to the message.%n"
831             + "     * @param p9 parameter to the message.%n"
832             + "     * @see #getMessageFactory()%n"
833             + "     * @since Log4j-2.6%n"
834             + "     */%n"
835             + "    public void methodName(final String message, final Object p0, "
836             + "final Object p1, final Object p2,%n"
837             + "            final Object p3, final Object p4, final Object p5, final Object p6,%n"
838             + "            final Object p7, final Object p8, final Object p9) {%n"
839             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, null, message, p0, p1, p2, p3, p4, p5, p6, p7, "
840             + "p8, p9);%n"
841             + "    }%n"
842             + "%n"
843             + "    /**%n"
844             + "     * Logs a message at the {@code CUSTOM_LEVEL} level including the stack trace of%n"
845             + "     * the {@link Throwable} {@code t} passed as parameter.%n"
846             + "     * %n"
847             + "     * @param message the message to log.%n"
848             + "     * @param t the exception to log, including its stack trace.%n"
849             + "     */%n"
850             + "    public void methodName(final String message, final Throwable t) {%n"
851             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, null, message, t);%n"
852             + "    }%n"
853             + "%n"
854             + "    /**%n"
855             + "     * Logs a message which is only to be constructed if the logging level is the {@code CUSTOM_LEVEL}"
856             + "level.%n"
857             + "     *%n"
858             + "     * @param msgSupplier A function, which when called, produces the desired log message;%n"
859             + "     *            the format depends on the message factory.%n"
860             + "     * @since Log4j-2.4%n"
861             + "     */%n"
862             + "    public void methodName(final Supplier<?> msgSupplier) {%n"
863             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, null, msgSupplier, (Throwable) null);%n"
864             + "    }%n"
865             + "%n"
866             + "    /**%n"
867             + "     * Logs a message (only to be constructed if the logging level is the {@code CUSTOM_LEVEL}%n"
868             + "     * level) including the stack trace of the {@link Throwable} <code>t</code> passed as parameter.%n"
869             + "     *%n"
870             + "     * @param msgSupplier A function, which when called, produces the desired log message;%n"
871             + "     *            the format depends on the message factory.%n"
872             + "     * @param t the exception to log, including its stack trace.%n"
873             + "     * @since Log4j-2.4%n"
874             + "     */%n"
875             + "    public void methodName(final Supplier<?> msgSupplier, final Throwable t) {%n"
876             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, null, msgSupplier, t);%n"
877             + "    }%n"
878             + "%n"
879             + "    /**%n"
880             + "     * Logs a message which is only to be constructed if the logging level is the%n"
881             + "     * {@code CUSTOM_LEVEL} level with the specified Marker.%n"
882             + "     *%n"
883             + "     * @param marker the marker data specific to this log statement%n"
884             + "     * @param msgSupplier A function, which when called, produces the desired log message;%n"
885             + "     *            the format depends on the message factory.%n"
886             + "     * @since Log4j-2.4%n"
887             + "     */%n"
888             + "    public void methodName(final Marker marker, final Supplier<?> msgSupplier) {%n"
889             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, marker, msgSupplier, (Throwable) null);%n"
890             + "    }%n"
891             + "%n"
892             + "    /**%n"
893             + "     * Logs a message with parameters which are only to be constructed if the logging level is the%n"
894             + "     * {@code CUSTOM_LEVEL} level.%n"
895             + "     *%n"
896             + "     * @param marker the marker data specific to this log statement%n"
897             + "     * @param message the message to log; the format depends on the message factory.%n"
898             + "     * @param paramSuppliers An array of functions, which when called, produce the desired log"
899             + " message parameters.%n"
900             + "     * @since Log4j-2.4%n"
901             + "     */%n"
902             + "    public void methodName(final Marker marker, final String message, final Supplier<?>..."
903             + " paramSuppliers) {%n"
904             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, marker, message, paramSuppliers);%n"
905             + "    }%n"
906             + "%n"
907             + "    /**%n"
908             + "     * Logs a message (only to be constructed if the logging level is the {@code CUSTOM_LEVEL}%n"
909             + "     * level) with the specified Marker and including the stack trace of the {@link Throwable}%n"
910             + "     * <code>t</code> passed as parameter.%n"
911             + "     *%n"
912             + "     * @param marker the marker data specific to this log statement%n"
913             + "     * @param msgSupplier A function, which when called, produces the desired log message;%n"
914             + "     *            the format depends on the message factory.%n"
915             + "     * @param t A Throwable or null.%n"
916             + "     * @since Log4j-2.4%n"
917             + "     */%n"
918             + "    public void methodName(final Marker marker, final Supplier<?> msgSupplier, final Throwable t) {%n"
919             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, marker, msgSupplier, t);%n"
920             + "    }%n"
921             + "%n"
922             + "    /**%n"
923             + "     * Logs a message with parameters which are only to be constructed if the logging level is%n"
924             + "     * the {@code CUSTOM_LEVEL} level.%n"
925             + "     *%n"
926             + "     * @param message the message to log; the format depends on the message factory.%n"
927             + "     * @param paramSuppliers An array of functions, which when called, produce the desired log"
928             + " message parameters.%n"
929             + "     * @since Log4j-2.4%n"
930             + "     */%n"
931             + "    public void methodName(final String message, final Supplier<?>... paramSuppliers) {%n"
932             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, null, message, paramSuppliers);%n"
933             + "    }%n"
934             + "%n"
935             + "    /**%n"
936             + "     * Logs a message which is only to be constructed if the logging level is the%n"
937             + "     * {@code CUSTOM_LEVEL} level with the specified Marker. The {@code MessageSupplier} may or may%n"
938             + "     * not use the {@link MessageFactory} to construct the {@code Message}.%n"
939             + "     *%n"
940             + "     * @param marker the marker data specific to this log statement%n"
941             + "     * @param msgSupplier A function, which when called, produces the desired log message.%n"
942             + "     * @since Log4j-2.4%n"
943             + "     */%n"
944             + "    public void methodName(final Marker marker, final MessageSupplier msgSupplier) {%n"
945             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, marker, msgSupplier, (Throwable) null);%n"
946             + "    }%n"
947             + "%n"
948             + "    /**%n"
949             + "     * Logs a message (only to be constructed if the logging level is the {@code CUSTOM_LEVEL}%n"
950             + "     * level) with the specified Marker and including the stack trace of the {@link Throwable}%n"
951             + "     * <code>t</code> passed as parameter. The {@code MessageSupplier} may or may not use the%n"
952             + "     * {@link MessageFactory} to construct the {@code Message}.%n"
953             + "     *%n"
954             + "     * @param marker the marker data specific to this log statement%n"
955             + "     * @param msgSupplier A function, which when called, produces the desired log message.%n"
956             + "     * @param t A Throwable or null.%n"
957             + "     * @since Log4j-2.4%n"
958             + "     */%n"
959             + "    public void methodName(final Marker marker, final MessageSupplier msgSupplier, final "
960             + "Throwable t) {%n"
961             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, marker, msgSupplier, t);%n"
962             + "    }%n"
963             + "%n"
964             + "    /**%n"
965             + "     * Logs a message which is only to be constructed if the logging level is the%n"
966             + "     * {@code CUSTOM_LEVEL} level. The {@code MessageSupplier} may or may not use the%n"
967             + "     * {@link MessageFactory} to construct the {@code Message}.%n"
968             + "     *%n"
969             + "     * @param msgSupplier A function, which when called, produces the desired log message.%n"
970             + "     * @since Log4j-2.4%n"
971             + "     */%n"
972             + "    public void methodName(final MessageSupplier msgSupplier) {%n"
973             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, null, msgSupplier, (Throwable) null);%n"
974             + "    }%n"
975             + "%n"
976             + "    /**%n"
977             + "     * Logs a message (only to be constructed if the logging level is the {@code CUSTOM_LEVEL}%n"
978             + "     * level) including the stack trace of the {@link Throwable} <code>t</code> passed as parameter.%n"
979             + "     * The {@code MessageSupplier} may or may not use the {@link MessageFactory} to construct the%n"
980             + "     * {@code Message}.%n"
981             + "     *%n"
982             + "     * @param msgSupplier A function, which when called, produces the desired log message.%n"
983             + "     * @param t the exception to log, including its stack trace.%n"
984             + "     * @since Log4j-2.4%n"
985             + "     */%n"
986             + "    public void methodName(final MessageSupplier msgSupplier, final Throwable t) {%n"
987             + "        logger.logIfEnabled(FQCN, CUSTOM_LEVEL, null, msgSupplier, t);%n"
988             + "    }%n";
989             //@formatter:on
990 
991     private Generate() {
992     }
993 
994     /**
995      * Generates source code for custom logger wrappers that only provide convenience methods for the specified custom
996      * levels, not for the standard built-in levels.
997      */
998     public static final class CustomLogger {
999         /**
1000          * Generates source code for custom logger wrappers that only provide convenience methods for the specified
1001          * custom levels, not for the standard built-in levels.
1002          *
1003          * @param args className of the custom logger to generate, followed by a NAME=intLevel pair for each custom log
1004          *            level to generate convenience methods for
1005          */
1006         public static void main(final String[] args) {
1007             generate(args, Type.CUSTOM);
1008         }
1009 
1010         private CustomLogger() {
1011         }
1012     }
1013 
1014     /**
1015      * Generates source code for extended logger wrappers that provide convenience methods for the specified custom
1016      * levels, and by extending {@code org.apache.logging.log4j.spi.ExtendedLoggerWrapper}, inherit the convenience
1017      * methods for the built-in levels provided by the {@code Logger} interface.
1018      */
1019     public static final class ExtendedLogger {
1020         /**
1021          * Generates source code for extended logger wrappers that provide convenience methods for the specified custom
1022          * levels.
1023          *
1024          * @param args className of the custom logger to generate, followed by a NAME=intLevel pair for each custom log
1025          *            level to generate convenience methods for
1026          */
1027         public static void main(final String[] args) {
1028             generate(args, Type.EXTEND);
1029         }
1030 
1031         private ExtendedLogger() {
1032         }
1033     }
1034 
1035     static class LevelInfo {
1036         final String name;
1037         final int intLevel;
1038 
1039         LevelInfo(final String description) {
1040             final String[] parts = description.split("=");
1041             name = parts[0];
1042             intLevel = Integer.parseInt(parts[1]);
1043         }
1044 
1045         public static List<LevelInfo> parse(final List<String> values, final Class<?> generator) {
1046             final List<LevelInfo> result = new ArrayList<>(values.size());
1047             for (int i = 0; i < values.size(); i++) {
1048                 try {
1049                     result.add(new LevelInfo(values.get(i)));
1050                 } catch (final Exception ex) {
1051                     System.err.println("Cannot parse custom level '" + values.get(i) + "': " + ex.toString());
1052                     usage(System.err, generator);
1053                     System.exit(-1);
1054                 }
1055             }
1056             return result;
1057         }
1058     }
1059 
1060     private static void generate(final String[] args, final Type type) {
1061         generate(args, type, System.out);
1062     }
1063 
1064     static void generate(final String[] args, final Type type, final PrintStream printStream) {
1065         if (!validate(args)) {
1066             usage(printStream, type.generator());
1067             System.exit(-1);
1068         }
1069         final List<String> values = new ArrayList<>(Arrays.asList(args));
1070         final String classFQN = values.remove(0);
1071         final List<LevelInfo> levels = LevelInfo.parse(values, type.generator());
1072         printStream.println(generateSource(classFQN, levels, type));
1073     }
1074 
1075     static boolean validate(final String[] args) {
1076         if (args.length < 2) {
1077             return false;
1078         }
1079         return true;
1080     }
1081 
1082     private static void usage(final PrintStream out, final Class<?> generator) {
1083         out.println("Usage: java " + generator.getName() + " className LEVEL1=intLevel1 [LEVEL2=intLevel2...]");
1084         out.println("       Where className is the fully qualified class name of the custom/extended logger");
1085         out.println("       to generate, followed by a space-separated list of custom log levels.");
1086         out.println("       For each custom log level, specify NAME=intLevel (without spaces).");
1087     }
1088 
1089     static String generateSource(final String classNameFQN, final List<LevelInfo> levels, final Type type) {
1090         final StringBuilder sb = new StringBuilder(10000 * levels.size());
1091         final int lastDot = classNameFQN.lastIndexOf('.');
1092         final String pkg = classNameFQN.substring(0, lastDot >= 0 ? lastDot : 0);
1093         if (!pkg.isEmpty()) {
1094             sb.append(String.format(PACKAGE_DECLARATION, pkg));
1095         }
1096         sb.append(String.format(type.imports(), ""));
1097         final String className = classNameFQN.substring(classNameFQN.lastIndexOf('.') + 1);
1098         final String javadocDescr = javadocDescription(levels);
1099         sb.append(String.format(type.declaration(), javadocDescr, className));
1100         sb.append(String.format(FQCN_FIELD, className));
1101         for (final LevelInfo level : levels) {
1102             sb.append(String.format(LEVEL_FIELD, level.name, level.name, level.intLevel));
1103         }
1104         sb.append(String.format(type.constructor(), className));
1105         sb.append(String.format(FACTORY_METHODS.replaceAll("CLASSNAME", className), ""));
1106         for (final LevelInfo level : levels) {
1107             final String methodName = camelCase(level.name);
1108             final String phase1 = METHODS.replaceAll("CUSTOM_LEVEL", level.name);
1109             final String phase2 = phase1.replaceAll("methodName", methodName);
1110             sb.append(String.format(phase2, ""));
1111         }
1112 
1113         sb.append('}');
1114         sb.append(System.getProperty("line.separator"));
1115         return sb.toString();
1116     }
1117 
1118     static String javadocDescription(final List<LevelInfo> levels) {
1119         if (levels.size() == 1) {
1120             return "the " + levels.get(0).name + " custom log level.";
1121         }
1122         final StringBuilder sb = new StringBuilder(512);
1123         sb.append("the ");
1124         String sep = "";
1125         for (int i = 0; i < levels.size(); i++) {
1126             sb.append(sep);
1127             sb.append(levels.get(i).name);
1128             sep = (i == levels.size() - 2) ? " and " : ", ";
1129         }
1130         sb.append(" custom log levels.");
1131         return sb.toString();
1132     }
1133 
1134     static String camelCase(final String customLevel) {
1135         final StringBuilder sb = new StringBuilder(customLevel.length());
1136         boolean lower = true;
1137         for (final char ch : customLevel.toCharArray()) {
1138             if (ch == '_') {
1139                 lower = false;
1140                 continue;
1141             }
1142             sb.append(lower ? Character.toLowerCase(ch) : Character.toUpperCase(ch));
1143             lower = true;
1144         }
1145         return sb.toString();
1146     }
1147 }