JDBCAppender tableName из Главного поиска аргументов - PullRequest
0 голосов
/ 10 января 2020

В моем приложении есть JDBCAppender, для которого я хотел бы установить параметр tableName из поиска основного аргумента . Причиной этого является то, что моя таблица базы данных может иметь префикс, поэтому я читаю это из файла конфигурации в моем приложении и хочу применить его к appender во время выполнения.

    <JDBC name="TaskLogJDBC" tableName="${main:1}LogEvents">
        <ConnectionFactory class="my.package.name.ConnectionFactory" method="getConnection"/>
        <Column name="created_on" isEventTimestamp="true"/>
        <Column name="lvl" pattern="%level"/>
        <Column name="logger" pattern="%logger"/>
        <Column name="message" pattern="%message"/>
        <Column name="throwable" pattern="%ex{full}"/>
    </JDBC>

Это то, что я использую в Main. java для определения аргументов:

MainMapLookup.setMainArguments(new String[] { "--prefix", tablesPrefix });

К сожалению, это не похоже на работу. JDBCAppender продолжает читать значение параметра tableName дословно как $ {main: 0} LogEvents вместо prefix_LogEvents . Я проследил это и думаю, что чтение конфигурации JDBCAppender происходит до вызова MainMapLookup.setMainArguments () . Это ошибка?

Опция поиска переменной среды - вариант, но я бы хотел этого избежать. Есть ли другие варианты?

Ответы [ 3 ]

0 голосов
/ 13 января 2020

Начиная с версии 2.13.0, вы ДОЛЖНЫ вызывать Log4j MainMapLookup.setMainArguments() из метода main() вашего приложения или из любого доступного массива из вашего приложения.

0 голосов
/ 21 января 2020

РЕДАКТИРОВАТЬ: После нескольких проб и ошибок я обнаружил, что проблема заключается в объявлении Logger в самом классе Main.

private static final Logger logger = LogManager.getLogger(Main.class.getName());

Это загружает log4j2. xml, включая все параметры приложения JDB C, до вызова MainMapLookup.setMainArguments(). Удаление logger сверху позволяет установить основные аргументы.


Ничего из того, что я пробовал, не сработало, потому что кажется, что мой файл log4j2. xml загружается до того, как main() моего приложения получает называется. Итак, я закончил взломом класса log4j2 JdbcDatabaseManager с помощью отражения. Это заменяет имя таблицы непосредственно в операторе SQL.

    final var jdbcAppender = (JdbcAppender) loggerContext.getConfiguration().getAppender("AppenderName");
    final var jdbcManager = jdbcAppender.getManager();
    var field = jdbcManager.getClass().getDeclaredField("sqlStatement");
    field.setAccessible(true);
    String value = (String) field.get(jdbcManager);
    value = value.replace("__DUMMY_TABLE__", prefix + "TaskLog");
    field.set(jdbcManager, value);

Имя таблицы определяется так же в файле log4j2. xml:

    <JDBC name="AppenderName" tableName="__DUMMY_TABLE__">

It похоже, сработало. Надеюсь, что это полезно для других.

0 голосов
/ 10 января 2020

Попробуйте:

static{
    MainMapLookup.setMainArguments(new String[] { "--prefix", tablesPrefix });
}
...