-
Notifications
You must be signed in to change notification settings - Fork 188
Support logging messages from the server #6476
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
| m_state = ConnectionState::connected; | ||
|
|
||
| // TODO(RCORE-1380) get this information in-band rather than from the websocket. | ||
| if (auto coid = m_websocket->get_appservices_request_id(); !coid.empty()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you should remove this method since it's only used here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can remove this function eventually, once the new server version is released.
| return; | ||
| } | ||
|
|
||
| logger.log(level, "Server log message for unknown session %1: %2", session_ident, message); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you need a return after this instruction
| e.what()); | ||
| } | ||
|
|
||
| static constexpr std::array<std::pair<std::string_view, util::Logger::Level>, 7> name_to_level = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can't this be an unordered_map so you can easily do the lookup below?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, I can make it a map
| // No sessions were enlisted to send | ||
| if (REALM_LIKELY(!m_is_closing)) | ||
| return; // Nothing more to do right now | ||
| break; // Check to see if there are any log messages to go out |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we can keep this the way it is if we move sending the log messages before the for loop.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wanted to give priority to any other messages that need to be sent before the log messages.
| logger.detail("Negotiated protocol version: %1", value_2); | ||
| // Grab the connection ID from the websocket if the protocol version is less than 10, | ||
| // otherwise, this value will come in a server log message | ||
| if (value_2 < 10) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this a temporary thing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It can be - since baas is not yet at protocol v10, I wanted to make sure things still worked the same until it is updated.
I have a similar check in the Sync Server for sending log messages.
| // Grab the connection ID from the websocket if the protocol version is less than 10, | ||
| // otherwise, this value will come in a server log message | ||
| if (value_2 < 10) { | ||
| receive_appservices_coid(m_websocket->get_appservices_request_id()); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hm, can we just always do this for now? otherwise this would block @yaseenmongo's work on the server change to start sending these, and that has not been prioritized yet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mean the protocol update to v10 has been delayed?
This is here to retain the previous functionality until the server protocol is updated to v10.
Or is the co_id not going to be sent until later, even though the new bind format and server log messages will be supported sooner?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or is the co_id not going to be sent until later, even though the new bind format and server log messages will be supported sooner?
right - the new bind format is being supported first which will involve the protocol version bump on the server (blocker for the breaking changes project). support for the log messages will come later (but that should does not need to block merging this client-side support for it)
| {"trace", util::Logger::Level::trace}, | ||
| }; | ||
|
|
||
| // connection id (co_id) is optional and level and msg are optional if a co_id is provided |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think we can loosen these invariants for simplicity
the server always has access to co_id, so it will likely always include it
we can make level optional and always default to debug/info (although the server would likely always include this as well)
and msg can also be "optional" and default to <no message> or something if the key is not provided (again, this would likely never happen)
lmk what you think
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the original "strict" checking was to find any malformed log messages from the server so they can be fixed.
We can loosen this checking, with a default level of Debug and nothing will be printed if the message is missing or empty.
| void send_log_message(util::Logger::Level level, const std::string&& message) | ||
| { | ||
| // Clients with protocol version less than 10 do not support log messages | ||
| if (m_connection.get_client_protocol_version() < 10) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: you can create a const for it
| // For now, grab the connection ID from the websocket if it supports it. In the future, the server | ||
| // will provide the appservices connection ID via a log message. | ||
| // TODO: Remove once the server starts sending the connection ID | ||
| receive_appservices_request_id(m_websocket->get_appservices_request_id()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
get_appservices_request_id() didn't seem to always have a value at this point previously
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is that why we have the checks in receive_server_log_message()?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The flow in websocket_handshake_completion_handler() will extract it from the headers before the call to websocket_connected_handler()
The checks in receive_server_log_message() is for when the server is providing the request_id and a log message is printed before it has sent this value. If it is always including the request_id in every log message, the checks aren't really needed. Also, custom platform networking implementations may not be able to provide this value, so it could be blank.
| } | ||
|
|
||
| std::string_view log_level; | ||
| bool has_level = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(why) is this optional?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Kiro had suggested it could default to a value (debug) if it wasn't provided.
| return; | ||
| } | ||
|
|
||
| try { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is a bit of an overkill, you can just use std::unordered_map::find().
| { | ||
| std::lock_guard log_guard(m_log_mutex); | ||
| m_log_messages.push(std::move(log_msg)); | ||
| m_send_trigger->trigger(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess the trigger does not need be under lock.
danieltabacaru
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. protocol.md should be updated with this new message.
|
|
||
| The body of the message is required and will be in JSON format with the following keys | ||
| currently supported: | ||
| - `co_id` is a string value that provides the appservices request/connection id for the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if this should be part of the header cc @kmorkos
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm, i think if the client is considering it optional then we should keep it in the json blob
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's up to the server if it's optional or not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i was going based on the docstring here. let's keep it optional just in case for forward compatibility
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK - I'll keep it as part of the JSON so it can be optional (the client really only needs to receive it once during a connection, since it will be cached when first received).
CHANGELOG.md
Outdated
| ### Enhancements | ||
| * <New feature description> (PR [#????](https://github.com/realm/realm-core/pull/????)) | ||
| * None. | ||
| * Added support for server log messages that are enabled by server protocol version 10. Appservices request id will be provided in a server log message in a future server release. ([PR #6476](https://github.com/realm/realm-core/pull/6476)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sync protocol version
What, How & Why?
Server log messages are going to be added to server protocol version 10 with the new session bind reason value. This code implements the receiving of log_message protocol messages from the server and prints them using the log level provided in the message. The connection id for the server will no longer be extracted from the websocket header and will be provided to the sync client as a log message with the "co_id" value when the websocket connection is first established. The websocket support for retrieving the request id value from the Websocket ACCEPT response HTTP headers added in #6143 will be removed once the server is sending the request id within server log messages.
log_message protocol messages use the following format:
The SyncServer was also updated to send a log message from connections and sessions to verify the operation of the receiving log_message messages. It will also send the appservices request id when the connection is established. This support is enabled if the client is using server protocol version 10 or greater.
Fixes #6801
☑️ ToDos
[ ] C-API, if public C++ API changed.