Intercept System.out and prepend date time in Java
Asked Answered
C

3

6

is it possible to intercept calls to System.out.print* and System.err.print* (in Java) and prepend a time stamp to them? Don't worry, we use the usual logging frameworks, but occasionally some sys.out leaks out and it would be nice to know when it happen so we can tie it up to the proper log files.

Cant answered 22/6, 2013 at 5:42 Comment(1)
You can use aspects for that. Check out AspectJ.Ostracoderm
L
10

You can do it.

See the docs

Reassigns the "standard" output stream. First, if there is a security manager, its checkPermission method is called with a RuntimePermission("setIO") permission to see if it's ok to reassign the "standard" output stream.

public class  CustomPrintStream extends PrintStream{

 //override  print  methods here 
}

System.setOut(new CustomPrintStream());
Lascar answered 22/6, 2013 at 5:44 Comment(2)
You will have to override all the possible print() and println() implementations in PrintStream and reformat the output as you see fit.Bossuet
@maclema Exactly..I forgot to comment there.Lascar
D
2

It should be possible.

System.out is a printStream.

you can extend the stream to append the date and time to the print methods and use System.setOut() to set the stream appropriately.

As an afterthought if you want to identify where the print statements are coming from you can use: Thread.currentThread().getStackTrace()[1].getClassName();

Dareen answered 22/6, 2013 at 5:44 Comment(0)
A
2

You could use Aspect Oriented Programming to achieve this - in particular the AspectJ tool.

The idea is that you define pointcuts that match at points in your code and then write advice that is executed at those points. The AspectJ compiler will then weave in your advice at those points.

So for your problem you would first define a pointcut that picked up every time you called a print method on a PrintStream

pointcut callPrint(PrintStream ps, String s) : 
              call(* java.io.PrintStream.print*(..)) && target(ps) && args(s);

You would then write advice that would go around this call to replace the argument if the PrintStream is System.out (you could do the same with System.err.

void around(PrintStream ps, String s) : callPrint(ps,s) {
  if(ps.equals(System.out)){
    String new_string = ...
    proceed(new_string);
  }
  else proceed(s);
}

You then need to put this all in an aspect and weave it into your code - there are lots of tutorials online of how to do that.

Alanson answered 22/6, 2013 at 7:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.