Не удалось закрыть файлы JposLogger

Я использую jpos 2.1.0 и использую JposLogger для создания и ротации журналов iso. Однако я не могу правильно настроить параметры, из-за чего ни журналы не вращаются в зависимости от дат, ни я не могу закрыть открытые файлы журналов.

Это связано с предыдущей проблемой Открыто слишком много файлов

что, как я думал, было связано с проблемой использования универсального упаковщика, но если углубиться, это произошло из-за неправильного закрытия файлов, сгенерированных JposLogger, что можно определить с помощью команды lsof -p в centos. Для одного запроса создается один файл.

[cipsappcen@connectipsappcen local]$ lsof -p 12108 |grep iso.log
java    12108 cipsappcen   36w      REG              253,2     58589 405618549 /u03/connectIPSSRVC/log/iso.log
java    12108 cipsappcen   47w      REG              253,2     58589 405618549 /u03/connectIPSSRVC/log/iso.log

public class Iso8583MessageBOKImpl implements Iso8583Message{
JposLogger logger = new JposLogger(isoLogLocation);
        org.jpos.iso.ISOPackager customPackager = new GenericPackager(isoPackagerLocation+iso8583Properties.getPackager());
        BaseChannel channel = new ASCIIChannel(iso8583Properties.getServerIp(), Integer.parseInt(iso8583Properties.getServerPort()), customPackager);// live
        logger.jposlogconfig(channel);
...
}

public void jposlogconfig(ISOChannel channel){
        try{
            //Configuring Logger   
            Logger logger = new Logger();
            logger.setName("Q2");
            org.jpos.util.DailyLogListener dayLog = new org.jpos.util.DailyLogListener();
            ProtectedLogListener pll = new ProtectedLogListener();
            Configuration protectLogCfg = new SimpleConfiguration();
            protectLogCfg.put("protect", "2");
            pll.setConfiguration(protectLogCfg);
            logger.addListener(pll);

            Configuration dayLogCfg = new SimpleConfiguration();
            dayLogCfg.put("window", "86400");
            dayLogCfg.put("prefix", logLocation);
            dayLogCfg.put("suffix", ".log");  
            dayLogCfg.put("date-format", "-yyyy-MM-dd");
            dayLog.setConfiguration(dayLogCfg);   
            logger.addListener(dayLog);
            logger.addListener(new SimpleLogListener(System.out)); 
            ((LogSource)channel).setLogger(logger, "connectips-channel");

            logger.removeListener(pll);
        }catch(Exception ex){
            System.out.println(ex);
        }
    }

Поскольку файлы не закрываются должным образом, ОС не может обрабатывать слишком много открытых файлов.


person Diwas Sapkota    schedule 03.07.2019    source источник
comment
Привет, этой информации, кажется, недостаточно, чтобы помочь вам с вашей проблемой, поскольку вы говорите, что файл журнала создается для каждого запроса, кажется, ваш метод jposlogconfig вызывается для каждого запроса, поэтому вы создаете новый Logger и LogListener в каждый запрос, и поэтому у вас есть проблема. Чтобы SimpleLogListener чередовал ваш файл журнала и все журналы попадали в один и тот же файл, вам нужно иметь только один экземпляр во всем приложении. Или же в каждом экземпляре вы говорите слушателю создать новый файл и повернуть этот вновь созданный файл, когда окно проходит   -  person Andrés Alcarraz    schedule 03.07.2019


Ответы (1)


Вам нужно создать экземпляр вашего регистратора и loglisteners только один раз в вашем приложении.

Один из вариантов — использовать Logger.getLogger() для регистрации и создания регистратора.

Сначала вам нужно создать регистратор только один раз в вашем приложении, например, с помощью такого метода

public void initLogger() {
    Logger logger = Logger.getLogger("Q2"); //this creates a logger and register it with Q2 name
    org.jpos.util.DailyLogListener dayLog = new org.jpos.util.DailyLogListener();
    ProtectedLogListener pll = new ProtectedLogListener();
    Configuration protectLogCfg = new SimpleConfiguration();
    protectLogCfg.put("protect", "2");
    pll.setConfiguration(protectLogCfg);
    logger.addListener(pll);

    Configuration dayLogCfg = new SimpleConfiguration();
    dayLogCfg.put("window", "86400");
    dayLogCfg.put("prefix", logLocation);
    dayLogCfg.put("suffix", ".log");  
    dayLogCfg.put("date-format", "-yyyy-MM-dd");
    dayLog.setConfiguration(dayLogCfg);   
    logger.addListener(dayLog);
    logger.addListener(new SimpleLogListener(System.out)); 
    //all set now logger is accessible via Logger.getLogger
}

Затем, когда вы создаете новый канал, все, что вам нужно, это установить ранее созданный регистратор:

public class Iso8583MessageBOKImpl implements Iso8583Message{
...
        org.jpos.iso.ISOPackager customPackager = new GenericPackager(isoPackagerLocation+iso8583Properties.getPackager());
        BaseChannel channel = new ASCIIChannel(iso8583Properties.getServerIp(), Integer.parseInt(iso8583Properties.getServerPort()), customPackager);// live
        channel.setLogger(Logger.getLogger("Q2"),"connectips-channel");
...
}

Внутренне Logger.getLogger(String name) создает новый регистратор, если нет ранее зарегистрированного регистратора с таким именем, и регистрирует его в Регистрация имен

Последовательные вызовы с тем же именем возвращают ранее созданный. Таким образом, вы создаете файлы только один раз.

Самое главное здесь то, что initLogger вызывается только в начале вашего приложения, например (это не лучший способ, просто пример) в статическом инициализаторе вашего класса, если это единственное место, где вы используете класс, связанный с jpos :

public class Iso8583MessageBOKImpl implements Iso8583Message{

    static {
        initLogger();
    }
...

И последнее, но не менее важное: я настоятельно рекомендую вам использовать Q2 для инициализации объектов jpos, это руководство содержит все необходимое для создания канала и регистратора.

Затем, когда вы хотите отправить сообщение, вам даже не нужно создавать экземпляр канала, просто вызовите методы QMUX.getMUX(mux-name) и QMUX.request(), чтобы отправить сообщение в канал и получить его ответ.

person Andrés Alcarraz    schedule 03.07.2019
comment
Большое спасибо, это решило мою проблему. Что касается использования сервера Q2, я уже пробовал Q2 в качестве сервера коммутации, где он получает запрос ISO8583 и перенаправляет его на другой CBS/коммутатор с интерфейсом ISO8583. Однако здесь мне нужно предоставить настраиваемый API на основе REST, который будет вызываться несколькими клиентами и будет отправляться в несколько банков (ISO8583) на основе определенных параметров. Поскольку я использую Spring boot для обработки запросов на основе REST и преобразования/пересылки запросов в банки классическим способом. Хотя хочу интегрировать сервер spring и q2, но понятия не имею. Пожалуйста, помогите. - person Diwas Sapkota; 05.07.2019