Skip to content

Server logging - #145

Open
VinodTech92 wants to merge 3 commits into
mainfrom
Server-Logging
Open

Server logging#145
VinodTech92 wants to merge 3 commits into
mainfrom
Server-Logging

Conversation

@VinodTech92

Copy link
Copy Markdown

Added changes will enable robust logging and tracing for each client connection
when Mapepire Server operates in daemon mode (multi-client/production scenarios).

  1. Added ConnectionTraceContext class for per-connection trace isolation
  2. Updated Tracer to support daemon mode tracing
  3. Updated DbWebsocketClient to initialize per-connection trace contexts
  4. Fixes server logging #136: server logging

- Add ConnectionTraceContext class for per-connection trace isolation
- Update Tracer to support daemon mode tracing
- Update DbWebsocketClient to initialize per-connection trace contexts
- Fixes #136: server logging

Key changes:
- Each WebSocket connection now gets an isolated trace buffer
- Trace data is automatically cleaned up on connection closure
- Backward compatible with existing single-mode tracing
- Thread-safe for multi-client scenarios
- Resolves daemon mode logging limitations

@ThePrez ThePrez left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

MAde some one-off comments throughout the code. To summarize, I have concerns about:

  • whether we are truly honoring trace isolation between requests
  • lack of clarity on global events vs. connection-level events

At a high level, a different approach would be to rework the main entry points and acquisition methods for the Tracer class. My thoughts:

  • Tracer.get() becomes Tracer.getGlobalTracer()
  • new method Tracer.getNew(String _connectionId) that is used within the SystemConnection constructor (or a similarly reasonable place). This returns a Tracer object specific for a connection.
  • Connection trace events are logged through non-static calls to the connection's Tracer object
    Overall this may be cleaner and less likely to have unforeseen intermingling between trace contexts.

Comment thread ConnectionTraceContext.java
Comment thread src/main/java/com/github/ibm/mapepire/Tracer.java
}
}

private File getJtOpenFile() throws IOException {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

same comments as on getFile()

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Incorporated the review comment.

}

private static class InMemCache<T> {
public static class InMemCache<T> {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Perhaps a personal preference, but I don't like having static inner classes be public.

Since it's static, we could pull it out into its own part, make it package-private, and use from adjacent consuming classes

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Incorporated the review comment.

super();
SystemConnection conn = new SystemConnection(clientHost, clientAddress,host, user, pass);
// ✅ NEW: Generate unique connection ID
this.connectionId = UUID.randomUUID().toString();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Please check the performance of this method. In the past, I have found randomUUID can take a long time (nearly a full second to complete). It may have gotten better since my distant memories were formed. I'm guessing this is the case, but please validate.

UUID is a great approach, but if it is problematic, perhaps an AtomicLong would do.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Incorporated the review feedback.

io = getDataStream(this, conn);

// ✅ NEW: Initialize per-connection trace context
Tracer.get().setConnectionId(connectionId);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This looks incorrectly handled.

  • get() returns a global static instance of Tracer
  • setConnectionId() sets a member variable in that global instance
  • subsequent trace requests will use a context derived from the global instance's member var
    ConnectionTraceContext.getOrCreate(m_connectionId).add(entry);
  • meaning that if another connection is initiated since the last time, we'd use the wrong trace context

(if I am mis-reading the code please explain)

Ideas for cleaner implementations would be:

  • Tracer.get() to take in the connection ID to get a Tracer object specific for that connection. Refactor accordingly.
  • (preferred) Initialize a ConnectionTraceContext directly. It would probably be "owned" by the SystemConnection class. In other words, the SystemConnection constructor would generate its own connection ID (makes sense for the connection ID to exist inside that class anyway), then generate a ConnectionTraceContext and store as a member variable. This would remove the need to keep a map of all the trace contexts here
    private static final ConcurrentHashMap<String, TraceBuffer> traceContexts = new ConcurrentHashMap<>();

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed, please review the latest commit.

return s_instance;
}

public static void info(Object _data) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Since get() is a static global instance, and there's nothing in this logic that delineates based on connection ID, I think this method should be named explicitly as a global thing. I'd propose globalInfo (and the same pattern would apply to peers (err, warn, etc)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Done.

Entry entry = new Entry(_t, _data);

// ✅ NEW: Daemon mode - use per-connection context
if (!MapepireServer.isSingleMode() && m_connectionId != null) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This needs to be reworked due to problems with m_connectionId

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed it.

@VinodTech92

Copy link
Copy Markdown
Author

@ThePrez I have reworked and incorporated all your review feedback received, please review when you can and provide the feedback. Thanks

@VinodTech92
VinodTech92 requested a review from ThePrez May 18, 2026 08:42
@eric-simpson

Copy link
Copy Markdown

@ThePrez can you please complete your review?

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.

server logging

3 participants