Newer
Older

Radek Ošlejšek
committed
package cz.fidentis.analyst;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.io.PrintStream;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.util.logging.Level;
/**
* A logging class that can be used from anywhere to display debugging or other
* messages.
* <p>
* Messages are printed into the system standard output by default. But can be also
* redirected to system error output or into the pipe.

Radek Ošlejšek
committed
* </p>
* <p>
* If the messages are redirected into pipe, then <b>a consumer has to be running
* concurrently</b> and reading the data through the {@link #read()} method.
* <b>Otherwise, the program can freeze due to the full buffer!</b>

Radek Ošlejšek
committed
* </p>
* <p>
* FIDENTIS application automatically redirects logged messages to the output window
* via the {@code OutputWindowThread}.

Radek Ošlejšek
committed
* </p>
* <p>
* <b>Usage:</b>
* <ul>
* <li>To print a message, use {@code Logger.print("message")}. A timestamp is added automatically.</li>
* <li>To print message together with duration, call {@code Logger log = Logger.measureTime();},
* then call the measured operations and finally call {@code log.printDuration("message")}.
* a timestamp and measured duration are added to the log message automatically.</li>
* </ul>
* </p>
*
* @author Radek Oslejsek
*/
public final class Logger {
private static final int PIPE_SIZE = 10240; // default is 1024

Radek Ošlejšek
committed
private static PrintStream out = System.out;
private static BufferedReader in;
private long lastTime = System.currentTimeMillis();
private Logger() {
}
/**
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
* Redirects messages into a pipe.
* <b>A consumer has to be running concurrently</b> and reading the messages
* through the {@link #read()} method.
* Otherwise, the program can freeze due to the full buffer!
*/
public static synchronized void redirectToPipe() {
if (in != null) {
return;
}
PipedOutputStream pOut = new PipedOutputStream();
out = new PrintStream(pOut);
try {
in = new BufferedReader(new InputStreamReader(new PipedInputStream(pOut, PIPE_SIZE)));
} catch (IOException ex) {
java.util.logging.Logger.getLogger(Logger.class.getName()).log(Level.SEVERE, null, ex);
}
}
/**
* Redirects messages into the system standard output.
*/
public static synchronized void redirectToStdOut() {
out = System.out;
in = null;
}
/**
* Redirects messages into the system error output.
*/
public static synchronized void redirectToStdErr() {
out = System.err;
in = null;
}
/**
* Returns an event message. If the logger is redirected to standard or error output,
* then {@code null} is returned. Also, if the is no message, {@code null} is returned.

Radek Ošlejšek
committed
*
* @return Event message or {@code null}
* @throws IOException on error in reading the message buffer.

Radek Ošlejšek
committed
*/
public static String read() throws IOException {
if (in == null/* || !in.ready()*/) {
return null;

Radek Ošlejšek
committed
}
return in.readLine();

Radek Ošlejšek
committed
}
/**
* Prints a message. The log time added automatically.
*
* @param msg Message to be logged
*/
public static void print(String msg) {
String outMsg =
new SimpleDateFormat("HH:mm:ss").format(System.currentTimeMillis())
+ " [duration unknown]: "
+ msg.trim();
out.println(outMsg);

Radek Ošlejšek
committed
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
}
/**
* Starts measuring of some operation.
* Call {@link #printDuration(java.lang.String)} on returned object
* to print the measured duration.
*
* @return An object used to print measured duration and message
*/
public static Logger measureTime() {
Logger ret = new Logger();
ret.lastTime = System.currentTimeMillis();
return ret;
}
/**
* Prints the message about an operation and the duration of the operation.
* The duration is computed as the difference between current system time and
* the time of calling {@link #measureTime()}. The time difference is measured in
* milliseconds and printed as [+mm:ss.SSS] where mm=minutes, ss=seconds,
* and SSS=milliseconds.
*
* @param msg Message to be printed
*/
public void printDuration(String msg) {
Duration duration = Duration.ofMillis(System.currentTimeMillis() - lastTime);
String outMsg =
new SimpleDateFormat("HH:mm:ss").format(System.currentTimeMillis())
+ " [duration "
+ String.format(
"%02d:%02d.%03d",
duration.toMinutes(),
duration.toSecondsPart(),
duration.toMillisPart())
+ "]: "
+ msg.trim();

Radek Ošlejšek
committed
out.println(outMsg);