Skip to content

Commit 9a34cfd

Browse files
committed
Merge pull request #217 from PaulaRudy/loggingFeature
Logging feature
2 parents 20ec2bf + 811944b commit 9a34cfd

10 files changed

Lines changed: 87 additions & 14 deletions

File tree

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,3 +87,6 @@ bower_components
8787
#Generated files should be ignored as the are regenerated as a build step
8888
*/src/generated
8989
/bin/
90+
91+
#Logging output file
92+
/ui/GRIP.log

core/src/main/java/edu/wpi/grip/core/Main.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
import edu.wpi.grip.generated.CVOperations;
77

88
import java.io.File;
9+
import java.io.IOException;
10+
import java.util.logging.*;
911

1012
/**
1113
* Main driver class for headless mode
@@ -17,6 +19,28 @@ public static void main(String[] args) throws Exception {
1719
return;
1820
}
1921

22+
//Set up the global level logger. This handles IO for all loggers.
23+
Logger globalLogger = LogManager.getLogManager().getLogger("");//This is our global logger
24+
25+
Handler fileHandler = null;//This will be our handler for the global logger
26+
27+
try {
28+
fileHandler = new FileHandler("./GRIP.log");//Log to the file "GRIPlogger.log"
29+
30+
globalLogger.addHandler(fileHandler);//Add the handler to the global logger
31+
32+
fileHandler.setFormatter(new SimpleFormatter());//log in text, not xml
33+
34+
//Set level to handler and logger
35+
fileHandler.setLevel(Level.FINE);
36+
globalLogger.setLevel(Level.FINE);
37+
38+
globalLogger.config("Configuration done.");//Log that we are done setting up the logger
39+
40+
} catch (IOException exception) {//Something happened setting up file IO
41+
throw new IllegalStateException(exception);
42+
}
43+
2044
final String projectPath = args[0];
2145

2246
final EventBus eventBus = new EventBus((exception, context) -> exception.printStackTrace());

core/src/main/java/edu/wpi/grip/core/Step.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
import java.util.NoSuchElementException;
99
import java.util.Optional;
10+
import java.util.logging.Level;
11+
import java.util.logging.Logger;
1012

1113
import static com.google.common.base.Preconditions.checkNotNull;
1214

@@ -16,6 +18,7 @@
1618
*/
1719
@XStreamAlias(value = "grip:Step")
1820
public class Step {
21+
private static final Logger logger = Logger.getLogger(Step.class.getName());
1922
private Operation operation;
2023
private InputSocket<?>[] inputSockets;
2124
private OutputSocket<?>[] outputSockets;
@@ -103,15 +106,15 @@ private synchronized void runPerformIfPossible() {
103106
));
104107
}
105108
} catch (NoSuchElementException e) {
106-
e.printStackTrace();
109+
//TODO: show warning icon
107110
resetOutputSockets();
108111
return; /* Only run the perform method if all of the input sockets are present. */
109112
}
110113

111114
try {
112115
this.operation.perform(inputSockets, outputSockets, data);
113116
} catch (Exception e) {
114-
e.printStackTrace();
117+
logger.log(Level.WARNING, e.getMessage(), e);
115118
resetOutputSockets();
116119
}
117120
}

core/src/main/java/edu/wpi/grip/core/operations/PythonScriptOperation.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,11 @@
1010
import java.net.URL;
1111
import java.util.Optional;
1212
import java.util.List;
13+
import java.util.logging.Level;
14+
import java.util.logging.Logger;
1315
import java.util.Properties;
1416

17+
1518
/**
1619
* A class that implements an operation using Jython. This enables users to write plugins for the application as
1720
* Python scripts. Python script plugins should have global lists of SocketHints called "inputs" and "outputs" that
@@ -53,6 +56,7 @@ public class PythonScriptOperation implements Operation {
5356

5457
private static final String DEFAULT_NAME = "Python Operation";
5558
private static final String DEFAULT_DESCRIPTION = "";
59+
private static final Logger logger = Logger.getLogger(PythonScriptOperation.class.getName());
5660

5761

5862
// Either a URL or a String of literal source code is stored in this field. This allows a PythonScriptOperation to
@@ -215,9 +219,9 @@ public void perform(InputSocket[] inputs, OutputSocket[] outputs) {
215219
/* Exceptions can happen if there's a mistake in a Python script, so just print a stack trace and leave the
216220
* current state of the output sockets alone.
217221
*
218-
* TODO: This method should not throw (since it's an event handler), but it should somehow communicate the
219-
* error to the GUI. */
220-
e.printStackTrace();
222+
* TODO: communicate the error to the GUI.
223+
*/
224+
logger.log(Level.WARNING, e.getMessage(), e);
221225
}
222226
}
223227

core/src/main/java/edu/wpi/grip/core/operations/composite/HSLThresholdOperation.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
import java.util.List;
1111
import java.util.Optional;
12+
import java.util.logging.Level;
13+
import java.util.logging.Logger;
1214

1315
import static org.bytedeco.javacpp.opencv_core.*;
1416
import static org.bytedeco.javacpp.opencv_imgproc.COLOR_BGR2HLS;
@@ -18,6 +20,7 @@
1820
* An {@link edu.wpi.grip.core.Operation} that converts a color image into a binary image based on the HSL threshold ranges
1921
*/
2022
public class HSLThresholdOperation extends ThresholdOperation {
23+
private static final Logger logger = Logger.getLogger(HSLThresholdOperation.class.getName());
2124
private final SocketHint<Mat> inputHint = SocketHints.Inputs.createMatSocketHint("Input", false);
2225
private final SocketHint<List> hueHint = SocketHints.Inputs.createNumberListRangeSocketHint("Hue", 0.0, 180.0);
2326
private final SocketHint<List> saturationHint = SocketHints.Inputs.createNumberListRangeSocketHint("Saturation", 0.0, 255.0);
@@ -84,7 +87,7 @@ public void perform(InputSocket<?>[] inputs, OutputSocket<?>[] outputs, Optional
8487
inRange(hls, low, high, output);
8588
outputSocket.setValue(output);
8689
} catch (RuntimeException e) {
87-
e.printStackTrace(); // TODO: Report OpenCV errors
90+
logger.log(Level.WARNING, e.getMessage(), e);
8891
}
8992
}
9093
}

core/src/main/java/edu/wpi/grip/core/operations/composite/HSVThresholdOperation.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
import java.util.List;
1212
import java.util.Optional;
13+
import java.util.logging.Level;
14+
import java.util.logging.Logger;
1315

1416
import static org.bytedeco.javacpp.opencv_core.inRange;
1517
import static org.bytedeco.javacpp.opencv_imgproc.COLOR_BGR2HSV;
@@ -20,6 +22,7 @@
2022
*/
2123
public class HSVThresholdOperation extends ThresholdOperation {
2224

25+
private static final Logger logger = Logger.getLogger(HSVThresholdOperation.class.getName());
2326
private final SocketHint<Mat> inputHint = SocketHints.Inputs.createMatSocketHint("Input", false);
2427
private final SocketHint<List> hueHint = SocketHints.Inputs.createNumberListRangeSocketHint("Hue", 0.0, 180.0);
2528
private final SocketHint<List> saturationHint = SocketHints.Inputs.createNumberListRangeSocketHint("Saturation", 0.0, 255.0);
@@ -85,7 +88,7 @@ public void perform(InputSocket<?>[] inputs, OutputSocket<?>[] outputs, Optional
8588
inRange(hsv, low, high, output);
8689
outputSocket.setValue(output);
8790
} catch (RuntimeException e) {
88-
e.printStackTrace(); // TODO: Report OpenCV errors
91+
logger.log(Level.WARNING, e.getMessage(), e);
8992
}
9093
}
9194
}

core/src/main/java/edu/wpi/grip/core/operations/composite/RGBThresholdOperation.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55

66
import java.util.List;
77
import java.util.Optional;
8+
import java.util.logging.Level;
9+
import java.util.logging.Logger;
810

911
import static org.bytedeco.javacpp.opencv_core.*;
1012

@@ -13,6 +15,7 @@
1315
*/
1416
public class RGBThresholdOperation extends ThresholdOperation {
1517

18+
private static final Logger logger = Logger.getLogger(RGBThresholdOperation.class.getName());
1619
private final SocketHint<Mat> inputHint = SocketHints.Inputs.createMatSocketHint("Input", false);
1720
private final SocketHint<List> redHint = SocketHints.Inputs.createNumberListRangeSocketHint("Red", 0.0, 255.0);
1821
private final SocketHint<List> greenHint = SocketHints.Inputs.createNumberListRangeSocketHint("Green", 0.0, 255.0);
@@ -84,7 +87,7 @@ public void perform(InputSocket<?>[] inputs, OutputSocket<?>[] outputs, Optional
8487

8588
outputSocket.setValue(output);
8689
} catch (RuntimeException e) {
87-
e.printStackTrace(); // TODO: Report OpenCV errors
90+
logger.log(Level.WARNING, e.getMessage(), e);
8891
}
8992
}
9093
}

core/src/main/java/edu/wpi/grip/core/operations/opencv/MinMaxLoc.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
import org.bytedeco.javacpp.opencv_core.Mat;
1010
import org.bytedeco.javacpp.opencv_core.Point;
1111

12+
import java.util.logging.Level;
13+
import java.util.logging.Logger;
14+
1215
/** Operation to call {@link opencv_core#minMaxLoc} */
1316
public class MinMaxLoc implements CVOperation {
1417

@@ -23,6 +26,7 @@ public class MinMaxLoc implements CVOperation {
2326
private final SocketHint<Point>
2427
minLocOutputHint = SocketHints.Outputs.createPointSocketHint("Min Loc"),
2528
maxLocOutputHint = SocketHints.Outputs.createPointSocketHint("Max Loc");
29+
private static Logger logger = Logger.getLogger(MinMaxLoc.class.getName());
2630

2731
@Override
2832
public String getName() {
@@ -68,8 +72,7 @@ public void perform(InputSocket<?>[] inputs, OutputSocket<?>[] outputs) {
6872
((OutputSocket) outputs[2]).setValue(outputs[2].getValue().get());
6973
((OutputSocket) outputs[3]).setValue(outputs[3].getValue().get());
7074
} catch (final Exception e) {
71-
//TODO Add socket error parsing
72-
e.printStackTrace();
75+
logger.log(Level.WARNING, e.getMessage(), e);
7376
}
7477
}
7578
}

core/src/main/java/edu/wpi/grip/core/sources/CameraSource.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
import java.util.Properties;
1919
import java.util.concurrent.TimeUnit;
2020
import java.util.concurrent.TimeoutException;
21+
import java.util.logging.Level;
22+
import java.util.logging.Logger;
2123

2224
import static com.google.common.base.Preconditions.checkNotNull;
2325

@@ -29,6 +31,7 @@ public final class CameraSource extends Source implements StartStoppable {
2931

3032
private final static String DEVICE_NUMBER_PROPERTY = "deviceNumber";
3133
private final static String ADDRESS_PROPERTY = "address";
34+
private static Logger logger = Logger.getLogger(CameraSource.class.getName());
3235

3336
private EventBus eventBus;
3437
private String name;
@@ -207,9 +210,7 @@ public final void stop() throws TimeoutException, IllegalStateException {
207210
frameThread = Optional.empty();
208211
} catch (InterruptedException e) {
209212
Thread.currentThread().interrupt();
210-
//TODO: Move this into a logging framework
211-
System.err.println("Caught Exception:");
212-
e.printStackTrace();
213+
logger.log(Level.WARNING, e.getMessage(), e);
213214
} finally {
214215
// This will always run even if a timeout exception occurs
215216
try {

ui/src/main/java/edu/wpi/grip/ui/Main.java

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
import javafx.scene.image.Image;
1212
import javafx.stage.Stage;
1313

14+
import java.io.IOException;
15+
import java.util.logging.*;
16+
1417
public class Main extends Application {
1518
private final EventBus eventBus = new EventBus((exception, context) -> {
1619
this.triggerUnexpectedThrowableEvent(new UnexpectedThrowableEvent(exception, "An Event Bus subscriber threw an uncaught exception"));
@@ -25,6 +28,29 @@ public static void main(String[] args) {
2528

2629
@Override
2730
public void start(Stage stage) {
31+
32+
//Set up the global level logger. This handles IO for all loggers.
33+
Logger globalLogger = LogManager.getLogManager().getLogger("");//This is our global logger
34+
35+
Handler fileHandler = null;//This will be our handler for the global logger
36+
37+
try {
38+
fileHandler = new FileHandler("./GRIP.log");//Log to the file "GRIPlogger.log"
39+
40+
globalLogger.addHandler(fileHandler);//Add the handler to the global logger
41+
42+
fileHandler.setFormatter(new SimpleFormatter());//log in text, not xml
43+
44+
//Set level to handler and logger
45+
fileHandler.setLevel(Level.FINE);
46+
globalLogger.setLevel(Level.FINE);
47+
48+
globalLogger.config("Configuration done.");//Log that we are done setting up the logger
49+
50+
} catch (IOException exception) {//Something happened setting up file IO
51+
throw new IllegalStateException(exception);
52+
}
53+
2854
this.eventBus.register(this);
2955
this.root = new MainWindowView(eventBus);
3056
/**
@@ -66,7 +92,7 @@ public final void onUnexpectedThrowableEvent(UnexpectedThrowableEvent event) {
6692
}
6793
});
6894

69-
if(event.isFatal()) {
95+
if (event.isFatal()) {
7096
System.err.println("Original fatal exception");
7197
event.getThrowable().printStackTrace();
7298
System.exit(1);

0 commit comments

Comments
 (0)