Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > log4j логирование


Автор: Samotnik 19.1.2009, 23:12
сабж
Есть приложение  TCP/IP 
нужно сделать элементарную вещь  smile 
каждый новый клиент, который коннектицца к серверу должен писаться в отдельный файл. 
Т.Е.  законнектился первый - для него создался файл и туда пишется все то, что присылает этот клиент. И так для каждого.
Код

ServerSocket ss;
ss = new ServerSocket(9876);
            System.out.println("Server started!");
            Socket socket;
            while (true) {
                socket = ss.accept();
                Thread t = new Thread(new MyThread(socket));
                t.start();
                System.out.println("New connection!");
            }

Вот этот вывод нужно писать с помощью логов в отдельные файлы
Соббсно сам вопрос
Как сконфигурять log4j.xml ?   smile

Добавлено через 10 минут
на данный момент у меня такая вот конфигурация 
Код

<?xml version='1.0' encoding='ISO-8859-1' ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration>

    <appender name="LOG-FILE-APPENDER" class="org.apache.log4j.FileAppender">
        <param name="file" value="app.log"/>
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d{ISO8601} [%5p] %c %m at %l%n"/>
        </layout>
    </appender>

    <root>
        <priority value="DEBUG"/>
        <appender-ref ref="LOG-FILE-APPENDER"/>
    </root>

</log4j:configuration>

Автор: COVD 20.1.2009, 01:12
Цитата

Т.Е.  законнектился первый - для него создался файл 

Т.Е.  законнектился первый - для него создался .. логгер. 

Однако сразу после accept имя пользователя как правило неизвестно. Поэтому мы всех пишем в единый лог. И сохраняем там ip. После того, как имя стало известно, то и имя добавляем в соответствующую позицию. А анализируем логи с помошью программ http://www.baremetalsoft.com/ - нужного пользователя можно выделить с помощью фильтров. И в то же время можно видеть общую картину.

ЗЫ Ну, не принижайте без нужды наше ремесло - "элементарная задача" smile .

Автор: ivg 20.1.2009, 01:40
Цитата(COVD @  20.1.2009,  03:12 Найти цитируемый пост)
И сохраняем там ip. После того, как имя стало известно, то и имя добавляем в соответствующую позицию.

Примерчик элементарной реализации этого можно? smile Я к тому, что для тех, кто слабо знаком с log4j, не так уж это и элементарно.

Автор: Samotnik 20.1.2009, 01:46
не  я не про то  smile 
Я отлавливаю каждое новое соединение (пример кода я выложил)
При каждом новом соединении у меня пишется  System.out.println("New connection!");
так вот я спрашиваю
как сделать эту же запись тока в разные файлы ???
т.е. сейчас у меня все пишется в один файл (file.log) типа 
Цитата

клиент 1 соед
клиент 2 соед
клиент 3 соед 
и т.д.

а мне нужно чтобы эти соединения писались в разные файлы, т.е. к примеру 
file1.log
клиент 1 соед

file2.log
клиент  2 соед

file3.log 
клиент 3 соед

Автор: ivg 20.1.2009, 02:14
Samotnik, я тебя понял, что ты хочешь. Но на каждый сеанс по файлу - по мне, плохая идея. По пользователю - нормально, но сначала аутентификация, а до этого логи куда девать? Того, что ты хочешь - самый нормальный вариант - по IP. Но в текущей реализации log4j конфигурированием этого, по моему, не сделать. Только если написать свой Appender. Но, как уже сказал COVD, с использованием программ для анализа логов, такая необходимость отпадает.

Автор: Samotnik 20.1.2009, 02:46
Цитата(ivg @  20.1.2009,  01:14 Найти цитируемый пост)
Но на каждый сеанс по файлу - по мне, плохая идея

возможно
но нужно сделать именно так ! 
неужто нету способов писать все не в один файл в одном аппендере, а в много файлов ?  К новому файлу добавлять цифирку ?

Добавлено через 1 минуту и 15 секунд
Цитата(ivg @  20.1.2009,  01:14 Найти цитируемый пост)
ого, что ты хочешь - самый нормальный вариант - по IP

окей
и как это сделать по ип ?
Цитата(ivg @  20.1.2009,  01:14 Найти цитируемый пост)
Только если написать свой Appender.

как это сделать ?
без сторонних тулзов 

Автор: vdweller 20.1.2009, 10:31
Статическим конфигом так не сделать скорее всего, тебе придется в рантайме после создания логгера задавать ему имя файла

Автор: LSD 20.1.2009, 12:43
Цитата(Samotnik @  20.1.2009,  02:46 Найти цитируемый пост)
неужто нету способов писать все не в один файл в одном аппендере, а в много файлов ?

Стандартные аппендеры такого не позволяют.

Если бы меня уж так прижало реализовывать такую лабуду, я бы написал бы свой аппендер + NDC. Или динамическое создание категорий и конфигурирование аппендеров из кода.

Автор: Samotnik 20.1.2009, 14:03
Цитата(LSD @  20.1.2009,  11:43 Найти цитируемый пост)
Если бы меня уж так прижало реализовывать такую лабуду

почему лабуду ?
вот допустим есть чат  который работает по  tcp/ip  все клиенты проходят через сервер
и вот серверу нужно для каждого клиента создавать свой логгер и вести записи для каждого клиента, как в аське - история общения сохраняется для КАЖДОГО юзера с которым ты говорил, а не  все разговоры в одном файле
Вот и мне нужно сделать то же самое, никакой лабуды тут не вижу, очень полезная штука! Хранить разговоры каждого клиента в отдельном файле  smile

Добавлено через 47 секунд
вобщем ясно, никто ничего не подскажет  smile 

Автор: dima32 20.1.2009, 14:21
Если тебе непонятно как сделать свой аппендер - вот тут прмер:
http://www.log4j.ru/articles/NewAppender.html

Добавлено @ 14:30
ну и как сказал LSD и наверно использование org.apache.log4j.NDC удобно  для хранения какой-то id клиента (хотя   пойдёт даже Статическая ThreadLocal переменная )

Автор: LSD 21.1.2009, 00:32
Цитата(Samotnik @  20.1.2009,  14:03 Найти цитируемый пост)
почему лабуду ?
вот допустим есть чат  который работает по  tcp/ip  все клиенты проходят через сервер
и вот серверу нужно для каждого клиента создавать свой логгер и вести записи для каждого клиента, как в аське - история общения сохраняется для КАЖДОГО юзера с которым ты говорил, а не  все разговоры в одном файле
Вот и мне нужно сделать то же самое, никакой лабуды тут не вижу, очень полезная штука! Хранить разговоры каждого клиента в отдельном файле

ICQ совсем другое дело.
1. Это не логи, а история сообщений.
2. Количество контактов в ICQ фиксировано, в отличие от количества IP адресов.

Автор: Samotnik 21.1.2009, 03:06
dima32, спасибо, только я  не понимаю, а что делать со своим аппендером ? 
Каким образом его применить в нужных мне целях ? 
 smile  smile  smile  smile 
За ссылку спасибо  smile  smile 

Автор: ivg 21.1.2009, 13:46
Samotnik, сохранение истории сообщений в чате - это функционал самого приложения, а не библиотек типа log4j. То есть с помощью log4j так или иначе можно получить то что ты хочешь. Только вот вопрос а надо ли? Я предлагаю отказаться от идеи - хранить это дело в файлах. Сообщения каждого пользователя имеют смысл вместе с сообщениями других участников, так ведь? Если в общем чате несколько десятков человек, в файл каждого из них ты будешь сохранять одну и туже информацию(сообщения всех участников)? Или только одного человека? А как потом собирать всё это в диалог? Нам ведь нужны простые решения так ведь? Если пользователь захочет посмотреть историю весь файл будешь пересылать? Или в твоём случае эти логи нужны только "большому брату"? smile
Короче, если делать как в ICQ, предоставлять пользователю выборку истории за определённый период времени, фильтры на пользователей и т. п. однозначно ИМХО, лучшим местом хранения сообщений будет база данных.

Автор: dima32 23.1.2009, 09:13
Примерно так. Как уже было сказано - log4j не обязательно
Код

public class MyThread extends Thread{
    private static ThreadLocal<String> clientIp;
    Socket socket;
    public MyThread(Socket socket) {
        this.socket=socket;
    }

    @Override
    public void run() {
        clientIp.set(socket.getRemoteSocketAddress().toString());
        try{
          //do here   what you want
         // log.info(" my message")
       
        }finally {
            clientIp.set(null);
        }        
    }    
}



Код


    public class MyAppender extends AppenderSkeleton{
        @Override
        protected void append(LoggingEvent event) {
            String fileName=MyThread.clientIp.get();
            String message=event.getMessage();
            // write message  file             
        }

      //implement other methods
    }



ну и конфиг будет примерно такой
Код


<?xml version='1.0' encoding='ISO-8859-1' ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration>
    <appender name="LOG-FILE-APPENDER" class="MyAppender"/>
    <root>
        <priority value="DEBUG"/>
        <appender-ref ref="LOG-FILE-APPENDER"/>
    </root>
</log4j:configuration>

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)