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 }