This might be a very dumb question but, is there a way to fire a trigger whenever something is printed to the console in Java and listen for it somewhere else?
I have very little understanding of triggers or of the System class (or of Logger for that matter) so if there is an easier way of doing this (without triggers) please tell me so.
We are trying to use Logger to log all of our tests. Currently, we have been using the simple "System.out.println" to log everything in the console, so I was wondering whether I could fire a trigger whenever something in printed to it and then have a listener add that info to Logger.
Thanks.
The most direct way to do this would be
System.setOut(new PrintStream(System.out) {
public void println(String s) {
logger.log(s);
super.println(s);
}
// override some other methods?
});
Aspect-Oriented Programming (AOP) can help you implement this behaviour.
Since you are working on Java, you can use AspectJ (one of the most mature AOP languages) to capture all the calls to System.out.println()
and 'inject' your behaviour of notifying the Logger class.
Here is some sample code in AspectJ of how that would work:
pointcut somethingIsBeingLogged(): execution(public static * System.out.println());
before() : somethingIsBeingLogged() {
// Get the context by joinPoint.getThis();
// Notify the Logger class
}
You can actually stop the calls to System.out.println()
and let only your Logger class take control. I can provide more details if you would like to take the AOP path.
This is just a nice singleton wrapper around Louis Wasserman's excellent answer. My code is free to use by anyone who wishes to use it. Using it you can get the console output anywhere in a fairly simple way.
public class SystemOutListener {
private static SystemOutListener singleton;
public static SystemOutListener GetSingleton() {
if (singleton == null) {
singleton = new SystemOutListener();
singleton.ReplaceStandartSystemOutPrintStream();
}
return singleton;
}
private ArrayList<ISystemOutObserver> observersList = new ArrayList<>();
public void AttachSystemOutObserver(ISystemOutObserver observer) {
observersList.add(observer);
}
public void RemoveSystemOutObserver(ISystemOutObserver observer) {
observersList.remove(observer);
}
private void FireSystemOutPrintln(String message) {
for (int i = 0; i < observersList.size(); i++) {
java.awt.EventQueue.invokeLater(new HandleSystemOutRunner(observersList.get(i), message));
}
}
private void ReplaceStandartSystemOutPrintStream() {
System.setOut(new PrintStream(System.out) {
@Override
public void println(String s) {
super.println(s);
FireSystemOutPrintln(s);
}
});
}
public interface ISystemOutObserver {
public void HandleSystemOut(String message);
}
private class HandleSystemOutRunner implements Runnable {
private String message;
private ISystemOutObserver target;
public HandleSystemOutRunner(ISystemOutObserver target, String message) {
this.message = message;
this.target = target;
}
@Override
public void run() {
target.HandleSystemOut(message);
}
}
}
Usage:
SystemOutListener.GetSingleton().AttachSystemOutObserver(/*YOUR OBSERVER*/)
Lambdas(Java 8) can be used in place of the observer, too!
Probably a thousand miles from what you need, but you could use something like "watch" under linux looking for specific text. If you were to log out to a file you could set "watch" to monitor the file for certain texts and issue instructions accordingly.