Каркас ведения журнала для Java-приложения - PullRequest
0 голосов
/ 08 февраля 2010

Я создал небольшое веб-приложение на Java. А теперь я хочу добавить в него функции ведения журнала. Но я не хочу использовать какую-либо доступную инфраструктуру журналирования, такую ​​как Log4j или что-то еще, вместо этого я хочу создать свою собственную инфраструктуру журналирования, которая также может быть использована в будущем. Поэтому нужно несколько отжиманий для того же самого, и это подходящее место для этого.

Спасибо.

Ответы [ 6 ]

18 голосов
/ 08 февраля 2010

Мой совет - не делать этого. Используйте проверенные и проверенные каркасы журналирования, такие как log4j. Почему вы хотите заново изобрести колесо?

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

Не забывайте, что многие фреймворки (такие как log4j или даже встроенный java.util.logging) расширяются с помощью ваших собственных форматеров, обработчиков и т. Д. Вы действительно должны решить, что вы хотите делать, что не так. рассмотрим существующие фреймворки и посмотрим, сможете ли вы создать только этот бит вместо создания еще одной фреймворка журналирования.

Если и когда вы выяснили, что вам нужно написать какой-то дополнительный код, вы можете задавать вопросы об этих конкретных потребностях, а не о своем текущем довольно общем вопросе.

3 голосов
/ 08 февраля 2010

Это хорошо сделать только потому, что вы поймете, почему вы должны использовать одну из множества отличных платформ журналирования. После того, как вы возились с этим в течение недели, вернитесь и используйте log4j.

Однако, до тех пор, и чтобы вы начали, вот один, который я подготовил ранее только потому, что хотел разобраться, какова сложность. Это неполно для ваших целей, и я рекомендую вам использовать его просто для того, чтобы решить, что вы хотите сделать, а не основывать свою реализацию на этом. Он должен дать вам разумное представление о том, что необходимо, и обеспечивает базовое однопоточное ведение журнала ...

/*
 * Created on Jun 11, 2005
 */
package com.hupa.util;

import java.io.*;
import java.util.Date;

/**
 * @author simonpalmer
 */
public class MessageWriter implements ILog
{
    public class e_LogLevel
    {
        public static final int e_log_error = 1;
        public static final int e_log_warn = 2;
        public static final int e_log_info = 4;
        public static final int e_log_debug = 8;
    }
    public int m_iLogLevel = e_LogLevel.e_log_error;
    public String m_strLogFile = new String();
    public String m_strLogPath = new String();
    public boolean m_bConsoleOut = true;
    PrintStream m_ps;
    public boolean m_bLogOpen = false;
    private static Date dt = new Date();

    /**
     * Output info level message
     * @param strMess
     */
    public void info(String strMess)
    {
        if ((m_iLogLevel & e_LogLevel.e_log_info) == e_LogLevel.e_log_info)
        {
            dt.setTime(System.currentTimeMillis());
            String strOut = dt.toString() + " inf: " + strMess;
            if (m_bConsoleOut) System.out.println(strOut);
            if (m_bLogOpen) m_ps.println(strOut);
        }
    }
    public boolean bInfo(){return ((m_iLogLevel & e_LogLevel.e_log_info) == e_LogLevel.e_log_info);}
    /**
     * Output debug level message
     * @param strMess
     */
    public void debug(String strMess)
    {
        if ((m_iLogLevel & e_LogLevel.e_log_debug) == e_LogLevel.e_log_debug)
        {
            dt.setTime(System.currentTimeMillis());
            String strOut = dt.toString() + " dbg: " + strMess;
            if (m_bConsoleOut) System.out.println(strOut);
            if (m_bLogOpen) m_ps.println(strOut);
        }
    }
    public boolean bDebug(){return ((m_iLogLevel & e_LogLevel.e_log_debug) == e_LogLevel.e_log_debug);}
    /**
     * Output warning level message
     * @param strMess
     */
    public void warn(String strMess)
    {
        if ((m_iLogLevel & e_LogLevel.e_log_warn) == e_LogLevel.e_log_warn)
        {
            dt.setTime(System.currentTimeMillis());
            String strOut = dt.toString() + " warn: " + strMess;
            if (m_bConsoleOut) System.out.println(strOut);
            if (m_bLogOpen) m_ps.println(strOut);
        }
    }
    public boolean bWarn(){return ((m_iLogLevel & e_LogLevel.e_log_warn) == e_LogLevel.e_log_warn);}
    /**
     * Output error level message
     * @param strMess
     */
    public void error(String strMess)
    {
        if ((m_iLogLevel & e_LogLevel.e_log_error) == e_LogLevel.e_log_error)
        {
            dt.setTime(System.currentTimeMillis());
            String strOut = dt.toString() + " err: " + strMess;
            if (m_bConsoleOut) System.out.println(strOut);
            if (m_bLogOpen) m_ps.println(strOut);
        }
    }
    public boolean bError(){return ((m_iLogLevel & e_LogLevel.e_log_error) == e_LogLevel.e_log_error);}

    /**
     * construst the log file name
     * @return String, full file path and name
     */
    public String GetLogFileName()
    {
        return m_strLogPath + m_strLogFile + ".log";
    }

    /**
     * Open the log file prescribed by the settings
     * @return boolean, success
     */
    public boolean OpenLog()
    {
        try
        {
            m_ps = new PrintStream(new FileOutputStream(GetLogFileName()));
            m_bLogOpen = true;
        }
        catch (FileNotFoundException e)
        {
            // this means that the folder doesn't exist
            if (MakeFolder(m_strLogPath))
            {
                m_bLogOpen = true;
                try
                {
                    m_ps = new PrintStream(new FileOutputStream(GetLogFileName()));
                }
                catch (IOException e1)
                {
                    e.printStackTrace();
                    m_bLogOpen = false;
                }
            }
        }
        return m_bLogOpen;
    }

    public static boolean MakeFolder(String strFolder)
    {
        try
        {
            java.io.File f = new File(strFolder);
            if (!f.mkdirs())
            {
                return false;
            }
        }
        catch (SecurityException e)
        {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * Close the log file
     * @return boolean, success
     */
    public boolean CloseLog()
    {
        if (m_ps != null)
        {
            m_ps.flush();
            m_ps.close();
        }
        m_bLogOpen = false;
        return m_bLogOpen;
    }

    public void setConsoleOut(boolean b)
    {
        m_bConsoleOut = b;
    }
    public void setLogLevel(int i)
    {
        m_iLogLevel = i;
    }

}

и вот интерфейс

public interface ILog 
{
    abstract public void debug(String message);
    abstract public void info(String message);
    abstract public void warn(String message);
    abstract public void error(String message);

    abstract public void setLogLevel(int i);
    abstract public void setConsoleOut(boolean b);
    abstract public boolean CloseLog();
    abstract public boolean OpenLog();

    abstract public boolean bDebug();
}
2 голосов
/ 08 февраля 2010

Вот некоторые подводные камни, в которые вы можете попасть, пытаясь создать собственную структуру ведения журнала:

  • Проблемы параллелизма. Доступ к среде ведения журналов может осуществляться разными потоками одновременно. Необходимо убедиться, что не возникает никаких конфликтов и что сообщения регистрируются в правильном порядке.
  • Инстанциация: фреймворк должен быть создан один раз, а затем доступен для остальной части приложения. Вам нужен класс 'Singleton', который вы должны тщательно реализовать. Использование статических методов - путь.
  • У вас должен быть механизм настройки, использующий XML-файлы или аннотации.
  • Ваш фреймворк должен взаимодействовать со сторонними библиотеками. Я считаю, что это настоящая пробка для вас. Возможно, у вас есть логическая структура для вашего кода, но для библиотек, которые вы используете, требуется другая.
1 голос
/ 08 февраля 2010

Если вы действительно хотите сделать свой собственный журнал работы (и я настоятельно рекомендую вам этого не делать), то сначала запишите некоторые требования. Что это должно сделать? Какие функции он должен иметь и т. Д.

Примерами являются возможность записи в несколько выходов - файлы, консоли, сокеты, последовательные порты и т. Д.

Также многопоточная запись - вам не нужно, чтобы несколько потоков писали в журнал одновременно, иначе вы получите мусор.

Лог уровней - сколько?

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

1 голос
/ 08 февраля 2010

Уже существует слишком много фреймворков для ведения журналов Java.

Почему бы просто не обернуть встроенный java.util.logging?

http://java.sun.com/j2se/1.4.2/docs/guide/util/logging/overview.html

0 голосов
/ 08 февраля 2010

Вы хотите небольшой объем памяти, но расширяемость? Избегайте преждевременной оптимизации, а затем: попробуйте log4j или java.util.logging, измерьте размер (условную компиляцию) и посмотрите, действительно ли вы можете справиться с этим, откатившись или развернувшись. Помимо определения требований, как советует Visage, и удовлетворения ловушек, на которые указывает kgiannakakis, измерения - ваш лучший друг.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...