Как создать свой собственный Appender в log4j?

Я новичок в log4j. Кто-нибудь может объяснить, как создать свой собственный Appender? то есть как реализовать классы и интерфейсы и как их переопределить?


person unknown    schedule 20.05.2011    source источник
comment
вам необходимо реализовать интерфейс добавления. но вам, вероятно, следует создать подкласс одного из существующих приложений и переопределить методы, например. doAppend(LoggingEvent) в соответствии с вашими потребностями.   -  person happymeal    schedule 20.05.2011
comment
что, если существующий аппендикс является окончательным?   -  person Gaurav    schedule 15.02.2019


Ответы (4)


Вы должны расширить класс AppenderSkeleton, который (цитируя javadoc) «предоставляет код для общих функций, таких как поддержка пороговой фильтрации и поддержка общих фильтров».

Если вы прочтете код AppenderSkeleton, то увидите, что он обрабатывает почти все, оставляя вам только:

  1. protected void append (событие LoggingEvent)
  2. публичное закрытие пустоты ()
  3. общественное логическое значение требуетLayout()

Основным методом является append. Помните, что вам не нужно реализовывать в нем логику фильтрации, потому что она уже реализована в doAppend, который, в свою очередь, вызывает append. Здесь я сделал (совершенно бесполезный) класс, который хранит записи журнала в ArrayList, как демонстрацию.

public /*static*/ class MyAppender extends AppenderSkeleton {
    ArrayList<LoggingEvent> eventsList = new ArrayList();

    @Override
    protected void append(LoggingEvent event) {
        eventsList.add(event);
    }

    public void close() {
    }

    public boolean requiresLayout() {
        return false;
    }

}

Хорошо, давайте проверим это:

public static void main (String [] args) {

    Logger l = Logger.getLogger("test");

    MyAppender app = new MyAppender();

    l.addAppender(app);

    l.warn("first");
    l.warn("second");
    l.warn("third");

    l.trace("fourth shouldn't be printed");

    for (LoggingEvent le: app.eventsList) {
        System.out.println("***" + le.getMessage());
    }
} 

У вас должны быть напечатаны «первый», «второй», «третий»; четвертое сообщение не должно быть напечатано, поскольку уровень журнала корневого регистратора — отладка, а уровень событий — трассировка. Это доказывает, что AbstractSkeleton правильно реализует для нас «управление уровнями». Так что это определенно кажется правильным... теперь вопрос: зачем вам нужен пользовательский присоединитель, в то время как в этом журнале есть много встроенных практически для любого места назначения? (кстати, хорошее место для начала с log4j: http://logging.apache.org/log4j/1.2/manual.html)

person AgostinoX    schedule 23.05.2011
comment
я использовал вышеуказанный класс, без ошибок, .. как я могу определить, что новый Appender будет создан? Как я могу его использовать? - person unknown; 24.05.2011
comment
Из logging.apache.org/log4j/1.2/manual.html,A Запрос журнала уровня p в регистраторе с (назначенным или унаследованным, в зависимости от того, что подходит) уровнем q включается, если p›=q. Запрос журнала имеет уровень трассировки, в то время как для регистратора установлен уровень отладки, который выше уровня трассировки, поэтому он не будет зарегистрирован. Помните, что регистратору не назначается уровень, поэтому он наследует уровень корневого регистратора. Чтобы регистратор регистрировал также запросы уровня трассировки (максимальная многословность!), вы можете установить программно (l.setLevel(Level.TRACE);) или (лучше) через файлы свойств уровень регистратора или корневого регистратора. - person AgostinoX; 24.05.2011
comment
я создал веб-службу, теперь я хочу вызвать веб-службу с помощью этого Appender. как я могу вызвать? - person unknown; 25.05.2011
comment
Вы имеете в виду, как использовать этот Appender изнутри веб-сервера? - person AgostinoX; 25.05.2011
comment
Я не знаю ваш конкретный веб-сервер. Пробовали ли вы предложения по инициализации по умолчанию в Tomcat, которые входят в logging.apache.org/log4j /1.2/manual.html ? - person AgostinoX; 25.05.2011
comment
хорошо, когда сервер запускается, файлы журнала печатают выходной оператор ... как я могу напечатать этот оператор журнала в своем собственном файле? - person unknown; 25.05.2011
comment
Это не то, что вы задали в своем первоначальном вопросе. Если вы создали свой собственный подкласс Appender, вы должны предоставить код для записи на диск. Вероятно, вам не нужен пользовательский класс Appender, вам нужен только FileAppender, который регистрируется на диске из коробки. Вы просто указываете имя файла. - person AgostinoX; 25.05.2011
comment
@Elakkiya: пожалуйста. Вы решили свою проблему с log4j? Вы расширили AppenderSkeleton или использовали какой-либо предоставленный Appender? - person AgostinoX; 04.06.2011
comment
Моя проблема здесь ссылка - person unknown; 04.06.2011
comment
Привет, ты знаешь, как это сделать в более новых версиях? Я спрашиваю, так как это не работает для меня сейчас. Я получаю сообщение об ошибке, что в логгере нет функции addAppender. - person Tomer; 07.05.2017

Если вы хотите выполнить некоторые манипуляции или решения, вы можете сделать это следующим образом:

@Override
protected void append(LoggingEvent event) {
        String message = null;
        if(event.locationInformationExists()){
            StringBuilder formatedMessage = new StringBuilder();
            formatedMessage.append(event.getLocationInformation().getClassName());
            formatedMessage.append(".");
            formatedMessage.append(event.getLocationInformation().getMethodName());
            formatedMessage.append(":");
            formatedMessage.append(event.getLocationInformation().getLineNumber());
            formatedMessage.append(" - ");
            formatedMessage.append(event.getMessage().toString());
            message = formatedMessage.toString();
        }else{
            message = event.getMessage().toString();
        }

        switch(event.getLevel().toInt()){
        case Level.INFO_INT:
            //your decision
            break;
        case Level.DEBUG_INT: 
            //your decision
            break;
        case Level.ERROR_INT:
            //your decision
            break;
        case Level.WARN_INT:
            //your decision
            break;
        case Level.TRACE_INT:
            //your decision
            break;
        default:
            //your decision
            break;
        }
}
person Lior    schedule 24.04.2013

Я хотел бы использовать ответ @AgostinoX для поддержки конфигурации файла pro и возможности запуска и остановки записи журнала:

public class StringBufferAppender extends org.apache.log4j.AppenderSkeleton {

    StringBuffer logs = new StringBuffer();
    AtomicBoolean captureMode = new AtomicBoolean(false);

    public void close() {
        // TODO Auto-generated method stub

    }

    public boolean requiresLayout() {
        // TODO Auto-generated method stub
        return false;
    }


    @Override
    protected void append(LoggingEvent event) {
        if(captureMode.get())
            logs.append(event.getMessage());
    }

    public void start()
    {
        //System.out.println("[StringBufferAppender|start] - Start capturing logs");
        StringBuffer logs = new StringBuffer();
        captureMode.set(true);
    }

    public StringBuffer stop()
    {
        //System.out.println("[StringBufferAppender|start] - Stop capturing logs");
        captureMode.set(false);
        StringBuffer data = new StringBuffer(logs);
        logs = null;
        return data;
    }


}

Теперь все, что вам нужно сделать, это определить в файле log4j.property

log4j.rootLogger=...., myAppender  # here you adding your appendr name
log4j.appender.myAppender=com.roi.log.StringBufferAppender # pointing it to the implementation

чем когда вы хотите включить его во время runtume:

Logger logger = Logger.getRootLogger();
        StringBufferAppender appender = (StringBufferAppender)logger.getAppender("myAppender");
        appender.start();

и пока хотите остановить это:

StringBuffer sb = appender.stop();
person USer22999299    schedule 01.08.2015
comment
Ошибка: удалите StringBuffer из следующего: StringBuffer logs = new StringBuffer(); - person Lennart Rolland; 27.08.2016
comment
@LennartRolland это не ошибка. - person USer22999299; 29.08.2016
comment
Я получаю сообщение об ошибке при переопределении метода append(событие LoggingEvent) - The method append(LoggingEvent) of type MyCustomAppender must override or implement a supertype method - person Chetan Oswal; 10.03.2020

Чтобы создать собственный Appender, вы просто реализуете интерфейс Appender и просто переопределяете его. А также изучите эту ссылку, начните лог

person Aabi    schedule 10.06.2011