@@ -33,8 +33,7 @@ public class LogWatcher : BackgroundService
3333 private readonly SemaphoreSlim _fileSemaphore = new ( Environment . ProcessorCount ) ;
3434
3535 // Static readonly for better performance
36- private static readonly string RemoveANSIEscapePattern = @"\x1B\[[0-9;]*[A-Za-z]" ;
37- private static readonly Regex RemoveANSIEscapeRegex = new ( RemoveANSIEscapePattern , RegexOptions . Compiled ) ;
36+ // Moved to LogParser class in LogMkCommon
3837
3938 // Retry configuration
4039 private const int MaxRetryAttempts = 3 ;
@@ -439,7 +438,7 @@ private async Task ReadNewLinesAsync(PodInfo info, CancellationToken stoppingTok
439438 private LogLine ? ProcessLogLine ( string line , PodInfo info , PodSettings podSettings , DeploymentSettings deploymentSettings , ref bool foundRecent )
440439 {
441440 // Remove ANSI escape sequences
442- var cleanLine = RemoveANSIEscapeRegex . Replace ( line , string . Empty ) ;
441+ var cleanLine = LogParser . RemoveANSIEscapeSequences ( line ) ;
443442
444443 // Parse container format (timestamp stdout/stderr message)
445444 var processedLine = ParseContainerLogFormat ( line , cleanLine ) ;
@@ -472,25 +471,7 @@ private async Task ReadNewLinesAsync(PodInfo info, CancellationToken stoppingTok
472471
473472 private string ParseContainerLogFormat ( string originalLine , string cleanLine )
474473 {
475- var firstSpace = originalLine . IndexOf ( ' ' ) ;
476- if ( firstSpace <= 0 )
477- return cleanLine ;
478-
479- var secondSpace = originalLine . IndexOf ( ' ' , firstSpace + 1 ) ;
480- if ( secondSpace <= 0 )
481- return cleanLine ;
482-
483- var thirdSpace = originalLine . IndexOf ( ' ' , secondSpace + 1 ) ;
484- if ( thirdSpace <= 0 )
485- return cleanLine ;
486-
487- var outType = originalLine . Substring ( firstSpace + 1 , secondSpace - firstSpace - 1 ) ;
488- if ( outType == "stdout" || outType == "stderr" )
489- {
490- return cleanLine . Substring ( thirdSpace + 1 - ( originalLine . Length - cleanLine . Length ) ) ;
491- }
492-
493- return cleanLine ;
474+ return LogParser . ParseContainerLogFormat ( originalLine , cleanLine ) ;
494475 }
495476
496477 private LogLevel GetLogLevelCached ( string logLine )
@@ -519,28 +500,9 @@ private LogLevel GetLogLevel(string logLine)
519500 if ( string . IsNullOrEmpty ( logLine ) )
520501 return LogLevel . Any ;
521502
522- var lowerLogLine = logLine . ToLowerInvariant ( ) ;
523-
524- var errorIndex = FindFirst ( lowerLogLine , "error" , "err" ) ;
525- var warningIndex = FindFirst ( lowerLogLine , "warning" , "warn" , "wrn" ) ;
526- var infoIndex = FindFirst ( lowerLogLine , "information" , "info" , "inf" ) ;
527- var debugIndex = FindFirst ( lowerLogLine , "debug" , "dbg" ) ;
528-
529- var firstIndex = MinNonNegative ( errorIndex , warningIndex , infoIndex , debugIndex ) ;
530-
531- if ( firstIndex < 0 )
532- return LogLevel . Any ; // No recognizable log level found
533- if ( firstIndex == errorIndex )
534- return LogLevel . Error ;
535- if ( firstIndex == warningIndex )
536- return LogLevel . Warning ;
537- if ( firstIndex == infoIndex )
538- return LogLevel . Information ;
539- if ( firstIndex == debugIndex )
540- return LogLevel . Debug ;
541-
542-
543- return LogLevel . Trace ; // Default to Trace if no specific level found
503+ var parsedLevel = LogParser . ParseLogLevel ( logLine ) ;
504+ // Return Any if it's Information (default) to maintain existing behavior
505+ return parsedLevel == LogLevel . Information ? LogLevel . Any : parsedLevel ;
544506 }
545507
546508 private LogLine ParseLogLine ( string originalLine , string cleanLine , string podName , string deploymentName , LogLevel logLevel )
@@ -559,65 +521,20 @@ private LogLine ParseLogLine(string originalLine, string cleanLine, string podNa
559521
560522 private DateTimeOffset ? ParseTimestamp ( string line )
561523 {
562- var firstSpace = line . IndexOf ( ' ' ) ;
563- if ( firstSpace < 0 )
564- return null ;
565-
566- var timestampStr = line . Substring ( 0 , firstSpace ) ;
567-
568- try
569- {
570- timestampStr = TruncateFractionalSeconds ( timestampStr , 7 ) ;
571-
572- if ( DateTimeOffset . TryParseExact ( timestampStr , "yyyy-MM-ddTHH:mm:ss.fffffffZ" ,
573- CultureInfo . InvariantCulture , DateTimeStyles . None , out var timestamp ) )
574- {
575- return timestamp ;
576- }
577- }
578- catch ( Exception ex )
579- {
580- _logger . LogDebug ( ex , "Failed to parse timestamp: {Timestamp}" , timestampStr ) ;
581- }
582-
583- return null ;
584- }
585-
586- private static string TruncateFractionalSeconds ( string timestamp , int maxFractionalDigits )
587- {
588- var dotIndex = timestamp . IndexOf ( '.' ) ;
589- if ( dotIndex == - 1 )
590- return timestamp ;
591-
592- var endIndex = dotIndex + maxFractionalDigits + 1 ;
593- if ( endIndex >= timestamp . Length - 1 )
594- return timestamp ;
595-
596- return timestamp . Substring ( 0 , endIndex ) + "Z" ;
524+ return LogParser . ParseTimestamp ( line ) ;
597525 }
598526
599- private static int FindFirst ( string line , params string [ ] keywords )
600- {
601- return keywords
602- . Select ( keyword => line . IndexOf ( keyword , StringComparison . Ordinal ) )
603- . Where ( index => index >= 0 )
604- . DefaultIfEmpty ( - 1 )
605- . Min ( ) ;
606- }
527+ // TruncateFractionalSeconds moved to LogParser class
607528
608- private static int MinNonNegative ( params int [ ] values )
609- {
610- var validValues = values . Where ( v => v >= 0 ) ;
611- return validValues . Any ( ) ? validValues . Min ( ) : - 1 ;
612- }
529+ // Helper methods moved to LogParser class
613530
614531 private bool IsLineContinuation ( string line , PodInfo info , DateTimeOffset lastTimestamp )
615532 {
616533 if ( string . IsNullOrWhiteSpace ( line ) )
617534 return false ;
618535
619536 // Parse container format to get the actual log content
620- var cleanLine = RemoveANSIEscapeRegex . Replace ( line , string . Empty ) ;
537+ var cleanLine = LogParser . RemoveANSIEscapeSequences ( line ) ;
621538 var processedLine = ParseContainerLogFormat ( line , cleanLine ) ;
622539
623540 // Check if line has a timestamp at the beginning
0 commit comments