javascript - 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)
当我明确提到 javascript 时,我不确定为什么它试图将其编译为 nashorn 脚本。我是脚本新手,所以不确定这里出了什么问题。
根据我的建议,我将 => 更改为功能,我遇到了另一个异常
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)
解决方案
我认为这是因为您正在尝试使用箭头函数,它是 ECMAScript 6 构造,而 Nashorn 默认为 ECMAScript 5.1。
您可以尝试使用,function (error, stdout, stderr) { … }
而不是(error, stdout, stderr) => { … }
,我相信会奏效。
TL;博士:
Nashorn 确实支持 ES6 的一个不错的子集,但需要使用嵌入通常不支持的标志来启用它,因为您需要超出javax.script
API 并使用 Nashorn 自己的 API, NashornScriptEngineFactory.getScriptEngine(String...)
您可以在其中传递这些标志,所以它会是
ScriptEngine engine = NashornScriptEngineFactory.getScriptEngine("--language=es6");
...
FWIW,如果您要求语言为“ecmascript-6”或类似语言,我们提供一个 ES6 默认引擎是有意义的。我会考虑的。
推荐阅读
- javascript - 如果以下条件不匹配并且我的表单不应该提交,如何设置条件
- android - Skype 如何处理后台执行限制?
- docker - 无法访问主机外部的 docker kibana
- python-2.7 - 是否可以一次从 RabbitMQ 队列中提取所有消息?
- android - 计时器计时器不会停止
- sql - 是否可以在审计表中有单独的列来存储列名以反映所做的更改
- java - 可选的通用参数或对抗类型错误的方法
- sql-server - mvc,两个项目连接到一个数据库,用项目-A更新表它在项目-B中不起作用
- airflow - MySqlToGoogleCloudStorageOperator 意外失败
- azure-cosmosdb - 是否可以使用 Azure cosmos mongodb API 创建多个“唯一且稀疏”的索引