java应用程序的日志框架

时间:2010-02-08 11:17:35

标签: java logging

我在java中创建了一个小型Web应用程序。现在我想添加日志功能。但我不想使用任何可用的Logging框架,如Log4j或其他东西,而是我想创建自己的日志框架,这也可以在将来使用。因此,需要一些初步推进,这是正确的地方。

感谢。

6 个答案:

答案 0 :(得分:18)

我的建议是不要这样做。使用经过测试和测试的日志框架,例如log4j。你为什么要重新发明轮子?

在现有框架上花了很多时间 - 让它们在各种不同的环境下快速工作等等。当你可以花费同样时间处理用户真正关心的功能时,你是否真的想浪费时间复制这些工作?大约?

不要忘记许多框架(例如log4j,甚至是内置的java.util.logging)都可以使用您自己的格式化程序,处理程序等进行扩展。您应该真正计算出您想要做的事情。由现有框架覆盖,看看你是否可以构建那个位而不是创建另一个日志框架。

如果您确定 需要编写一些额外的代码,那么您可以提出有关这些特定需求的问题,而不是您当前的一般性问题。

答案 1 :(得分:3)

这样做是件好事,因为你会明白为什么要使用众多优秀的日志框架之一。在你摆弄了一个星期之后,回去使用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 :(得分:2)

这些是您在尝试创建自己的日志记录框架时可能遇到的一些陷阱:

  • 并发问题:可以通过不同的线程同时访问日志框架。您需要确保不会发生冲突,并确保以正确的顺序记录消息。
  • 实例化:框架必须实例化一次,然后可供应用程序的其余部分使用。你需要一个'Singleton'类,你必须仔细实现。使用静态方法是一种方法。
  • 您必须具有使用xml文件或注释的配置机制。
  • 您的框架必须与第三方库合作。我相信这对你来说是真正的绊脚石。您可能拥有代码的日志框架,但您使用的库需要另一个。

答案 3 :(得分:1)

已经有太多的Java日志框架了。

为什么不包装内置的java.util.logging

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

答案 4 :(得分:1)

如果你真的想制作自己的伐木工作(我强烈建议你不要),那么先写下一些要求。它该怎么办?应该具备哪些功能等。

示例是能够写入多个输出 - 文件,控制台,套接字,串口等

同样是多线程写入 - 你不希望多个线程同时写入日志,否则你最终会得到垃圾。

日志级别 - 多少?

然后你可以开始编写代码....只是,正如建议的那样,我不明白为什么你没有使用那里的许多免费提供的记录框架之一,,,

答案 5 :(得分:0)

您想要一个小内存占用但可扩展性?避免过早优化,然后:尝试log4j或java.util.logging,测量足迹(条件编译),看看你是否真的可以通过滚动自己或分支来打败它。除了定义Visage建议的要求,并满足kgiannakakis指出的陷阱,测量是你最好的朋友。