Skip to content

Instantly share code, notes, and snippets.

@ivarref
Created April 3, 2024 07:00
Show Gist options
  • Save ivarref/c76a34f734e78496c423c312330d330c to your computer and use it in GitHub Desktop.
Save ivarref/c76a34f734e78496c423c312330d330c to your computer and use it in GitHub Desktop.
TrayMonitor.java
package no.nsd;
import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
import java.net.ConnectException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.http.HttpTimeoutException;
import java.time.Duration;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Base64;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
import javax.swing.*;
public class TrayMonitor {
private static volatile TrayIcon trayIcon;
public static void debug(String... args) {
StringBuilder sb = new StringBuilder();
sb.append(pattern.format(ZonedDateTime.now()));
sb.append(" DEBUG ");
for (String s : args) {
sb.append(s);
sb.append(" ");
}
sb.deleteCharAt(sb.length() - 1);
//sout(sb.toString());
}
public static void info(String... args) {
StringBuilder sb = new StringBuilder();
sb.append(pattern.format(ZonedDateTime.now()));
sb.append(" INFO ");
for (String s : args) {
sb.append(s);
sb.append(" ");
}
sb.deleteCharAt(sb.length() - 1);
sout(sb.toString());
}
public static void warn(String... args) {
StringBuilder sb = new StringBuilder();
sb.append(pattern.format(ZonedDateTime.now()));
sb.append(" WARN ");
for (String s : args) {
sb.append(s);
sb.append(" ");
}
sb.deleteCharAt(sb.length() - 1);
sout(sb.toString());
}
public static void error(String... args) {
StringBuilder sb = new StringBuilder();
sb.append(pattern.format(ZonedDateTime.now()));
sb.append(" ERROR ");
for (String s : args) {
sb.append(s);
sb.append(" ");
}
sb.deleteCharAt(sb.length() - 1);
sout(sb.toString());
}
public static final Base64.Decoder decoder = Base64.getDecoder();
public static byte[] decode(String b64) {
return decoder.decode(b64);
}
public static final String redCircle = "iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAABmJLR0QA/wD/AP+gvaeTAAAHrklEQVRoge1Zy24cxxU99eie7mlyZkiIkoh4k0W8MII4ASxRjKgYTgDL+ggjBLINEMBLw4GQ2D+QVZYKko9wHCCxIkRQJIeJso12tkGBkUQOyel31a0suqpZHHGGQ5qxN7xAY7qrq6vOuXXrPmqAczmXczmXb1LYWQ3075s3b+g8X6e6vkJEy9C6B8YkABhjFBNij3P+lAvxKJyfv/Pdjz++fxbzfiUCT27d6uxl2Ycqy97lnF+Oul0EUQQZBBCcA5w3HYmgiaDqGnVRoMgyGKKnQbf7h++PRh+wjY36ayfweG3tvTLPb4dx3Ov2euhEEWSngyAIwIUA4xyMNcMbY2CIQFqjrmuoskRZFMj29lDl+W6UJLdfv3fvN18LgS9u3lzc3N7+RArxRrKwgDhJEMUxZBCACQEuRKN9xg4RgDHQloTRGqquUeQ58jRFurMDpfVnF5Pk7W/fvTv8vxF4vLb2ap6m95P5+QtzgwGiuTmEYQgZBOBSgnMO7syG83ZwAwBEaH6ouZSCqmtUVYViNMJoOEQ6Gj3rz81df+3evSdnTuDx2tqrRZo+mh8M+slggDhJEFjwTIgGPGOA1bp/D2NAxhy6J6J2JeqqalZiOMT+cLjbC8Mrrz18OBMJPkunL1ZXF/P9/ftz/X4/6ffR9cBzziEYO9CEMWDGtGYDe8/cs9WaYAycc8ggQBCG6CYJkn4fc/1+f1iW95+srPRmwSZnIpDnnyRJcqHb6yHudpuNKmWjZXgmwg4W1BhzaAUYYzBHvOOMQUgJZgzibhdEBF1VSy+y7E8Arh2H7dgV+MfKyi8CId7o9nqI47iZjHNwp2UiMKJG63aDElHrdUjr5t6ajNEazBgwIoAIxhhwY8A4h5AScRyj2+tBCLHyz6tX3zsO39Q98OTWrc7zzz//b+/ixV5vMEDU7TY+XojGw1jTYYw1pgI0mnUadnY/1sZsm3HfWGVo552yDHvDIXafP99dDcOlaXFi6grsbG19FMRxL4oiBNZkuLNrp0GrZad1o1SraePa3LNS7Wo4dwrbB3YlOGMIpEQURQg7nf4G8KtpGKcSqIvi3ShJ0AlDcM8twpoMHAAHzgF1z/41/s5+C2tSzs0yAJxzdMIQUZKgzPP1UxF4ePXqDc75pdD5dwDMapg8YKQUTF03wOr6ZeDjl9f3pXGUAiMCtyRCKcGFWN5YWZm4mSd6IZNl651OB1LKxs4tAXAOEIFsm2k/MJOGOlp8j+W1MaJ2PiklOmGIOk3XAfz9RARIqStyfr5JC4AGtLcxmd2AZhJwNuYfJvRr0w3P5bq+gnPIMESWpquTcE4mYMyysAkZd5vWC1iHwI+D88Ec9ez1Mx4Jf1xuY4fgHIxo+cQEDFGP20ldNsnthMYu85HmMwXsxL52LGYdBXmRnDeEJkbliQSYLUZ8D2Gcv/dTBd/fO1DTzOqIvsbFFHfvAuTBCgYnJmA8zYOo0bx7Z/32WRGAJWDsfnOpibGReuI+m0YAWitoHbqUwEXQ1oTsoC6SHgI13jap3d9TjIHsHAS0gRFaA1pPjMTTkrk9rfUF0rrVlEZjUgwHRcpLBI4CexwpW/wY5+mAxutpDd0ob+/EBAzRplLqAikFbe2TufzFc3XOvF6SGdwoAw7MxtUPdg7tih6lYIzZPDkBYz6ry/J7dRRBCNFER3gmYze27TtpmKnCGGtMBGgCpDUpAqCJUNc16rIEmxDEphIIpbxTluXPVF2DggAtXKt9BruZbdtJKTAcBC/GeZMbMdbsBQBkM9OyLCGBO9PGmSh3X3nlaW9h4fJ8kiCwxbqLDX61BX8/zAjemQvzTAcWvCZCrTX20xT7Ozubb3755bcmjTU1G+XA74ssQ1lV0DZlbgsUly57abPLLs2Eq81e/TR7bEwigtYaZVWhyDLAmInaP5bAjUuXPqiKYrcsS9RKNSS8QEYuHowBgkfGgT6yjyvu3Xi2qKmVQtmcHQ1/dPny6esBtrFRB0r9Mh+NUBYFtCMxBrw1oTHtuiOUQ8XNWH+fiNYaWimURYF8NIIA3j/u1G6mY5U/Ly09SubnryRJgigMIa3tHkozXF0MHJxKjBf11ssYxsC88yNjXacyBkVVIU1T5Gn64K2trR8eh22mU4nFun57J03/wxlbgjEIgwACzYkC845R/PrW146fufq5jnHBywbJqq6R5znS0WgrUeqdWbDNdC70g+FwKIiuj/b2drMsQ1GWUFo3wcbabhsf3Cp4z23m6r1332kiKK1RlCWyLMP+/v4ugOvXtrcnRl9fTnS0+Nelpe8o4G9xHF+M4xihlJCMNSvhTiicScErVtxJBJrI61aErNlUSiHPc2RZthUwduPNZ8/O/mjRyb8Gg8E2538MomglsiRCIQ5IuBx+rPhhxoBsuwNfaY1KKRR5jqooHswB78yq+VMTcPLpwsLPNecfdaKo3+l0EHAOYa92Nfzjdfur7X8FNVHrKhnR+z/Z2fntaXB8pT84DBD8pd//NXH+UxmGy6GUkFK2EbtNFaz2NRGUUqiUgq6qTUn0O7O7e/stQJ0Ww5n9xfTp4uI1U1XrJMQqY2zZMNZnUjZejqiG1nvGmKdc6wfodO78+MWLh2c197mcy7mcyzcn/wN5Pwx0yKEqhgAAAABJRU5ErkJggg==";
public static final String pray = "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";
public static Image getImage(String base64) {
return (new ImageIcon(decode(base64))).getImage();
}
public static final Image unhealthy = getImage(redCircle);
public static final Image healthy = getImage(pray);
public static final Image catHeartEyes = getImage("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");
public static final Image drool = getImage("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");
public static final Image sleepy = getImage("iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAABmJLR0QA/wD/AP+gvaeTAAAFZklEQVRoge2ZW0wUVxjHf2eWBYFeZEHLzbamARFtSQPa0lsimLZoTG0falIw9aEVCJTExIe+WNuk0TSttYmuiCYmRk3aah+0YhNNaJoqRAqJtmIFxFRcWIOAlwo6u935+sBF2Psut33gS05m5syc+X7/+b4zM+ccmLWZNTXTAMFYQ2lXH2AZX6t+za9JLdBmhCh0Ey9Vc2GSIiCCiassB1aIIheDLCAF4bFh1/cRuoFWZdCMoo7FNCqFEYqfho/tRWhGLeAwDHn51f3pFyYkQK6ywFBUKKEESEN49Kzc9z3rbAKHNRdWlYMtkK9zZTfna+L6E3hKRG16ZV/qdxBmBKSdeYaJL5WwASHaK7B/+LF1DhEOaE62qDx6vfpDVEOp/WeFrBY4nV+T+rZCSVgCpIMPBHYBFp9wwcOP7nfWb3lw1/Z6/UBvdgeAEurz96UfBGgos21C1LcobpkNZ07evmftIzxBC5AmzIaFPUr4yC9cGPAInK/ucnfZl1+TlnSu7OZSTVx/AHPQeCe/Ou3E2IuCegtJN3GSwPGpggfIeHMjaXk7GM4MtKh/vwYwiesQMAcAg+MNpV3SUNo1mmoBBUgTZnnAMaBoquARsCw8xUDPiyCKJ9N/Y9mGxSulhWhB3fbHFzCFXNfYP5VPfmRrv7iRzoatmGP7eP69lZhjexDYa1pGuT8+vxGQDoqnA36wLwtb46cALHxjM+bYHgCUUCaNrPPH6DMCYiNRdK4ASVMJj8Cln04z0Ltk1HdUzG1yS5aOXN+voljk6xXrMwKGg23TAY+AKfquJ4CMFovh5AtfnF4jIO2ki0YHE/9IhXdePOocyiBDvUanO6vXCBgalREED0K0gffO7BEBETTp4DqQHiHwI8ddqptn1Pu4xvJ6RuAqL0UgPAhpJJPrjusthVZEIPxIKXCHjXKvECHv0UHkwKuhbVARyIxI+CFbFIyAFH8gFV9lsv6zbAYfmsY5G3hgonhrNpU7Mn0CV+zMZP02t7YCAw9NFG/PptLq2VaNP04JLODRMNAriO7QaL0eR9U3GVy+Fo/u1Gi5Fk/VjgzabXHoTs0rPAK6U6P1RhxVuzK4/E88ukOj5Xo8VdYM2rvj0B3j2yp3/8Lj7rger1HjCjoQ7espdvfGUL49E3tfjIf21CSd6s1tpFh0r+K7e2Mo35mJvd9LW4tOdWUbKQm6L3gQdFU4/GvtR0AfMjyF4SOV7t2P4tAvydQ1J9DTb2Z+goPC3DuUvGXniTiX35y/NxDFoTPJ1F1IoOeOmflzHRTm3KGkwM4TsS5/8AC9qpB5/gX8zSVgyYx3WO9t/lIreWEsr7dO3Bah8GDQ6g7rIUAZNEUk/NB+U0ABKOoiEl4AbZjNr4DFNCLciDh46OQszQEFKIUhcCTC4EE4oj73nIr0Oh7QXFgRHBEEr+PA6o3V42cOQOVgc13kgIKycOCdTkVNbRqnGhNRClbl9bGxqAuzScKBB2G/WoPHzBf4G9S3YBEnrQQ7Lh5TrCfSOXgmedz9Piy8ScVqWzjwfTjJUmtCHNSrJfQrxSfhpE3t+USP+51sTAwHHoRyX/B+BQCoHL4XoSbUnE9P0j3u9fQ8PRx4qyriqF9GfycB5EdM8hzHgLXT1GFHSi1zWKtW8N+EBABIE3ECRxFWTQu8wUlcrFNrGAzEFtTstMpjUMFagb3T8OStxPJuMPAQzgJHI+vEYDdC0iTD30KoCJTz7hbyKqVazg9KkSWwB0GfBHgdYTeQFSo8THCVUupJMwwqFRQjLAgR/gbCYRxYfX2kgrHJWmbV+J08hAKGpj4WAWkY45ZZbRi0AU1o1HGWZm//NrM2a7MWmv0PblydmGDHmGkAAAAASUVORK5CYII=");
public static final Image scream = getImage("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");
public static final Image nauseous = getImage("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");
public static final AtomicBoolean running = new AtomicBoolean(true);
public static void setImage(Image img) {
if (trayIcon == null) {
warn("TrayIcon not ready.");
} else if (trayIcon.getImage() == img) {
debug("doing nothing.");
} else {
trayIcon.setImage(img);
}
}
public static void main(String[] args) {
info("TrayMonitor starting");
UIManager.put("swing.boldMetal", Boolean.FALSE);
SwingUtilities.invokeLater(TrayMonitor::createAndShowGUI);
ScheduledExecutorService pool = Executors.newScheduledThreadPool(1);
AtomicLong count = new AtomicLong(0);
AtomicLong errorCount = new AtomicLong(0);
pool.scheduleAtFixedRate(() -> {
if (running.get()) {
long startTime = System.currentTimeMillis();
boolean res = checkOnce(args);
long spentTime = System.currentTimeMillis() - startTime;
long cnt = count.incrementAndGet();
if (res) {
errorCount.set(0);
info("All", "" + args.length, "services healthy in", "" + spentTime, "ms. Check count:", "" + cnt);
if (cnt == 1) {
setImage(catHeartEyes);
}
else if (cnt % 100 == 0) {
setImage(catHeartEyes);
} else if (cnt % 10 == 0) {
setImage(drool);
} else {
setImage(healthy);
}
} else {
long errCount = errorCount.incrementAndGet();
warn("Some services unhealthy in", "" + spentTime, "ms. Error count:", ""+errCount);
if (errCount >= 5) {
setImage(scream);
}
else if (errCount >= 3) {
setImage(unhealthy);
} else {
setImage(nauseous);
}
}
}
}
, 0, 1, TimeUnit.MINUTES);
}
public static final DateTimeFormatter pattern = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
public synchronized static void sout(String txt) {
System.out.println(txt);
}
public static final HttpClient client = HttpClient.newHttpClient();
public static boolean checkOnce(String[] args) {
for (String s : args) {
URI uri = null;
try {
uri = new URI(s);
} catch (URISyntaxException e) {
error("Bad URI syntax. Got:", s);
System.exit(1);
}
HttpRequest request = HttpRequest.newBuilder()
.uri(uri)
.timeout(Duration.ofSeconds(3))
.GET()
.build();
try {
long startTime = System.currentTimeMillis();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
long spentTime = System.currentTimeMillis() - startTime;
String contentType = response.headers().firstValue("Content-Type").orElse("none");
boolean textPlain = contentType.startsWith("text/plain");
if (200 == response.statusCode() && (!textPlain || response.body().equalsIgnoreCase("OK"))) {
debug("Checking", s, "=> OK in", "" + spentTime, "ms");
} else {
warn("Checking", s, "returned", "HTTP " + response.statusCode(), "Body:", response.body(), "in", "" + spentTime, "ms");
return false;
}
} catch (IOException e) {
if (e instanceof ConnectException) {
error("Could not connect to", s);
} else if (e instanceof HttpTimeoutException) {
error("Request to", s, "timed out.");
} else {
error("Error while checking", s, ". Error message:", e.getMessage(), ". Class: " + e.getClass());
}
return false;
} catch (InterruptedException e) {
warn("Interrupted");
return false;
}
}
return true;
}
private static void createAndShowGUI() {
//Check the SystemTray support
if (!SystemTray.isSupported()) {
error("SystemTray is not supported");
System.exit(1);
return;
}
final PopupMenu popup = new PopupMenu();
trayIcon = new TrayIcon(sleepy);
trayIcon.setImageAutoSize(true);
final SystemTray tray = SystemTray.getSystemTray();
// Create a popup menu components
MenuItem aboutItem = new MenuItem("About");
CheckboxMenuItem cb1 = new CheckboxMenuItem("Set auto size");
CheckboxMenuItem cb2 = new CheckboxMenuItem("Set tooltip");
Menu displayMenu = new Menu("Display");
MenuItem errorItem = new MenuItem("Error");
MenuItem warningItem = new MenuItem("Warning");
MenuItem infoItem = new MenuItem("Info");
MenuItem noneItem = new MenuItem("None");
MenuItem exitItem = new MenuItem("Exit");
//Add components to popup menu
popup.add(aboutItem);
popup.addSeparator();
popup.add(cb1);
popup.add(cb2);
popup.addSeparator();
popup.add(displayMenu);
displayMenu.add(errorItem);
displayMenu.add(warningItem);
displayMenu.add(infoItem);
displayMenu.add(noneItem);
popup.add(exitItem);
trayIcon.setPopupMenu(popup);
try {
tray.add(trayIcon);
} catch (AWTException e) {
error("TrayIcon could not be added.");
System.exit(1);
return;
}
trayIcon.addActionListener(e -> JOptionPane.showMessageDialog(null,
"This dialog box is run from System Tray"));
aboutItem.addActionListener(e -> JOptionPane.showMessageDialog(null,
"This dialog box is run from the About menu item"));
cb1.addItemListener(e -> {
int cb1Id = e.getStateChange();
if (cb1Id == ItemEvent.SELECTED) {
trayIcon.setImageAutoSize(true);
} else {
trayIcon.setImageAutoSize(false);
}
});
trayIcon.setToolTip("mjau...");
cb2.addItemListener(e -> {
int cb2Id = e.getStateChange();
if (cb2Id == ItemEvent.SELECTED) {
trayIcon.setToolTip("Sun TrayIcon");
} else {
trayIcon.setToolTip(null);
}
});
ActionListener listener = e -> {
MenuItem item = (MenuItem) e.getSource();
//TrayIcon.MessageType type = null;
if ("Error".equals(item.getLabel())) {
//type = TrayIcon.MessageType.ERROR;
trayIcon.displayMessage("Sun TrayIcon Demo",
"This is an error message", TrayIcon.MessageType.ERROR);
} else if ("Warning".equals(item.getLabel())) {
//type = TrayIcon.MessageType.WARNING;
trayIcon.displayMessage("Sun TrayIcon Demo",
"This is a warning message", TrayIcon.MessageType.WARNING);
} else if ("Info".equals(item.getLabel())) {
//type = TrayIcon.MessageType.INFO;
trayIcon.displayMessage("Sun TrayIcon Demo",
"This is an info message", TrayIcon.MessageType.INFO);
} else if ("None".equals(item.getLabel())) {
//type = TrayIcon.MessageType.NONE;
trayIcon.displayMessage("Sun TrayIcon Demo",
"This is an ordinary message", TrayIcon.MessageType.NONE);
}
};
errorItem.addActionListener(listener);
warningItem.addActionListener(listener);
infoItem.addActionListener(listener);
noneItem.addActionListener(listener);
exitItem.addActionListener(e -> {
tray.remove(trayIcon);
info("Exiting");
System.exit(0);
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment