heartbeat log, json age

This commit is contained in:
rusefi 2020-07-25 00:30:31 -04:00
parent 977a0d2ea4
commit ebdd6eeb19
6 changed files with 93 additions and 3 deletions

View File

@ -10,6 +10,7 @@ public class ApplicationConnectionState {
@NotNull
private final IoStream clientStream;
private final ControllerConnectionState state;
private final Birthday birthday = new Birthday();
public ApplicationConnectionState(UserDetails userDetails, IoStream clientStream, ControllerConnectionState state) {
this.userDetails = Objects.requireNonNull(userDetails, "userDetails");
@ -31,6 +32,10 @@ public class ApplicationConnectionState {
return userDetails;
}
public Birthday getBirthday() {
return birthday;
}
public void close() {
try {
clientStream.close();

View File

@ -34,8 +34,10 @@ import static com.devexperts.logging.Logging.getLogging;
import static com.rusefi.Timeouts.SECOND;
/**
* See NetworkConnectorStartup
* See NetworkConnectorStartup - NetworkConnector connects an ECU to this backend
*
* @see ControllerConnectionState ECU session
* @see ApplicationConnectionState tuning application session
* @see BackendLauncher
*/
public class Backend implements Closeable {
@ -51,6 +53,7 @@ public class Backend implements Closeable {
* @see BinaryProtocolProxy#USER_IO_TIMEOUT
*/
private static final int APPLICATION_INACTIVITY_TIMEOUT = 3 * Timeouts.MINUTE;
static final String AGE = "age";
private final FkRegex showOnlineControllers = new FkRegex(ProxyClient.LIST_CONTROLLERS_PATH,
(Take) req -> getControllersOnline()
@ -261,6 +264,7 @@ public class Backend implements Closeable {
JsonObject applicationObject = Json.createObjectBuilder()
.add(UserDetails.USER_ID, application.getUserDetails().getUserId())
.add(UserDetails.USERNAME, application.getUserDetails().getUserName())
.add(AGE, application.getBirthday().getDuration())
.add(MAX_PACKET_GAP, application.getClientStream().getStreamStats().getMaxPacketGap())
.build();
builder.add(applicationObject);
@ -281,6 +285,7 @@ public class Backend implements Closeable {
JsonObjectBuilder objectBuilder = Json.createObjectBuilder()
.add(UserDetails.USER_ID, client.getUserDetails().getUserId())
.add(UserDetails.USERNAME, client.getUserDetails().getUserName())
.add(AGE, client.getBirthday().getDuration())
.add(ProxyClient.IS_USED, client.getTwoKindSemaphore().isUsed())
.add(ControllerStateDetails.RPM, rpm)
.add(ControllerStateDetails.CLT, clt)
@ -351,6 +356,10 @@ public class Backend implements Closeable {
isClosed = true;
}
public boolean isClosed() {
return isClosed;
}
public List<ControllerConnectionState> getControllers() {
synchronized (lock) {
return new ArrayList<>(controllers);

View File

@ -0,0 +1,26 @@
package com.rusefi.server;
import org.jetbrains.annotations.NotNull;
import java.time.Duration;
public class Birthday {
private final long createAt = System.currentTimeMillis();
public String getDuration() {
return humanReadableFormat(System.currentTimeMillis() - createAt);
}
@NotNull
static String humanReadableFormat(long millis) {
return humanReadableFormat(Duration.ofMillis(millis));
}
@NotNull
static String humanReadableFormat(Duration duration) {
return duration.toString()
.substring(2)
.replaceAll("(\\d[HMS])(?!$)", "$1 ")
.toLowerCase();
}
}

View File

@ -36,6 +36,7 @@ public class ControllerConnectionState {
private final TwoKindSemaphore twoKindSemaphore = new TwoKindSemaphore();
private final SensorsHolder sensorsHolder = new SensorsHolder();
private final Birthday birthday = new Birthday();
public ControllerConnectionState(Socket clientSocket, UserDetailsResolver userDetailsResolver) {
this.clientSocket = clientSocket;
@ -48,6 +49,10 @@ public class ControllerConnectionState {
}
}
public Birthday getBirthday() {
return birthday;
}
public IoStream getStream() {
return stream;
}

View File

@ -1,5 +1,6 @@
package com.rusefi.server;
import com.devexperts.logging.Logging;
import com.rusefi.rusEFIVersion;
import com.rusefi.tools.online.ProxyClient;
import org.takes.Take;
@ -13,15 +14,22 @@ import java.lang.management.ManagementFactory;
import java.lang.management.OperatingSystemMXBean;
import java.util.Date;
import static com.rusefi.Timeouts.SECOND;
import static com.rusefi.binaryprotocol.BinaryProtocol.sleep;
public class Monitoring {
public static final String STATUS = "/status";
private static final Logging log = Logging.getLogging(Monitoring.class);
private static final int PERIOD = 10 * SECOND;
final FkRegex showStatistics;
private final Backend backend;
private final Birthday birthday = new Birthday();
public Monitoring(Backend backend) {
this.backend = backend;
showStatistics = new FkRegex(STATUS,
(Take) req -> getStatus());
showStatistics = new FkRegex(STATUS, (Take) req -> getStatus());
startHeartbeatThread();
}
private static String formatSize(long v) {
@ -30,6 +38,26 @@ public class Monitoring {
return String.format("%.1f %sB", (double) v / (1L << (z * 10)), " KMGTPE".charAt(z));
}
public void startHeartbeatThread() {
new Thread(new Runnable() {
@Override
public void run() {
while (!backend.isClosed()) {
writeLogEntry();
sleep(PERIOD);
}
}
}, "heartbeat").start();
}
private void writeLogEntry() {
OperatingSystemMXBean operatingSystemMXBean = ManagementFactory.getOperatingSystemMXBean();
log.info("cpu=" + operatingSystemMXBean.getSystemLoadAverage() +
",free=" + Runtime.getRuntime().freeMemory() +
",sessions=" + Backend.totalSessions.get() +
",threads=" + Thread.getAllStackTraces().size());
}
private RsJson getStatus() throws IOException {
JsonObjectBuilder builder = Json.createObjectBuilder();
OperatingSystemMXBean operatingSystemMXBean = ManagementFactory.getOperatingSystemMXBean();
@ -46,6 +74,7 @@ public class Monitoring {
builder.add("framework version", rusEFIVersion.CONSOLE_VERSION);
builder.add("compiled", new Date(rusEFIVersion.classBuildTimeMillis()).toString());
builder.add("now", System.currentTimeMillis());
builder.add(Backend.AGE, birthday.getDuration());
return new RsJson(builder.build());
}

View File

@ -0,0 +1,16 @@
package com.rusefi.server;
import org.junit.Test;
import static com.rusefi.Timeouts.MINUTE;
import static com.rusefi.Timeouts.SECOND;
import static com.rusefi.server.Birthday.humanReadableFormat;
import static org.junit.Assert.assertEquals;
public class BirthdayTest {
@Test
public void testDurationString() {
assertEquals("1s", humanReadableFormat(SECOND));
assertEquals("1m", humanReadableFormat(MINUTE));
}
}