Skip to content

feature/ServerLogging - #22

Merged
bamsemats merged 7 commits into
mainfrom
feature/ServerLogging
Feb 10, 2026
Merged

feature/ServerLogging#22
bamsemats merged 7 commits into
mainfrom
feature/ServerLogging

Conversation

@addee1

@addee1 addee1 commented Feb 10, 2026

Copy link
Copy Markdown

Closes #19
This PR introduces basic logging to the HTTP server.

Changes

  • Added a centralized "ServerLogger" utility
  • Replaced "System.out.println" and "printStackTrace" in "SocketServer" with structured logging
  • Logs server startup, client connections, incoming HTTP requests, and errors

Scope

Logging is currently applied to "SocketServer", which is the entry point for server and connection handling.

Notes

  • Uses standard Java logging (java.util.logging)
  • No file logging or configurable log levels included
  • No functional HTTP behavior changed (no responses are sent yet)

Verification

  • Server startup is logged

  • Client connections are logged

  • HTTP method and path are logged on incoming requests

  • No unit tests added as logging contains no business logic

Summary by CodeRabbit

  • New Features

    • Added centralized, configurable logging for server startup, client connections, and request details; log level can be set via an environment variable or system property.
  • Bug Fixes

    • Replaced ad-hoc console prints with standardized logs and improved error logging for server/socket and client-handling errors, enhancing observability and troubleshooting.

…class in SocketServer.java to return logging information upon opening socket and user connecting to server.
@coderabbitai

coderabbitai Bot commented Feb 10, 2026

Copy link
Copy Markdown

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a centralized java.util.logging configuration class (ServerLogging) and integrates its Logger into SocketServer, replacing System.out and printStackTrace calls with logger calls for server startup, client connections, incoming request method/path, and error logging.

Changes

Cohort / File(s) Summary
Logging Infrastructure
src/main/java/org/juv25d/logging/ServerLogging.java
New class that configures a java.util.logging.Logger (disables parent handlers, ensures a ConsoleHandler with SimpleFormatter, reads level from log.level / LOG_LEVEL, defaults to INFO) and exposes public static Logger getLogger().
SocketServer Integration
src/main/java/org/juv25d/SocketServer.java
Adds private static final Logger logger = ServerLogging.getLogger() and replaces System.out.println and e.printStackTrace() with structured logger calls for server start, client connections, incoming request (method + path), and exception logging.

Sequence Diagram(s)

sequenceDiagram
    participant Client as Client
    participant Server as SocketServer
    participant Logger as ServerLogging

    Client->>Server: TCP connect / send HTTP request
    Server->>Logger: log(INFO, "Server started")
    Server->>Logger: log(INFO, "Client connected: <addr>:<port>")
    Server->>Logger: log(INFO, "Request: <METHOD> <PATH>")
    Server->>Client: respond (HTTP)
    alt on exception
        Server->>Logger: log(WARNING/SEVERE, "Error handling request", exception)
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐇 I hopped into the server den,
I logged each knock of client men,
Methods and paths I note with care,
No stray prints left hanging in the air,
I nibble bytes and bounce elsewhere.

🚥 Pre-merge checks | ✅ 3 | ❌ 2
❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'feature/ServerLogging' is a branch name format that describes the feature but lacks specificity about the actual change being made to SocketServer. Use a more descriptive title that specifies the main change, such as 'Add centralized logging to SocketServer' to better convey the primary modification.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed All coding requirements from issue #19 are met: centralized ServerLogging utility created, server start and client connections logged, HTTP method/path logged, and errors use logger instead of printStackTrace.
Out of Scope Changes check ✅ Passed All changes directly align with issue #19 scope: ServerLogging utility class and SocketServer modifications for centralized logging. No extraneous changes detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/ServerLogging

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@src/main/java/org/juv25d/logging/ServerLogging.java`:
- Around line 11-25: The logger configuration in ServerLogging never runs
because it's in an unused constructor; move the ConsoleHandler/SimpleFormatter,
setUseParentHandlers(false), and setLevel(Level.INFO) logic into a static
initializer that configures the static Logger logger used by getLogger(), remove
the unused HttpParser parameter and the public constructor, and add a private
no-op constructor to make ServerLogging a true utility class; ensure
SocketServer continues to call ServerLogging.getLogger() and that the static
block references Logger.getLogger(SocketServer.class.getName()) (the existing
logger field) so configuration is applied at class load time.
🧹 Nitpick comments (5)
src/main/java/org/juv25d/logging/ServerLogging.java (1)

3-4: Circular dependency and tight coupling to SocketServer.

ServerLogging imports SocketServer just to use its class name for the logger, while SocketServer imports ServerLogging — creating a circular dependency between packages. The HttpParser import is also unnecessary once the constructor is removed.

Consider accepting the logger name as a parameter or using the ServerLogging class name itself:

♻️ Proposed refactor
-import org.juv25d.SocketServer;
-import org.juv25d.parser.HttpParser;
 
 // ...
 
-    private static final Logger logger = Logger.getLogger(SocketServer.class.getName());
+    private static final Logger logger = Logger.getLogger("org.juv25d");

Or provide a factory method so each caller gets a properly-named logger:

public static Logger getLogger(Class<?> clazz) {
    return Logger.getLogger(clazz.getName());
}

Also applies to: 12-12

src/main/java/org/juv25d/SocketServer.java (4)

28-28: Inconsistent logging style: mix of string concatenation and parameterized messages.

Lines 32 and 38 correctly use logger.log(Level.INFO, "... {0}", arg) (parameterized), but lines 28, 49, 50, and 53 use string concatenation ("..." + value). Parameterized logging avoids the cost of string concatenation when the log level is disabled and is the idiomatic JUL pattern.

♻️ Suggested: use parameterized logging consistently
-            logger.info("Server started at port: " + serverSocket.getLocalPort());
+            logger.log(Level.INFO, "Server started at port: {0}", serverSocket.getLocalPort());
-            logger.info("Method: " + request.method());
-            logger.info("Path: " + request.path());
+            logger.log(Level.INFO, "Request: {0} {1}", new Object[]{request.method(), request.path()});
-            logger.warning("Error handling client: " + e.getMessage());
+            logger.log(Level.WARNING, "Error handling client: {0}", e.getMessage());

Also applies to: 49-50, 53-53


37-39: Consider logging the full exception for SEVERE errors.

On a severe server socket error, only the message string is logged. The stack trace is lost, making debugging harder. Pass the exception as a parameter to preserve it:

♻️ Proposed fix
-            logger.log(Level.SEVERE, "Server socket error: {0}", e.getMessage());
+            logger.log(Level.SEVERE, "Server socket error", e);

52-54: Same here — preserve the exception stack trace for client errors.

logger.warning(msg) discards the stack trace. Use logger.log(Level.WARNING, msg, e) to retain it for diagnostics.

♻️ Proposed fix
-            logger.warning("Error handling client: " + e.getMessage());
+            logger.log(Level.WARNING, "Error handling client", e);

21-21: Logger field placement: move above the constructor for conventional ordering.

Static final fields are conventionally declared at the top of the class, before instance fields and constructors. Currently logger is declared after the constructor.

♻️ Suggested reorder
 public class SocketServer {
 
+    private static final Logger logger = ServerLogging.getLogger();
     private final HttpParser httpParser;
 
     public SocketServer(HttpParser httpParser) {
         this.httpParser = httpParser;
     }
 
-    private static final Logger logger = ServerLogging.getLogger();
-
     static void createSocket() {

Comment thread src/main/java/org/juv25d/logging/ServerLogging.java

@fmazmz fmazmz left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!
Only one suggestion regarding logging level.
Instead of hard coding Level.INFO, should we maybe read it form System properties so that we can add debug logs and switch the logging level easily in JVM args when running the program.

Example:
java -Dlog.level=FINE org.juv25d.Main || java -Dlog.level=ALL org.juv25d.Main

Something like this?:

String levelName = System.getProperty(
   "log.level",
     System.getenv().getOrDefault("LOG_LEVEL", "INFO")
     );

Level level = Level.parse(levelName.toUpperCase());

More info:
https://docs.oracle.com/javase/8/docs/api/java/util/logging/Level.html

HerrKanin
HerrKanin previously approved these changes Feb 10, 2026
Comment thread src/main/java/org/juv25d/logging/ServerLogging.java
@Cavve
Cavve self-requested a review February 10, 2026 10:23
Cavve
Cavve previously approved these changes Feb 10, 2026
…tiated and allow for log level to be set by args in JVM (default level 'INFO' if no args provided).
@bamsemats
bamsemats dismissed stale reviews from Cavve and HerrKanin via 1b5b22c February 10, 2026 10:37
fmazmz
fmazmz previously approved these changes Feb 10, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@src/main/java/org/juv25d/SocketServer.java`:
- Around line 36-38: The catch blocks in SocketServer that currently call
logger.severe(e.getMessage()) lose stack traces; import java.util.logging.Level
and replace those calls with logger.log(Level.SEVERE, "<descriptive message>",
e) (e.g., in the server socket catch in run/start method and the other catch at
the later catch block referenced) so the full Throwable is preserved in the
logs; update both occurrences (use the exact logger variable and the existing
exception variable name `e`) and keep descriptive messages like "Server socket
error" or the corresponding context.
🧹 Nitpick comments (2)
src/main/java/org/juv25d/SocketServer.java (2)

20-20: Nitpick: Declare static final field before the constructor.

Java convention is to place static fields at the top of the class, before instance fields and constructors.

♻️ Suggested reordering
 public class SocketServer {
 
+    private static final Logger logger = ServerLogging.getLogger();
+
     private final HttpParser httpParser;
 
     public SocketServer(HttpParser httpParser) {
         this.httpParser = httpParser;
     }
 
-    private static final Logger logger = ServerLogging.getLogger();
-

48-49: Consider combining method and path into a single log line.

Two separate logger.info calls for one request add noise and make log correlation harder. A single entry is easier to grep and reason about.

♻️ Proposed change
-            logger.info("Method: " + request.method());
-            logger.info("Path: " + request.path());
+            logger.info("Request: " + request.method() + " " + request.path());

Comment thread src/main/java/org/juv25d/SocketServer.java
@bamsemats
bamsemats merged commit 06d3f0c into main Feb 10, 2026
2 checks passed
@fmazmz
fmazmz deleted the feature/ServerLogging branch February 11, 2026 12:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add basic server logging

6 participants