diff --git a/internal/server/tcp.go b/internal/server/tcp.go index 3c91df0..3d3008a 100644 --- a/internal/server/tcp.go +++ b/internal/server/tcp.go @@ -11,6 +11,7 @@ import ( "hash-of-wisdom/internal/application" "hash-of-wisdom/internal/lib/sl" + "hash-of-wisdom/internal/metrics" "hash-of-wisdom/internal/protocol" "hash-of-wisdom/internal/service" ) @@ -130,6 +131,10 @@ func (s *TCPServer) acceptLoop(ctx context.Context) { func (s *TCPServer) handleConnection(ctx context.Context, rawConn net.Conn) { defer rawConn.Close() + // Track active connections + metrics.ActiveConnections.Inc() + defer metrics.ActiveConnections.Dec() + connLogger := s.logger.With("remote_addr", rawConn.RemoteAddr().String()) connLogger.Info("connection accepted") @@ -187,19 +192,38 @@ func (s *TCPServer) processConnection(ctx context.Context, conn net.Conn, logger logger.Debug("client closed connection gracefully") return nil } + metrics.RequestErrors.WithLabelValues("decode_error").Inc() logger.Error("failed to decode message", sl.Err(err)) return fmt.Errorf("decode error: %w", err) } logger.Debug("message decoded", "type", msg.Type, "payload_length", msg.PayloadLength) - // Process message through application layer + // Track all requests + metrics.RequestsTotal.Inc() + + // Process message through application layer with timing + start := time.Now() response, err := s.wisdomApplication.HandleMessage(ctx, msg) + duration := time.Since(start) + metrics.RequestDuration.Observe(duration.Seconds()) + if err != nil { + metrics.RequestErrors.WithLabelValues("internal_error").Inc() logger.Error("application error", sl.Err(err)) return fmt.Errorf("application error: %w", err) } + // Check if response is an error response + if errorResp, isError := response.(*protocol.ErrorResponse); isError { + metrics.RequestErrors.WithLabelValues(string(errorResp.Code)).Inc() + } else { + // Track quotes served for successful solution requests + if msg.Type == protocol.SolutionRequestType { + metrics.QuotesServed.Inc() + } + } + logger.Debug("sending response to client") // Send response using the response's own Encode method if err := response.Encode(dc); err != nil {