Description
CsvParameterLayout.toSerializable passes Message.getParameters() to CSVFormat.printRecord with no null check. It is null for SimpleMessage, so every plain logger.info("some text") throws.
Only IOException is caught, so the NPE escapes to the appender: one error per event, no output, JVM exits 0. Parameterised calls work, so it survives testing and appears in production.
final Object[] parameters = message.getParameters(); // null for SimpleMessage
try {
getFormat().printRecord(buffer, parameters); // NPE
} catch (final IOException e) { // IOException only
Present on both lines:
- 2.x
04c93c1d33 — log4j-core/.../core/layout/CsvParameterLayout.java:98
- 3.x
main — log4j-csv/.../csv/layout/CsvParameterLayout.java:104
Reproduced on 2.26.1, JDK 21.
Logs
ERROR An exception occurred processing Appender CsvParams
java.lang.NullPointerException: Cannot read the array length because "values" is null
at org.apache.commons.csv.CSVFormat.printRecord(CSVFormat.java:2265)
at CsvParameterLayout.toSerializable(CsvParameterLayout.java:98)
Reproduction
<File name="Csv" fileName="params.csv"><CsvParameterLayout format="Default"/></File>
logger.info("order {} accepted", 4711); // fine
logger.info("plain text"); // NPE, file gains nothing
Suggested fix
getFormat().printRecord(buffer, parameters == null ? EMPTY : parameters);
An empty row is well-formed and matches the present-but-zero-length case. Widening the catch would stop the throw but leave the column count wrong, which is worse for a machine-read format.
Description
CsvParameterLayout.toSerializablepassesMessage.getParameters()toCSVFormat.printRecordwith no null check. It isnullforSimpleMessage, so every plainlogger.info("some text")throws.Only
IOExceptionis caught, so the NPE escapes to the appender: one error per event, no output, JVM exits 0. Parameterised calls work, so it survives testing and appears in production.Present on both lines:
04c93c1d33—log4j-core/.../core/layout/CsvParameterLayout.java:98main—log4j-csv/.../csv/layout/CsvParameterLayout.java:104Reproduced on 2.26.1, JDK 21.
Logs
Reproduction
Suggested fix
An empty row is well-formed and matches the present-but-zero-length case. Widening the
catchwould stop the throw but leave the column count wrong, which is worse for a machine-read format.