cleanup metrics websocket

This commit is contained in:
Lee 2024-04-20 14:17:17 +01:00
parent cf8e27f039
commit ab3ed0511f
8 changed files with 119 additions and 53 deletions

@ -1,22 +0,0 @@
package xyz.mcutils.backend.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
import xyz.mcutils.backend.service.MetricService;
import xyz.mcutils.backend.websocket.MetricsWebSocketHandler;
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
@Autowired
private MetricService metricService;
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(new MetricsWebSocketHandler(metricService), "/websocket/metrics").setAllowedOrigins("*");
}
}

@ -3,9 +3,9 @@ package xyz.mcutils.backend.service;
import lombok.extern.log4j.Log4j2; import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import xyz.mcutils.backend.common.AppConfig;
import xyz.mcutils.backend.common.DNSUtils; import xyz.mcutils.backend.common.DNSUtils;
import xyz.mcutils.backend.common.EnumUtils; import xyz.mcutils.backend.common.EnumUtils;
import xyz.mcutils.backend.common.AppConfig;
import xyz.mcutils.backend.exception.impl.BadRequestException; import xyz.mcutils.backend.exception.impl.BadRequestException;
import xyz.mcutils.backend.exception.impl.ResourceNotFoundException; import xyz.mcutils.backend.exception.impl.ResourceNotFoundException;
import xyz.mcutils.backend.model.cache.CachedMinecraftServer; import xyz.mcutils.backend.model.cache.CachedMinecraftServer;

@ -1,7 +1,7 @@
package xyz.mcutils.backend.service.metric.metrics; package xyz.mcutils.backend.service.metric.metrics;
import xyz.mcutils.backend.service.metric.impl.IntegerMetric; import xyz.mcutils.backend.service.metric.impl.IntegerMetric;
import xyz.mcutils.backend.websocket.MetricsWebSocketHandler; import xyz.mcutils.backend.websocket.WebSocketManager;
public class ConnectedSocketsMetric extends IntegerMetric { public class ConnectedSocketsMetric extends IntegerMetric {
@ -16,6 +16,6 @@ public class ConnectedSocketsMetric extends IntegerMetric {
@Override @Override
public void collect() { public void collect() {
setValue(MetricsWebSocketHandler.SESSIONS.size()); setValue(WebSocketManager.getTotalConnections());
} }
} }

@ -10,7 +10,10 @@ import xyz.mcutils.backend.model.server.BedrockMinecraftServer;
import xyz.mcutils.backend.service.pinger.MinecraftServerPinger; import xyz.mcutils.backend.service.pinger.MinecraftServerPinger;
import java.io.IOException; import java.io.IOException;
import java.net.*; import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
/** /**
* The {@link MinecraftServerPinger} for pinging * The {@link MinecraftServerPinger} for pinging

@ -3,7 +3,6 @@ package xyz.mcutils.backend.service.pinger.impl;
import lombok.extern.log4j.Log4j2; import lombok.extern.log4j.Log4j2;
import xyz.mcutils.backend.Main; import xyz.mcutils.backend.Main;
import xyz.mcutils.backend.common.JavaMinecraftVersion; import xyz.mcutils.backend.common.JavaMinecraftVersion;
import xyz.mcutils.backend.common.ServerUtils;
import xyz.mcutils.backend.common.packet.impl.java.JavaPacketHandshakingInSetProtocol; import xyz.mcutils.backend.common.packet.impl.java.JavaPacketHandshakingInSetProtocol;
import xyz.mcutils.backend.common.packet.impl.java.JavaPacketStatusInStart; import xyz.mcutils.backend.common.packet.impl.java.JavaPacketStatusInStart;
import xyz.mcutils.backend.exception.impl.BadRequestException; import xyz.mcutils.backend.exception.impl.BadRequestException;

@ -0,0 +1,54 @@
package xyz.mcutils.backend.websocket;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.jetbrains.annotations.NotNull;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@RequiredArgsConstructor @Getter @Log4j2(topic = "WebSocket")
public abstract class WebSocket extends TextWebSocketHandler {
/**
* The sessions that are connected to the WebSocket.
*/
private final List<WebSocketSession> sessions = new ArrayList<>();
/**
* The path of the WebSocket.
* <p>
* Example: /websocket/metrics
* </p>
*/
public final String path;
/**
* Sends a message to the client.
*
* @param session the session to send the message to
* @param message the message to send
* @throws IOException if an error occurs while sending the message
*/
public void sendMessage(WebSocketSession session, String message) throws IOException {
session.sendMessage(new TextMessage(message));
}
@Override
public void afterConnectionEstablished(@NotNull WebSocketSession session) throws Exception {
this.sessions.add(session);
log.info("Connection established: {}", session.getId());
}
@Override
public void afterConnectionClosed(@NotNull WebSocketSession session, @NotNull CloseStatus status) throws Exception {
this.sessions.remove(session);
log.info("Connection closed: {}", session.getId());
}
}

@ -0,0 +1,51 @@
package xyz.mcutils.backend.websocket;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
import xyz.mcutils.backend.service.MetricService;
import xyz.mcutils.backend.websocket.impl.MetricsWebSocket;
import java.util.ArrayList;
import java.util.List;
@Configuration
@EnableWebSocket
public class WebSocketManager implements WebSocketConfigurer {
private static final List<WebSocket> WEB_SOCKETS = new ArrayList<>();
private final MetricService metricService;
@Autowired
public WebSocketManager(MetricService metricService) {
this.metricService = metricService;
}
@Override
public void registerWebSocketHandlers(@NotNull WebSocketHandlerRegistry registry) {
registerWebSocket(registry, new MetricsWebSocket(metricService));
}
/**
* Registers a WebSocket.
*
* @param registry the registry to register the WebSocket on
* @param webSocket the WebSocket to register
*/
private void registerWebSocket(WebSocketHandlerRegistry registry, WebSocket webSocket) {
registry.addHandler(webSocket, webSocket.getPath()).setAllowedOrigins("*");
WEB_SOCKETS.add(webSocket);
}
/**
* Gets the total amount of connections.
*
* @return the total amount of connections
*/
public static int getTotalConnections() {
return WEB_SOCKETS.stream().mapToInt(webSocket -> webSocket.getSessions().size()).sum();
}
}

@ -1,34 +1,30 @@
package xyz.mcutils.backend.websocket; package xyz.mcutils.backend.websocket.impl;
import lombok.extern.log4j.Log4j2; import lombok.extern.log4j.Log4j2;
import org.jetbrains.annotations.NotNull;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage; import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession; import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import xyz.mcutils.backend.Main; import xyz.mcutils.backend.Main;
import xyz.mcutils.backend.common.Timer; import xyz.mcutils.backend.common.Timer;
import xyz.mcutils.backend.service.MetricService; import xyz.mcutils.backend.service.MetricService;
import xyz.mcutils.backend.service.metric.metrics.TotalRequestsMetric; import xyz.mcutils.backend.service.metric.metrics.TotalRequestsMetric;
import xyz.mcutils.backend.service.metric.metrics.UniquePlayerLookupsMetric; import xyz.mcutils.backend.service.metric.metrics.UniquePlayerLookupsMetric;
import xyz.mcutils.backend.service.metric.metrics.UniqueServerLookupsMetric; import xyz.mcutils.backend.service.metric.metrics.UniqueServerLookupsMetric;
import xyz.mcutils.backend.websocket.WebSocket;
import java.util.ArrayList;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@Log4j2(topic = "WebSocket/Metrics") @Log4j2(topic = "WebSocket/Metrics")
public class MetricsWebSocketHandler extends TextWebSocketHandler { public class MetricsWebSocket extends WebSocket {
private final long interval = TimeUnit.SECONDS.toMillis(5); private final long interval = TimeUnit.SECONDS.toMillis(5);
public static final List<WebSocketSession> SESSIONS = new ArrayList<>();
private final MetricService metricService; private final MetricService metricService;
public MetricsWebSocketHandler(MetricService metricService) { public MetricsWebSocket(MetricService metricService) {
super("/websocket/metrics");
this.metricService = metricService; this.metricService = metricService;
Timer.scheduleRepeating(() -> { Timer.scheduleRepeating(() -> {
for (WebSocketSession session : SESSIONS) { for (WebSocketSession session : this.getSessions()) {
sendMetrics(session); sendMetrics(session);
} }
}, interval, interval); }, interval, interval);
@ -50,19 +46,4 @@ public class MetricsWebSocketHandler extends TextWebSocketHandler {
log.error("An error occurred while sending metrics to the client", e); log.error("An error occurred while sending metrics to the client", e);
} }
} }
@Override
public void afterConnectionEstablished(WebSocketSession session) {
log.info("WebSocket connection established with session id: {}", session.getId());
sendMetrics(session);
SESSIONS.add(session);
}
@Override
public void afterConnectionClosed(WebSocketSession session, @NotNull CloseStatus status) {
log.info("WebSocket connection closed with session id: {}", session.getId());
SESSIONS.remove(session);
}
} }