[jcifs] Patch Suggestion

Hardy Cherry hcherry at xactware.com
Wed May 2 17:06:11 MDT 2012


After implementing Michael's solution I ran into some problems. Here is what I have and what I think is happening.

Let's say I have this class
public class TimeStampedJCIFSLogStream extends PrintStream
{
        private static final String newLine = System.getProperty("line.separator");

        public TimeStampedJCIFSLogStream(PrintStream stream)
        {
                super(stream);
        }

        @Override
        public void println(String x)
        {
                super.println(new java.util.Date().toString() + newLine + "  Source: jCIFS Error " + newLine + "  ERROR: " + x);
        }

        @Override
        public void print(String s)
        {
                super.print(new java.util.Date().toString() + newLine + "  Source: jCIFS Error " + newLine + "  ERROR: " + s);
        }
}

And here is the LogStream class in 1.3.17, I removed the log level variable because it's not important for this question.

public class LogStream extends PrintStream {

    private static LogStream inst;

    public LogStream( PrintStream stream ) {
        super( stream );
    }
    /**
     * This must be called before <tt>getInstance</tt> is called or
     * it will have no effect.
     */
    public static void setInstance( PrintStream stream ) {
        inst = new LogStream( stream );
    }
    public static LogStream getInstance() {
        if( inst == null ) {
            setInstance( System.err );
        }
        return inst;
    }
}

In my code I set up the LogStream like this.
LogStream.setInstance(new TimeStampedJCIFSLogStream (System.err))

Now at some jCIFS calls LogStream.println("Something to print");

It appears that when it calls println, it calls the PrintStream.println() function and bypasses the TimeStampedJCIFSLogStream.println() function. I believe that happens because when I call setInstance it sets the instance to a new LogStream. I guess since it wraps the passed in print stream (which is an instance of TimeStampedJCIFSLogStream), it overrides the overridden methods in TimeStampedJCIFSLogStream with the println function that LogStream inherits. Without making changes to the LogStream class is there any way to get the code to call the TimeStampedJCIFSLogStream.println() function instead of the LogStream.println function?


-Hardy


-----Original Message-----
From: Michael B Allen [mailto:ioplex at gmail.com]
Sent: Tuesday, May 01, 2012 5:50 AM
To: Hardy Cherry
Cc: jcifs at lists.samba.org
Subject: Re: [jcifs] Patch Suggestion

On Mon, Apr 30, 2012 at 1:07 PM, Hardy Cherry <hcherry at xactware.com> wrote:
> We are investigating the use of jCIFS in one of our products. To monitor our error logs we use splunk which depends on each log having a timestamp.
> Would it be possible to format the logs jCIFS creates so that they have a time stamp?
>
> Here is my suggested change to the LogStream class:
> Add an overrided version of println()
>
>    @Override
>    public void println(String x)
>    {
>       String newLine = System.getProperty("line.separator");
>       //Format the error before printing it. Will look like this
>       //Mon Apr 30 04:06:05 MDT 2012
>       //  Source: jCIFS Error Logging
>       //  ERROR: x
>       super.println(new java.util.Date().toString() + newLine + "
> Source: jCIFS Error Logging " + newLine + "  ERROR: " + x);
>    }

Hi Hardy,

A patch is not necessary. Just extend the log stream class, override both println methods as desired and then install it with LogStream.setInstance().

But multiple lines for each entry is probably not what you want. A proper implementation would probably look something like:

class TimestampedLogStream extends jcifs.util.LogStream {

    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    TimestampedLogStream(OutputStream out)
    {
        super(out);
    }

    public void println(Object o)
    {
        synchronized (sdf) {
            super.println(sdf.format(new Date()) + ": " + o);
        }
    }
    public void println(String s)
    {
        synchronized (sdf) {
            super.println(sdf.format(new Date()) + ": " + s);
        }

And then install this early in your program somewhere with a statement like:

  jcifs.util.LogStream.setInstance(new TimestampedLogStream(System.err));

Mike

--
Michael B Allen
Java Active Directory Integration
http://www.ioplex.com/

________________________________

This email is intended solely for the recipient. It may contain privileged, proprietary or confidential information or material. If you are not the intended recipient, please delete this email and any attachments and notify the sender of the error.


More information about the jCIFS mailing list