AWS Lambda (Java) вызывает неправильный экземпляр объекта - PullRequest
0 голосов
/ 09 января 2019

У меня необычная проблема с вызовами AWS Lambda, не нашел много об этом при поиске. Я надеюсь, что у кого-то здесь есть более глубокое понимание Java-сборщика мусора и / или лямбда-контейнеров AWS.

Я создал собственный PrintStream для перехвата распечаток из System.out и System.err. Цель состоит в том, чтобы зарегистрировать эти распечатки через регистратор, чтобы добавить полезную информацию в сообщения.

CustomPrintStream.write запускается при каждом вызове после первого вызова, который все еще использует объект из первого вызова. Это означает, что когда я использовал переменную timeWhenFunctionStarted, он содержит значение из первого вызова, а истекшее время неверно.

Я добавил распечатку хеш-кода объектов, чтобы лучше проиллюстрировать эту проблему.

Вот журналы

Во время первого вызова (холодный запуск) все, как и ожидалось, соответствует мс и тот же хэш-код:

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

Проблема возникает, когда лямбда-функция снова вызывается в том же контейнере, см. Hashcode, requesttid и 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 вызывается из обработчика лямбда-функции, где проблемы нет:

//other stuff
CustomLogger logger = new CustomLogger(...);
logger.logINFO(...);

Проблема возникает, когда ведение журнала вызывается из класса CustomPrintStream. Я попытался установить для CustomPrintStream и регистратора значение null после завершения программы и вручную вызвать метод finalize из суперкласса, но это ничего не меняет.

Я хочу, чтобы распечатки использовали CustomPrintStream в объекте регистратора для текущего вызова.

Я благодарен за ответы.

Ответы [ 2 ]

0 голосов
/ 09 января 2019

Решил вопрос, вроде как минимум. Перемещено CustomPrintStream из класса CustomLogger.

0 голосов
/ 09 января 2019

Похоже, вы создаете CustomPrintStream в static контексте. Благодаря тому, что повторное использование контейнера работает в AWS Lambda, ваши статически определенные объекты будут сохраняться при каждом вызове.

...