Skip to content

Commit 56cd8c5

Browse files
author
Timothy Dodd
committed
Handle empty logs and assign unique client-side IDs
Added a check in `LogWatcher.cs` to skip processing empty lines after stripping the CRI prefix, improving efficiency. Enhanced `ParseContainerLogFormat` in `LogParser.cs` to handle cases where CRI logs contain only flags (`F` or `P`) without messages, returning an empty string for such cases. Addressed edge cases involving ANSI escape sequences. Introduced `nextClientId` in `log-processing.service.ts` to generate unique IDs for logs without one (e.g., SignalR logs). Updated `transformLogs` to assign these IDs, ensuring all logs have consistent identifiers.
1 parent 9a8e0cd commit 56cd8c5

3 files changed

Lines changed: 30 additions & 12 deletions

File tree

src/LogMkAgent/Services/LogWatcher.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,10 @@ private async Task ReadNewLinesAsync(PodInfo info, CancellationToken stoppingTok
551551
// Parse container format (timestamp stdout/stderr message)
552552
var processedLine = ParseContainerLogFormat(line, cleanLine);
553553

554+
// Skip empty lines after CRI prefix stripping
555+
if (string.IsNullOrWhiteSpace(processedLine))
556+
return null;
557+
554558
var logLevel = GetLogLevelCached(processedLine);
555559

556560
// If no log level was detected, default based on the CRI stream type:

src/LogMkCommon/LogParser.cs

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -163,25 +163,35 @@ public static string ParseContainerLogFormat(string originalLine, string cleanLi
163163
// Check for the F/P flag after stdout/stderr
164164
var thirdSpace = originalLine.IndexOf(' ', secondSpace + 1);
165165
if (thirdSpace <= 0)
166+
{
167+
// No space after stdout/stderr - check if remainder is just a flag (F/P)
168+
var remainder = originalLine.Substring(secondSpace + 1);
169+
if (remainder == "F" || remainder == "P")
170+
return string.Empty; // CRI line with empty message
166171
return cleanLine;
172+
}
167173

168174
var flag = originalLine.Substring(secondSpace + 1, thirdSpace - secondSpace - 1);
169175
if (flag == "F" || flag == "P")
170176
{
171-
// Find the actual log message after the flag
172-
var fourthSpace = originalLine.IndexOf(' ', thirdSpace + 1);
173-
if (fourthSpace > 0)
177+
// The actual message starts right after the flag space
178+
// CRI format: "timestamp stdout F message" - message is everything after "F "
179+
if (thirdSpace + 1 >= originalLine.Length)
174180
{
175-
// We need to find this position in the clean line
176-
// Count how many characters we need to skip in the clean line
177-
var prefixToSkip = originalLine.Substring(0, fourthSpace + 1);
178-
var cleanPrefixToSkip = RemoveANSIEscapeRegex.Replace(prefixToSkip, string.Empty);
179-
180-
if (cleanPrefixToSkip.Length < cleanLine.Length)
181-
{
182-
return cleanLine.Substring(cleanPrefixToSkip.Length);
183-
}
181+
// Nothing after the flag - empty message
182+
return string.Empty;
183+
}
184+
185+
var prefixToSkip = originalLine.Substring(0, thirdSpace + 1);
186+
var cleanPrefixToSkip = RemoveANSIEscapeRegex.Replace(prefixToSkip, string.Empty);
187+
188+
if (cleanPrefixToSkip.Length < cleanLine.Length)
189+
{
190+
return cleanLine.Substring(cleanPrefixToSkip.Length);
184191
}
192+
193+
// Clean line is shorter than prefix (edge case with ANSI sequences)
194+
return string.Empty;
185195
}
186196
else
187197
{

src/LogMkWeb/src/app/_services/log-processing.service.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,17 @@ export interface ExtractedFilters {
2222
})
2323
export class LogProcessingService {
2424

25+
// Counter for generating unique client-side IDs for logs that arrive without one (e.g. SignalR real-time logs)
26+
private nextClientId = -1;
27+
2528
/**
2629
* Core log transformation: assign pod colors and clean log lines
2730
* This is the main entry point for transforming raw logs into display-ready logs
2831
*/
2932
transformLogs(logs: Log[]): Log[] {
3033
return logs.map(log => ({
3134
...log,
35+
id: log.id || this.nextClientId--,
3236
podColor: this.getPodColor(log.pod),
3337
view: this.cleanLogLine(log.line),
3438
}));

0 commit comments

Comments
 (0)