mirror of
https://github.com/mattermost/mattermost.git
synced 2026-11-04 13:16:45 -06:00
* [MM-71392] Search server logs on the server and flag truncated results The structured log viewer only ever loaded each node's latest 10,000 entries and searched them in the browser, so older matches were missed and nothing said entries were left out. LogFilter gains an optional search term (max 256 characters), applied while the log file is scanned: a case-insensitive substring match over every field except level and timestamp, like the viewer's own search. A line whose raw bytes can't contain the term is skipped before it is decoded, so a rare term scans the file several times faster than a rare level. Remote nodes receive the term through the existing cluster query and older nodes ignore the unknown field, so the client-side search stays as a backstop. Since the viewer's search also matches node names once it lists several nodes, a node whose name holds the term is queried again unsearched. The viewer sends the debounced term with each query and live-tail poll, keeps the list in place instead of flashing the spinner while a search loads, and shows a notice when a node returned the full page, pointing to Download for the full file. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FpCfx5vEzDnjuW2q3TTD5t * [MM-71392] Drop the unused getAllLogs selector and duplicate log viewer strings getAllLogs has had no callers since the log viewer switched to getAllLogsWithNode, and needed a @ts-expect-error for the node-keyed response. The plain text viewer and the Copy log line button had their own IDs for strings the structured viewer already defines. They now use admin.logs.ReloadLogs, admin.logs.DownloadLogs, admin.logs.loading and admin.logs.copied, which keeps the IDs that already have translations. Labels that read the same but appear in different places, such as the Node column and the Node filter, stay separate. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FpCfx5vEzDnjuW2q3TTD5t * [MM-71392] Type the logs query response as entries keyed by node POST /logs/query returns each node's entries keyed by node name, but AdminState.logs was typed as LogObject[] and Client4.getLogs as string[], so the selectors had to cast the state. Add LogsByNode and use it for the client, the reducer, the initial state and AdminState, and drop the cast. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FpCfx5vEzDnjuW2q3TTD5t * [MM-71392] Correct the log filter date and log entry types LogDateFrom and LogDateTo were commented as epochs, but they hold a formatted date in the server's LogFilterDateLayout. LogObject marked job_id and worker as required, but only entries logged by background jobs carry them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FpCfx5vEzDnjuW2q3TTD5t * [MM-71392] Group every server log level under the viewer's four levels The server logs panic, fatal, critical, stdlog and trace besides the four levels the viewer knew. Unchecking any level sent only those four with the query, so the other levels were dropped on the server and in the browser. With every level shown, they were styled as debug and missing from the level counts. The level filter keeps its four entries, and each now covers a group: Error is panic, fatal, critical and error; Info is info and stdlog; Debug is debug and trace. The query sends every level of the checked groups, and the counts, the browser filter and the row colors use the same grouping. Rows still show the level's own name. LogLevelEnum gains the missing levels; silly stays, deprecated, since the server never logs it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FpCfx5vEzDnjuW2q3TTD5t * [MM-71392] Add mocked e2e tests for the server logs node, level and search handling A single-node test server can't log a cluster's response, a failed node, levels such as fatal or trace, or a full page of entries on demand. The new spec answers POST /api/v4/logs/query from the test and checks the viewer and the requests it sends: - two nodes show the node menu and each row's node, and picking one sends server_names - the failed node entry stays visible under a time range that hides older entries - fatal entries take the error color and stay when Debug is unchecked, trace entries are hidden, and the grouped levels are queried - a full page of 10,000 entries shows the truncation notice - the search term is sent with the query and the searched response shown The ServerLogs page object gains the node menu, the levels toggle, the level badge and the truncation notice. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FpCfx5vEzDnjuW2q3TTD5t * [MM-71392] Cap the server logs search at the length the server accepts The server rejects search terms over 256 characters, which left the viewer showing stale results with no sign the search failed. * [MM-71392] Drop the browser-side search of server logs The server now searches each node's log file, including node names, so the viewer listing only entries that also match in the browser just re-filtered the server's matches. Wherever the two matches disagreed it hid entries the server found, and it hid the entry for an unreachable node unless its error contained the term. During a rolling upgrade, nodes without search support return their latest entries unsearched, and the viewer now lists them as returned. * [MM-71392] Simplify the server logs search With the System Console no longer searching in the browser, the server no longer has to reproduce its JSON.stringify output exactly. Values logged as objects are matched as encoding/json wrote them, without undoing its escapes of <, > and &. The search term comes from a JSON request, so it is always valid UTF-8 and needs no check. The term helpers fold into plain functions. The raw line check and the in-place ASCII comparison stay: without them a term with a quote took 2.4 s instead of 175 ms on a 64 MB file, and a rare term allocated 75 MB instead of 135 kB. Also drop the Server Logs docs note and the API docs sentence on nodes without search support, and fix comments that still described the browser search. * [MM-71392] Stop matching node names in the server logs search The search matched node names by querying a node whose name held the term again, unsearched. Hostnames share substrings, such as the ip-10-0- prefix of every AWS node, so a common term dropped the search for every node at the cost of a second cluster round trip. The Node selector already narrows the logs to a node, so the search now matches the log lines only, and the Node column no longer highlights the term. * [MM-71392] Rely on the default logs page size for the logs query Client4.getLogs already requests page 0 with 10,000 entries per node, so getLogs doesn't pass them again. Also drop the note on nodes without search support from the LogFilter.Search comment. * [MM-71392] Scope the server logs truncation notice to the nodes in view With a node selected, the notice said entries from each node were limited, because the node list keeps every node seen. It also pointed to Download with several nodes listed, although Download only saves the log file of the node serving the request. The per-node title now needs all nodes in view, and the Download hint only shows with a single node. * [MM-71392] Fold non-ASCII search terms that lowercase to ASCII Go lowercases İ to i and the Kelvin sign to k, so a search for İstanbul became the ASCII term istanbul and was compared byte by byte against a line still holding İ, which never matched. Whether to compare bytes in place is now decided from the term before lowercasing. * [MM-71392] Check each scanned log line against the search term once A line that passed the raw check before decoding was checked again in isLogFilteredBySearch. The scan now keeps the first result. Also name the search length limit and drop two overlapping viewer tests. * [MM-71392] Pick the server logs search fast path from the line The in-place ASCII comparison was chosen from the search term, so İ and the Kelvin sign only matched when the term held them: istanbul missed İstanbul. The comparison now runs in place only when the line is ASCII, where it gives the same result as lowercasing the line, and lowercases any other line. A match is the lowercased value containing the lowercased term, whichever side holds such characters. * [MM-71392] Cap stored log entries at the shared logs page size The truncation notice flags a node once it holds a full page, so the live tail cap has to match the page size rather than a copy of it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FpCfx22jJ2GZkYnZiLDeMS --------- Co-authored-by: Claude <noreply@anthropic.com>