Пользовательский сценарий ролловера Log4j для удаления журналов, когда использование файловой системы достигло определенного процента

Я использую log4j для входа в свое приложение. Я хочу удалить сжатые файлы в зависимости от использования файловой системы. Итак, как только файловая система заполнится на 80 процентов, она должна начать удаление старых сжатых файлов. В Log4j нет приложения, которое могло бы сделать это из коробки, но у него есть ScriptCondition, которое можно использовать. В документации log4j я нашел только скрипт groovy (в наших системах groovy не установлен). Также упоминается, что javascript, nashorn также будет работать. Я написал следующий сценарий, чтобы посмотреть, работает он или нет.

<configuration status="trace" name="REST Servlet Logging Configuration">
        <Properties>
                <Property name="xx">xx</Property>
        </Properties>
        <appenders>
                <RollingFile name="xx"
                        fileName="xx"
                        filePattern="xx.log.%i.gz" append="true"
                        bufferedIO="true" immediateFlush="false" fileOwner="xx"
                        fileGroup="xx" filePermissions="rw-r-----">
                        <Policies>
                                <SizeBasedTriggeringPolicy size="4 MB" />
                        </Policies>
                        <DefaultRolloverStrategy max="100" fileIndex="min">
                        <Delete basePath="${xx}" maxDepth="1">
                        <ScriptCondition>
                        <Script name="superstitious" language="javascript"><![CDATA[
                             var  exec  = require('child_process');
                                exec("df -h / | tail -1 | tr -s ' ' | cut -d' ' -f4", (error, stdout, stderr) => {
                                        if(error) {
                                                 console.log('error: ${error.message}');
                                                 return;
                                         }
                                        if(stderr) {
                                                console.log('stderr: ${stderr}');
                                                return;
                                        }
                                         console.log('stdout: ${stdout}');
                                        statusLogger.trace("stdout in trace :${stdout}");
                                });
                            statusLogger.trace("running javascript");
                            result;
                        ]]>
                        </Script>
                    </ScriptCondition>
                </Delete>
            </DefaultRolloverStrategy>
        </RollingFile>

В журналах я мог видеть, что упоминается javascript, но по ошибке я получаю исключение nashorn.

05:58:46 UTC 2021 DEBUG createScript(name="superstitious", language="javascript", scriptText="var  exec  = require('child_process');
2021-11-02T05:58:47.197Z exec("df -h / | tail -1 | tr -s ' ' | cut -d' ' -f4", (error, stdout, stderr) => {
2021-11-02T05:58:47.197Z if(error) {
2021-11-02T05:58:47.197Z console.log('error: ${error.message}');
2021-11-02T05:58:47.197Z return;
2021-11-02T05:58:47.197Z }
2021-11-02T05:58:47.197Z if(stderr) {
2021-11-02T05:58:47.197Z console.log('stderr: ${stderr}');
2021-11-02T05:58:47.197Z return;
2021-11-02T05:58:47.197Z }
2021-11-02T05:58:47.197Z console.log('stdout: ${stdout}');
2021-11-02T05:58:47.197Z statusLogger.trace("stdout in trace :${stdout}");
2021-11-02T05:58:47.197Z });

Но я получаю следующее исключение

2021-11-02T06:00:41.581Z 2021-02-11 06:00:41,575 Log4j2-TF-1-RollingFileManager-1 ERROR Error running script superstitious javax.script.ScriptException: <eval>:3:11 Expected : but found (
2021-11-02T06:00:41.581Z if(error) {
2021-11-02T06:00:41.582Z ^ in <eval> at line number 3 at column number 11
2021-11-02T06:00:41.582Z at jdk.nashorn.api.scripting.NashornScriptEngine.throwAsScriptException(NashornScriptEngine.java:482)
2021-11-02T06:00:41.582Z at jdk.nashorn.api.scripting.NashornScriptEngine.compileImpl(NashornScriptEngine.java:549)
2021-11-02T06:00:41.582Z at jdk.nashorn.api.scripting.NashornScriptEngine.compileImpl(NashornScriptEngine.java:536)
2021-11-02T06:00:41.582Z at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:414)
2021-11-02T06:00:41.590Z at jdk.nashorn.api.scripting.NashornScriptEngine.eval(NashornScriptEngine.java:167)
2021-11-02T06:00:41.590Z at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:244)
2021-11-02T06:00:41.590Z at org.apache.logging.log4j.core.script.ScriptManager$MainScriptRunner.execute(ScriptManager.java:239)
2021-11-02T06:00:41.590Z at org.apache.logging.log4j.core.script.ScriptManager$ThreadLocalScriptRunner.execute(ScriptManager.java:269)
2021-11-02T06:00:41.590Z at org.apache.logging.log4j.core.script.ScriptManager$1.run(ScriptManager.java:177)
2021-11-02T06:00:41.590Z at java.security.AccessController.doPrivileged(AccessController.java:678)
2021-11-02T06:00:41.590Z at org.apache.logging.log4j.core.script.ScriptManager.execute(ScriptManager.java:174)
2021-11-02T06:00:41.590Z at org.apache.logging.log4j.core.appender.rolling.action.ScriptCondition.selectFilesToDelete(ScriptCondition.java:81)
2021-11-02T06:00:41.590Z at org.apache.logging.log4j.core.appender.rolling.action.DeleteAction.callScript(DeleteAction.java:98)
2021-11-02T06:00:41.590Z at org.apache.logging.log4j.core.appender.rolling.action.DeleteAction.executeScript(DeleteAction.java:86)
2021-11-02T06:00:41.590Z at org.apache.logging.log4j.core.appender.rolling.action.DeleteAction.execute(DeleteAction.java:82)
2021-11-02T06:00:41.590Z at org.apache.logging.log4j.core.appender.rolling.action.CompositeAction.execute(CompositeAction.java:74)
2021-11-02T06:00:41.590Z at org.apache.logging.log4j.core.appender.rolling.RollingFileManager$AsyncAction.execute(RollingFileManager.java:486)
2021-11-02T06:00:41.590Z at org.apache.logging.log4j.core.appender.rolling.action.AbstractAction.run(AbstractAction.java:66)
2021-11-02T06:00:41.590Z at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1160)
2021-11-02T06:00:41.590Z at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
2021-11-02T06:00:41.590Z at java.lang.Thread.run(Thread.java:822)
2021-11-02T06:00:41.590Z Caused by: jdk.nashorn.internal.runtime.ParserException: <eval>:3:11 Expected : but found (
2021-11-02T06:00:41.590Z if(error) {
2021-11-02T06:00:41.590Z ^
2021-11-02T06:00:41.590Z at jdk.nashorn.internal.parser.AbstractParser.error(AbstractParser.java:306)
2021-11-02T06:00:41.590Z at jdk.nashorn.internal.parser.AbstractParser.error(AbstractParser.java:291)
2021-11-02T06:00:41.590Z at jdk.nashorn.internal.parser.AbstractParser.expectDontAdvance(AbstractParser.java:362)
2021-11-02T06:00:41.590Z at jdk.nashorn.internal.parser.AbstractParser.expect(AbstractParser.java:349)
2021-11-02T06:00:41.590Z at jdk.nashorn.internal.parser.Parser.propertyAssignment(Parser.java:2309)
2021-11-02T06:00:41.590Z at jdk.nashorn.internal.parser.Parser.objectLiteral(Parser.java:2167)

Я не уверен, почему он пытается скомпилировать его как сценарий nashorn, когда я четко упомянул javascript. Я новичок в написании сценариев, поэтому не уверен, что здесь не так.

В соответствии с предложением я изменил = ›на функцию, и я получаю еще одно исключение.

2021-12-02T06:56:30.192Z 2021-02-12 06:56:30,185 Log4j2-TF-1-RollingFileManager-2 ERROR Error running script superstitious javax.script.ScriptException: ReferenceError: "require" is not defined in <eval> at line number 1
2021-12-02T06:56:30.192Z at jdk.nashorn.api.scripting.NashornScriptEngine.throwAsScriptException(NashornScriptEngine.java:482)
2021-12-02T06:56:30.192Z at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:438)
2021-12-02T06:56:30.192Z at jdk.nashorn.api.scripting.NashornScriptEngine.access$300(NashornScriptEngine.java:85)
2021-12-02T06:56:30.192Z at jdk.nashorn.api.scripting.NashornScriptEngine$3.eval(NashornScriptEngine.java:526)
2021-12-02T06:56:30.192Z at javax.script.CompiledScript.eval(CompiledScript.java:103)
2021-12-02T06:56:30.192Z at org.apache.logging.log4j.core.script.ScriptManager$MainScriptRunner.execute(ScriptManager.java:232)
2021-12-02T06:56:30.192Z at org.apache.logging.log4j.core.script.ScriptManager$ThreadLocalScriptRunner.execute(ScriptManager.java:269)
2021-12-02T06:56:30.192Z at org.apache.logging.log4j.core.script.ScriptManager$1.run(ScriptManager.java:177)
2021-12-02T06:56:30.192Z at java.security.AccessController.doPrivileged(AccessController.java:678)
2021-12-02T06:56:30.192Z at org.apache.logging.log4j.core.script.ScriptManager.execute(ScriptManager.java:174)
2021-12-02T06:56:30.192Z at org.apache.logging.log4j.core.appender.rolling.action.ScriptCondition.selectFilesToDelete(ScriptCondition.java:81)
2021-12-02T06:56:30.192Z at org.apache.logging.log4j.core.appender.rolling.action.DeleteAction.callScript(DeleteAction.java:98)
2021-12-02T06:56:30.192Z at org.apache.logging.log4j.core.appender.rolling.action.DeleteAction.executeScript(DeleteAction.java:86)
2021-12-02T06:56:30.192Z at org.apache.logging.log4j.core.appender.rolling.action.DeleteAction.execute(DeleteAction.java:82)
2021-12-02T06:56:30.192Z at org.apache.logging.log4j.core.appender.rolling.action.CompositeAction.execute(CompositeAction.java:74)
2021-12-02T06:56:30.192Z at org.apache.logging.log4j.core.appender.rolling.RollingFileManager$AsyncAction.execute(RollingFileManager.java:486)
2021-12-02T06:56:30.192Z at org.apache.logging.log4j.core.appender.rolling.action.AbstractAction.run(AbstractAction.java:66)
2021-12-02T06:56:30.192Z at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1160)
2021-12-02T06:56:30.192Z at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
2021-12-02T06:56:30.192Z at java.lang.Thread.run(Thread.java:822)
2021-12-02T06:56:30.192Z Caused by: <eval>:1 ReferenceError: "require" is not defined
2021-12-02T06:56:30.192Z at jdk.nashorn.internal.runtime.ECMAErrors.error(ECMAErrors.java:69)
2021-12-02T06:56:30.192Z at jdk.nashorn.internal.runtime.ECMAErrors.referenceError(ECMAErrors.java:331)
2021-12-02T06:56:30.192Z at jdk.nashorn.internal.runtime.ECMAErrors.referenceError(ECMAErrors.java:303)
2021-12-02T06:56:30.192Z at jdk.nashorn.internal.objects.Global.__noSuchProperty__(Global.java:1454)
2021-12-02T06:56:30.192Z at java.lang.invoke.DirectHandle.invokeExact_thunkArchetype_L(DirectHandle.java:302)
2021-12-02T06:56:30.192Z at java.lang.invoke.AsTypeHandle.invokeExact_thunkArchetype_X(AsTypeHandle.java:49)
2021-12-02T06:56:30.192Z at java.lang.invoke.BruteArgumentMoverHandle.invokeExact_thunkArchetype_X(BruteArgumentMoverHandle.java:404)
2021-12-02T06:56:30.192Z at jdk.nashorn.internal.scripts.Script$1$^eval_.:program(<eval>:1)
2021-12-02T06:56:30.192Z at java.lang.invoke.DirectHandle.invokeExact_thunkArchetype_L(DirectHandle.java:302)
2021-12-02T06:56:30.192Z at jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:649)
2021-12-02T06:56:30.192Z at jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:506)
2021-12-02T06:56:30.192Z at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:405)
2021-12-02T06:56:30.192Z at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:433)

person yogesh    schedule 11.02.2021    source источник


Ответы (1)


Я думаю, это связано с тем, что вы пытаетесь использовать стрелочные функции, которые являются конструкцией ECMAScript 6, а Нэшорн по умолчанию использует ECMAScript 5.1.

Вы можете попробовать использовать function (error, stdout, stderr) { … } вместо (error, stdout, stderr) => { … }, я считаю, что это сработает.

TL;DR:

Nashorn поддерживает приличное подмножество ES6, но его необходимо включить с помощью флага, который обычно не поддерживается встраиванием, поскольку вам нужно выйти за пределы javax.script API и использовать собственный API Nashorn, NashornScriptEngineFactory.getScriptEngine(String...), где вы можете передать ему эти флаги, так что это ' буду

ScriptEngine engine = NashornScriptEngineFactory.getScriptEngine("--language=es6");
...

FWIW, для нас было бы разумно предоставить движок по умолчанию для ES6, если вы запросили язык как ecmascript-6 или аналогичный. Я подумаю об этом.

person Attila Szegedi    schedule 11.02.2021
comment
После того, как я изменил = ›на функции, я получаю еще одно исключение, которое я обновил в своем исходном вопросе. - person yogesh; 12.02.2021
comment
Я не думаю, что это особенно хорошая идея редактировать исходный вопрос, потому что тогда это сбивает с толку людей, которые позже натыкаются на страницу. Что касается вашей новой проблемы, Nashorn - это чистая реализация ECMAScript, она не поставляется со встроенной реализацией модульной системы CommonJS, кому-то придется построить ее поверх нее. Для сравнения, Nashorn похож на простой двигатель V8. Это, например, Node.js берет V8 и строит на его основе другие функции, например требовать. Но ни в Nashorn, ни в V8 он не встроен. - person Attila Szegedi; 13.02.2021
comment
Конечно, я не буду редактировать вопрос. Теперь я понимаю, что Nashorn не поддерживает модули commonJS. Моя проблема в том, почему log4j пытается запустить скрипт как Nashorn и JavaScript, когда на языке я упоминал JavaScript. - person yogesh; 14.02.2021