backend/analyzer/entities/rider.backend.log.go (166 lines of code) (raw):

package entities import ( "bufio" "fmt" "log" "log_analyzer/backend/analyzer" "os" "regexp" "strings" "time" ) func init() { CurrentAnalyzer.AddDynamicEntity(analyzer.DynamicEntity{ Name: "Rider Backend Log", ConvertPathToLogs: parseRiderBackendLog, CheckPath: isRiderBackendLog, CheckIgnoredPath: isIgnoredRiderBackendFile, DefaultVisibility: isBackendLogVisible, GetDisplayName: getDisplayName, LineHighlightingColor: "#58c0f1", }) CurrentAnalyzer.AddDynamicEntity(analyzer.DynamicEntity{ Name: "Rider DebuggerWorker", ConvertPathToLogs: parseRiderBackendLog, CheckPath: isRiderDebuggerWorkerLog, CheckIgnoredPath: isIgnoredRiderBackendFile, DefaultVisibility: isPathVisible, GetDisplayName: getDisplayName, LineHighlightingColor: "#58c0f1", }) CurrentAnalyzer.AddDynamicEntity(analyzer.DynamicEntity{ Name: "Rider RoslynWorker", ConvertPathToLogs: parseRiderBackendLog, CheckPath: isRiderRoslynWorkerLog, CheckIgnoredPath: isIgnoredRiderBackendFile, DefaultVisibility: isPathVisible, GetDisplayName: getDisplayName, LineHighlightingColor: "#58c0f1", }) CurrentAnalyzer.AddDynamicEntity(analyzer.DynamicEntity{ Name: "Rider SolutionBuilder", ConvertPathToLogs: parseRiderBackendLog, CheckPath: isRiderSolutionBuilderLog, CheckIgnoredPath: isIgnoredRiderBackendFile, DefaultVisibility: isPathVisible, GetDisplayName: getDisplayName, LineHighlightingColor: "#58c0f1", }) CurrentAnalyzer.AddDynamicEntity(analyzer.DynamicEntity{ Name: "Rider UnitTestLogs", ConvertPathToLogs: parseRiderBackendLog, CheckPath: isRiderUnitTestLog, CheckIgnoredPath: isIgnoredRiderBackendFile, DefaultVisibility: isPathVisible, GetDisplayName: getDisplayName, LineHighlightingColor: "#58c0f1", }) CurrentAnalyzer.AddDynamicEntity(analyzer.DynamicEntity{ Name: "Rider MsBuildTask", ConvertPathToLogs: parseRiderBackendLog, CheckPath: isRiderMsBuildTaskLog, CheckIgnoredPath: isIgnoredRiderBackendFile, DefaultVisibility: isPathVisible, GetDisplayName: getDisplayName, LineHighlightingColor: "#58c0f1", }) } // ignore files bigger than 49MB func isBackendLogVisible(path string) bool { f, err := os.Stat(path) if err != nil { return true } if f.Size() >= 47*1024*1024 { log.Printf("File %s is too big (%d MB) to be displayed", path, f.Size()/(1024*1024)) return false } return true } func isPathVisible(path string) bool { return isRiderBackendLog(path) } func isRiderMsBuildTaskLog(path string) bool { return strings.Contains(path, "MsBuildTask") } func isRiderUnitTestLog(path string) bool { return strings.Contains(path, "UnitTestLogs") } func isRiderSolutionBuilderLog(path string) bool { return strings.Contains(path, "SolutionBuilder") && strings.Contains(path, "ReSharperBuild") } func isRiderRoslynWorkerLog(path string) bool { logMatcher := regexp.MustCompile(`backend.\d+.log`) return (strings.Contains(path, "backend.log") || logMatcher.MatchString(path)) && strings.Contains(path, "RoslynWorker") } func isRiderDebuggerWorkerLog(path string) bool { logMatcher := regexp.MustCompile(`backend.\d+.log`) return (strings.Contains(path, "backend.log") || logMatcher.MatchString(path)) && strings.Contains(path, "DebuggerWorker") } func isRiderBackendLog(path string) bool { logMatcher := regexp.MustCompile(`backend.\d+.log`) return (strings.Contains(path, "backend.log") || logMatcher.MatchString(path)) && !isRiderRoslynWorkerLog(path) && !isRiderDebuggerWorkerLog(path) && !isRiderSolutionBuilderLog(path) } func isIgnoredRiderBackendFile(path string) bool { return strings.Contains(path, "backend-protocol.log") || strings.Contains(path, "backend-out.log") } func parseRiderBackendLog(path string) analyzer.Logs { startDate := analyzer.GetFileModTime(path) if startDate.IsZero() { log.Printf("Could not get creation date for %s", path) } reader, _ := os.Open(path) scanner := bufio.NewScanner(reader) logToPass := []analyzer.LogEntry{} for scanner.Scan() { currentString := scanner.Text() if getTimeStringFromRiderBackendLog(currentString) != "" { logToPass = append(logToPass, parseRiderBackendLogString(startDate, currentString)) } else if len(logToPass) > 0 { logToPass[len(logToPass)-1].Text = logToPass[len(logToPass)-1].Text + "\n" + currentString } } return logToPass } func getTimeStringFromRiderBackendLog(str string) string { dateMatcher := regexp.MustCompile(`^(\d{2}:\d{2}:\d{2}[.,]\d{3})`) if !dateMatcher.MatchString(str) { return "" } return dateMatcher.FindString(str) } func parseRiderBackendLogString(startDate time.Time, logEntryAsString string) (currentEntry analyzer.LogEntry) { logEntryAsStringToIdeaLogFormat := fmt.Sprintf("%s %s", startDate.Format("2006-01-02"), logEntryAsString) logParts := analyzer.GetRegexNamedCapturedGroups(`(?P<Year>\d{4})-(?P<Month>\d{2})-(?P<Day>\d{2})\s+(?P<Hours>\d{2}):(?P<Minutes>\d{2}):(?P<Seconds>\d{2})[.,](?P<MiliSeconds>\d{3})\s*\|(?P<Severity>\w)\|(?P<Class>.*?)\|(?P<Text>.*)`, logEntryAsStringToIdeaLogFormat) if startDate.IsZero() || logParts["Hours"] == "" { log.Printf("PARSE_ERROR!\n logEntryAsStringToIdeaLogFormat:%s\n Start Date: %s\n logParts[\"Hours\"]: %s\n", logEntryAsStringToIdeaLogFormat, startDate, logParts["Hours"]) return analyzer.LogEntry{ Severity: "PARSE_ERROR", Time: time.Now().AddDate(0, 0, 1), Text: logEntryAsString, Visible: true, } } currentEntry.Time, _ = time.Parse(time.RFC3339Nano, fmt.Sprintf("%s-%s-%sT%s:%s:%s.%sZ", startDate.Format("2006"), startDate.Format("01"), startDate.Format("02"), logParts["Hours"], logParts["Minutes"], logParts["Seconds"], logParts["MiliSeconds"])) currentEntry.Severity = getSeverityFromRiderBackendLog(logParts["Severity"]) currentEntry.Text = logParts["Class"] + " —" + logParts["Text"] currentEntry.Visible = true return currentEntry } func getSeverityFromRiderBackendLog(s string) string { if strings.HasPrefix(s, "E") { return "ERROR" } if strings.HasPrefix(s, "W") { return "WARN" } if strings.HasPrefix(s, "V") { return "VERB" } if strings.HasPrefix(s, "T") { return "TRACE" } if strings.HasPrefix(s, "I") { return "INFO" } return "RIDER" }