1. Java / Говнокод #13481

    +69

    1. 1
    2. 2
    3. 3
    4. 4
    5. 5
    6. 6
    7. 7
    SOAPMessage msg = ctx.getMessage();
    
    //msg.writeTo(System.out);
    
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    msg.writeTo(baos);
    logger.trace(baos);

    где у хвалёного log4j метод для передачи его как аргументом java.io.OutputStream???

    Запостил: defecate-plusplus, 26 Июля 2013

    Комментарии (26) RSS

    • Хвалёный log4j - седая древность, переходите на slf4j + logback или log4j2.

      И я не понимаю вопроса. Что значит "для передачи его как аргументом java.io.OutputStream"? Парсер сломался.
      Ответить
      • именно log4j2 и используется

        http://docs.oracle.com/javaee/1.4/api/javax/xml/soap/SOAPMessage.html#writeTo(java.io.OutputStream)

        хочу, например msg.writeTo(logger.foobar(TRACE));
        Ответить
        • Народ везде советует запилить обертку реализующую интерфейс OutputStream или Writer, в зависимости от того байты или строки нам нужно вываливать в лог ;( Заодно там можно будет преобразовать байты в нужный формат - заэскейпить или записать в хексе.

          Еще пишут, что где-то в дистрибе log4j в папке contrib есть пример того, как это сделать.

          Ничего более изкоробочного не нашлось.

          P.S. А msg.toString() и запись результата в лог не катят?
          Ответить
          • жаба тем хороша, что я уже сделал за 5 минут и не буду ничего переделывать
            конечный результат - в ОП
            Ответить
          • >арод везде советует запилить обертку реализующую интерфейс OutputStream или Writer
            TOOWTDI? Нет, не слышали.

            Вот за это в том числе я и не люблю яву.
            Ответить
      • > Что значит "для передачи его как аргументом java.io.OutputStream"?
        Как я понял defecate++ хочет передать его некой функции, которая принимает OutputStream, и вываливает в него некий дамп некой фигни.

        UPD: Ну вот он и сам об этом написал. А я как всегда не обновлял комментарии перед тем как постить.
        Ответить
        • Это ужасный абьюз API, и если подумать, будет понятно, почему.

          Логгер - не поток. Атомарная единица потока - байт, а логгера - сообщение. При этом сообщение должно быть текстовым (в то время как в поток можно писать произвольные байты), у сообщения есть дата, источник, опциональный stack trace и прочие прелести жизни.
          Ответить
          • Само собой. Но иногда, в целях отладки или разбора полетов, удобно иметь в том же лог-файле какой-нибудь дамп структур\сообщений между обычных лог-записей. Писать дампы в отдельный файл неудобно - придется тратить время на поиск соответствий.

            P.S. Конечно же я понимаю, что аппендер это не лог-файл, и что он может писать во что-то более сложное, например таблицу в базе. Но юзкейс, имхо, вполне жизненный.

            В голову приходит еще один вариант - создать аппендера пишущего в поток, и этот самый поток юзать для записи в него дампов. Если аппендер флашит его после каждой месаги - все будет норм. Но что-то я запамятовал, можно ли писать в поток из нескольких тредов.
            Ответить
            • > В голову приходит еще один вариант
              Вариант плохой, т.к. если поток не лочить на время дампанья, дамп может рассеяться среди сообщений от других тредов.
              Ответить
          • в языке с RAII легко выдать в аргумент объекту поток, который 1) сможет выдавать очередную порцию в лог ("атомарное сообщение") по методу flush(), 2) так же запушит в лог остаток при своем принудительном/автоматическом закрытии
            при этом объект будет уверен, что всего лишь работает с std::ostream
            Ответить
            • Флушить в деструкторе немного неприятно... Экцепшн не кинешь. Кода возврата нет.
              Ответить
              • кстати, про экцепшены
                тарасу понравится
                try {
                    // some sql shit, leaving connection alive
                }
                catch (SQLException e) {
                    logger.error(e);
                
                    // cannot just close connection
                    // hate you!
                    try {
                        oraConnection.close();
                    }
                    catch (SQLException e2) {}
                
                    return false;
                }
                Ответить
                • http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/io/Closeables.html#closeQuietly(java.io.Clo seable)
                  Ответить
                  • тогда уж commons-dbutils

                    подробная ссылочка траеблядства для Тараса, покрасивее:
                    http://stackoverflow.com/questions/2225221/closing-database-connections-in-java/2225275#2225275
                    Ответить
                • Среди разрабов линукса, помнится, был холивар по поводу того, должно ли close() возвращать код ошибки. Если мне не изменяет память, Линус сказал что нехрен, ибо все равно никто не обрабатывает.
                  Ответить
                  • Я несколько раз попадался на необходимости флушить или применять транзакцию в деструкторе. Но не кинуть исключение, не сообщить о проблемах результата операции я не мог
                    Ответить
        • при этом некая фигня - это ~200Кб текста
          туда сюда её по потокам сувать

          а это всё потому, что в жабе нет перегрузки оператора <<
          (хотел зелёным, но не буду, ибо всё чистая правда)
          Ответить
          • Тут без зеленого вбросы не понимают.
            Ответить
            • Если от проверенного умного человека вброс звучит, то окружающие понимают, что реально такого он сказать не мог и лишь троллирует (особенно если ранее озвучивал своё мнение по этому вопросу). А прочим рекомендуют отсвечивать зеленым.
              Ответить
    • показать все, что скрытоvanished
      Ответить

    Добавить комментарий