tags:

views:

109

answers:

6

I have created a small web application in java. And now I want to add Logging features to it. But i don't want to use any available Logging framework like Log4j or something else, instead I want to create my own logging framework which can be expendable in future as well. So need some initial push ups for the same, And this is the right place for that.

Thanks.

+12  A: 

My advice would be not to do it. Use tried and tested logging frameworks such as log4j. Why do you want to reinvent the wheel?

A lot of time has been spent on existing frameworks - making them work fast, under various different environments etc. Do you really want to waste time replicating that effort when you could spend the same time on features that your users will really care about?

Don't forget that many frameworks (such as log4j, or even the built-in java.util.logging) are extensible with your own formatters, handlers etc. You should really work out what you want to do which isn't covered by the existing frameworks and see whether you can build just that bit rather than creating yet another logging framework.

If and when you've worked out that you do need to write some extra code, you can then ask questions about those specific needs, rather than your current rather general question.

Jon Skeet
+1 For advising to not reinvent the wheel.
Oded
Thanks Jon. But it will create a dependency on that. and i have limited storage problem. so i want to use how much it is required for my application, only those i will develop.
GK
@gurukulki: If you develop your own framework, that's going to take space too. Just how limited are you? You can always cut down which bits of log4j you ship - or use java.util.logging which is already in the JDK so won't add a new dependency.
Jon Skeet
Jon is right. As said in Effective Java for example, use libraries before redevelopping code. The people behind these frameworks have already thought of many things for you, including that "storage problem" (by the way log4j is 400ko, you're trying to develop on a floppy disk or what ?)
Valentin Rocher
Besides, if your consideration is "I don't want an extra jar", use the JDK logging.
Valentin Rocher
+1  A: 

There are already too many Java logging frameworks out there.

Why not just wrap the built in java.util.logging?

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

pjp
+1  A: 

If you really want to make your own logging franmework (and I strongly suggest you dont), then write down some requirements first. What should it do? What features should it have etc.

Examples are the ability to write to mulitple outputs - files, consoles, sockets, serial ports etc

Also multithreaded writing - you dont want multiple threads writing to a log at the same time, else you'll end up with garbage.

Log levels - how many?

Then you can start writing code....only, as suggested, I dont see why you're not using one of the many freely available logging framewroks out there,,,

Visage
+2  A: 

These are some pitfalls you may fell in while trying to create your own logging framework:

  • Concurrency issues: The logging framework may be accessed at the same time by different threads. You need to ensure that no conflicts arise and that the messages are logged in the right order.
  • Instantiation: The framework must be instantiated once and then be available to the rest of the application. You need a 'Singleton' class, which you must implement carefully. Using static methods is a way to go.
  • You must have a configuration mechanism, using xml files or annotations.
  • Your framework must cooperate with third-party libraries. I believe this is the real stopper for you. You may have your logging framework for your code, but the libraries you are using require another one.
kgiannakakis
+2  A: 

It's a good thing to do only because you'll realise why you should use one of the many and excellent logging frameworks. After you have fiddled around with this for a week, go back and use log4j.

However, until then, and to get you started, here is one I prepared earlier just because I wanted to get my head round what the complexity was. This is incomplete for your purposes and I recommend you use it just to decide what you want to do rather than base your implementation on it. It should give you a reasonable idea of what is necessary and it provides basic single threaded logging...

/*
 * 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;
    }

}

and here's the interface

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();
}
Simon
A: 

You want a small memory footprint yet expandability? Avoid premature optimization, then: try log4j or java.util.logging, measure the footprint (conditional compilation), and see if you really can beat that by rolling your own or branching off. Besides defining requirements as Visage advises, and meeting the pitfalls kgiannakakis points out, measurements are your best friend.

Pontus Gagge