我在java中创建了一个小型Web应用程序。现在我想添加日志功能。但我不想使用任何可用的Logging框架,如Log4j或其他东西,而是我想创建自己的日志框架,这也可以在将来使用。因此,需要一些初步推进,这是正确的地方。
感谢。
答案 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)
这些是您在尝试创建自己的日志记录框架时可能遇到的一些陷阱:
答案 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指出的陷阱,测量是你最好的朋友。