java - AWS Lambda (Java) 调用错误的 Object 实例
问题描述
我对 AWS Lambda 调用有一个不寻常的问题,在搜索时没有找到太多关于这个的问题。我希望这里有人对 Java 垃圾收集器和/或 AWS lambda 容器有更深入的了解。
我创建了一个自定义 PrintStream 来捕获来自 System.out 和 System.err 的打印输出。目的是通过记录器记录这些打印输出,以便为消息添加一些更有用的信息。
CustomPrintStream.write 在第一次调用之后的每次调用时触发,它仍然使用第一次调用的对象。这意味着当我使用变量 timeWhenFunctionStarted 时,它包含第一次调用的值,并且经过的时间不正确。
我添加了对象哈希码的打印输出以更好地说明这个问题。
这是日志
在第一次调用(冷启动)期间,一切都如预期的那样,一致的 ms 和相同的哈希码:
START RequestId: {requestid1} Version: $LATEST
2019-01-09 12:37:09.175 [INFO] {requestid1} START (1 ms) hashcode: 601008104 //other stuff
2019-01-09 12:37:09.193 [DEBUG] {requestid1} (18 ms) hashcode: 601008104 //other stuff
2019-01-09 12:37:09.213 [INFO] {requestid1} (38 ms) hashcode: 601008104 //other stuff
2019-01-09 12:37:13.813 [TRACE] {requestid1} (4638 ms) hashcode: 601008104 //other stuff
2019-01-09 12:37:16.143 [INFO] {requestid1} (6968 ms) hashcode: 601008104 //other stuff
2019-01-09 12:37:16.143 [INFO] {requestid1} END (6968 ms) hashcode: 601008104 //other stuff
END RequestId: {requestid1}
REPORT RequestId: {requestid1} Duration: 7207.15 ms Billed Duration: 7300 ms Memory Size: 512 MB Max Memory Used: 113 MB
当在同一个容器中再次调用 lambda 函数时会出现此问题,请参阅 hashcode、requestid 和 ms 以了解跟踪日志记录事件:
START RequestId: {requestid2} Version: $LATEST
2019-01-09 12:37:29.717 [INFO] {requestid2} START (0 ms) hashcode: 2117173674 //other stuff
2019-01-09 12:37:29.717 [DEBUG] {requestid2} (1 ms) hashcode: 2117173674 //other stuff
2019-01-09 12:37:29.718 [INFO] {requestid2} (1 ms) hashcode: 2117173674 //other stuff
2019-01-09 12:37:29.815 [TRACE] {requestid1} (20640 ms) hashcode: 601008104 //other stuff
2019-01-09 12:37:30.075 [INFO] {requestid2} (358 ms) hashcode: 2117173674 //other stuff
2019-01-09 12:37:30.075 [INFO] {requestid2} END (358 ms) hashcode: 2117173674 //other stuff
END RequestId: {requestid2}
REPORT RequestId: {requestid2} Duration: 358.78 ms Billed Duration: 400 ms Memory Size: 512 MB Max Memory Used: 116 MB
日志类:
public class CustomLogger {
//Constructor setting System out to object of class customPrintStream
public CustomLogger(...) {
//other stuff
this.logger = context.getLogger();
this.baosSystemOut = new ByteArrayOutputStream();
this.customPrintStreamObject= new customPrintStream(baosSystemOut);
System.setOut(customPrintStreamObject);
}
//Every logged message goes through here.
private void logMessages(String[] messages, String logLevel) {
//other stuff
String formatedMessage = ... System.currentTimeMillis() - timeWhenFunctionStarted ... System.hashcode(this) ...;
LOGGER.log(formatedMessage);
}
//called from CustomPrintStream class and from Lambda function handler, same for TRACE, DEBUG, INFO, WARN and ERROR.
public class logTRACE(String... messages){
//other stuff
logMessages(messages, "TRACE");
}
//private class to catch logging
private class CustomPrintStream extends PrintStream {
//other stuff
@Override
public void write(byte[] buf, int off, int len) {
//other stuff
logTRACE(message);
}
}
}
CustomLogger 从不存在问题的 Lambda 函数处理程序调用:
//other stuff
CustomLogger logger = new CustomLogger(...);
logger.logINFO(...);
当从 CustomPrintStream 类调用日志记录时会出现问题,我尝试在程序完成后将 CustomPrintStream 和记录器设置为 null 并从超类手动调用 finalize 方法,但这并没有改变任何东西。
我想要发生的是打印输出使用记录器对象中的 CustomPrintStream 进行当前调用。
我很感激答案。
解决方案
至少解决了这个问题。将 CustomPrintStream 移出 CustomLogger 类。
推荐阅读
- angular - Angular 2 Ace 管理主题没有按预期工作?
- vuejs2 - admob 与 nativescript-vue 集成
- highcharts - 刻度位置在高图子弹图中不起作用
- angular - 需要取消订阅 Firestore/Angularfire2 订阅
- python - 生成一个列表 a(n) 的形式不是 prime + a(k), k < n
- assembly - GAS 语法中具有三个操作数的 AVX
- javascript - 在元素加载之前更改 CSS
- php - 我想在 ci 的表上打印以下数据
- c++ - 如何使用按位运算将随机 uint64_t 转换为范围 (0, 1) 内的随机双精度
- django - Django过滤器返回空白查询集