// processFile processes a single bugreport file, and returns the parsing result as a string. // Writes csv data to csvWriter if a csv file is specified. func processFile(filePath string, csvWriter *bufio.Writer, isFirstFile bool) string { // Read the whole file c, err := ioutil.ReadFile(filePath) if err != nil { log.Fatal(err) } br, fname, err := bugreportutils.ExtractBugReport(filePath, c) if err != nil { log.Fatalf("Error getting file contents: %v", err) } fmt.Printf("Parsing %s\n", fname) writer := ioutil.Discard if csvWriter != nil && *summaryFormat == parseutils.FormatTotalTime { writer = csvWriter } pkgs, errs := packageutils.ExtractAppsFromBugReport(br) if len(errs) > 0 { log.Printf("Errors encountered when getting package list: %v\n", errs) } upm, errs := parseutils.UIDAndPackageNameMapping(br, pkgs) if len(errs) > 0 { log.Printf("Errors encountered when generating package mapping: %v\n", errs) } rep := parseutils.AnalyzeHistory(writer, br, *summaryFormat, upm, *scrubPII) // Exclude summaries with no change in battery level var a []parseutils.ActivitySummary for _, s := range rep.Summaries { if s.InitialBatteryLevel != s.FinalBatteryLevel { a = append(a, s) } } if rep.TimestampsAltered { fmt.Println("Some timestamps were changed while processing the log.") } if len(rep.Errs) > 0 { fmt.Println("Errors encountered:") for _, err := range rep.Errs { fmt.Println(err.Error()) } } fmt.Println("\nNumber of summaries ", len(a), "\n") for _, s := range a { s.Print(&rep.OutputBuffer) } // Write the battery level summary csv to the csvFile specified if csvWriter != nil && *summaryFormat == parseutils.FormatBatteryLevel { // The dimension header line is only written if the file is the first one in the directory. parseutils.BatteryLevelSummariesToCSV(csvWriter, &a, isFirstFile) } return rep.OutputBuffer.String() }
func main() { flag.Parse() c, err := ioutil.ReadFile(*inputFile) if err != nil { log.Fatalf("Cannot open the file %s: %v", *inputFile, err) } br, fname, err := bugreportutils.ExtractBugReport(*inputFile, c) if err != nil { log.Fatalf("Error getting file contents: %v", err) } fmt.Printf("Parsing %s\n", fname) bs := bugreportutils.ExtractBatterystatsCheckin(br) if strings.Contains(bs, "Exception occurred while dumping") { log.Fatalf("Exception found in battery dump.") } m, err := bugreportutils.ParseMetaInfo(br) if err != nil { log.Fatalf("Unable to get meta info: %v", err) } s := &sessionpb.Checkin{ Checkin: proto.String(bs), BuildFingerprint: proto.String(m.BuildFingerprint), } pkgs, errs := packageutils.ExtractAppsFromBugReport(br) if len(errs) > 0 { log.Fatalf("Errors encountered when getting package list: %v", errs) } var ctr checkinutil.IntCounter stats, warns, errs := checkinparse.ParseBatteryStats(&ctr, checkinparse.CreateCheckinReport(s), pkgs) if len(warns) > 0 { log.Printf("Encountered unexpected warnings: %v\n", warns) } if len(errs) > 0 { log.Fatalf("Could not parse battery stats: %v\n", errs) } fmt.Println("\n################\n") fmt.Println("Partial Wakelocks") fmt.Println("################\n") var pwl []*checkinparse.WakelockInfo for _, app := range stats.App { for _, pw := range app.Wakelock { if pw.GetPartialTimeMsec() > 0 { pwl = append(pwl, &checkinparse.WakelockInfo{ Name: fmt.Sprintf("%s : %s", app.GetName(), pw.GetName()), UID: app.GetUid(), Duration: time.Duration(pw.GetPartialTimeMsec()) * time.Millisecond, }) } } } checkinparse.SortByTime(pwl) for _, pw := range pwl[:min(5, len(pwl))] { fmt.Printf("%s (uid=%d) %s\n", pw.Duration, pw.UID, pw.Name) } fmt.Println("\n################") fmt.Println("Kernel Wakelocks") fmt.Println("################\n") var kwl []*checkinparse.WakelockInfo for _, kw := range stats.System.KernelWakelock { if kw.GetName() != "PowerManagerService.WakeLocks" && kw.GetTimeMsec() > 0 { kwl = append(kwl, &checkinparse.WakelockInfo{ Name: kw.GetName(), Duration: time.Duration(kw.GetTimeMsec()) * time.Millisecond, }) } } checkinparse.SortByTime(kwl) for _, kw := range kwl[:min(5, len(kwl))] { fmt.Printf("%s %s\n", kw.Duration, kw.Name) } data, err := proto.Marshal(stats) if err != nil { log.Fatalf("Error from proto.Marshal: %v", err) } ioutil.WriteFile("checkin.proto", data, 0600) }
func main() { flag.Parse() inputs := strings.Split(*inputFiles, ",") if len(inputs) != 2 { log.Fatal("wrong input file number, expect 2, got ", len(inputs)) } dir, err := filepath.Abs(filepath.Dir(os.Args[0])) if err != nil { log.Fatal(err) } stats := make([]*bspb.BatteryStats, 2) normalizedStats := make([]*bspb.BatteryStats, 2) var errs []error var warns []string var ctr checkinutil.IntCounter for i, f := range inputs { c, err := ioutil.ReadFile(f) if err != nil { log.Fatalf("Cannot open the file %s: %v", f, err) } br, fname, err := bugreportutils.ExtractBugReport(f, c) if err != nil { log.Fatalf("Error getting file contents: %v", err) } fmt.Printf("** File #%d: %s\n", i, fname) bs := bugreportutils.ExtractBatterystatsCheckin(br) if strings.Contains(bs, "Exception occurred while dumping") { log.Fatalf("Exception found in battery dump.") } s := &sessionpb.Checkin{Checkin: proto.String(bs)} stats[i], warns, errs = checkinparse.ParseBatteryStats(&ctr, checkinparse.CreateCheckinReport(s), nil) if len(errs) > 0 { log.Fatalf("Could not parse battery stats: %v", errs) } if len(warns) > 0 { fmt.Printf("Encountered unexpected warnings: %v\n", warns) } data, err := proto.Marshal(stats[i]) if err != nil { log.Fatalf("Cannot marshal input proto: %v", err) } if *doDelta { ioutil.WriteFile(*parseFileName+strconv.Itoa(i)+".rawproto", data, 0600) ioutil.WriteFile(dir+"/"+*parseFileName+strconv.Itoa(i)+".rawproto", data, 0600) } if *doComp { n, err := checkindelta.NormalizeStats(stats[i]) if err != nil { log.Fatalf("Failed to normalize: %v", err) } normalizedStats[i] = n normData, err := proto.Marshal(normalizedStats[i]) if err != nil { log.Fatalf("Cannot marshal normalized input proto: %v", err) } ioutil.WriteFile(*normalizedFileName+strconv.Itoa(i)+".rawproto", normData, 0600) ioutil.WriteFile(dir+"/"+*normalizedFileName+strconv.Itoa(i)+".rawproto", normData, 0600) } } if *doComp { fmt.Printf("\n\nNormalized Delta Report (File1 - File2): \n\n") for i, f := range inputs { fmt.Printf("File %d: %v\n", i+1, f) } outputProto := checkindelta.ComputeDelta(normalizedStats[0], normalizedStats[1]) if outputProto == nil { log.Fatalf("empty result") } printResults(outputProto, *compareFileName, dir) } if *doDelta { fmt.Printf("\n\nDelta Report(File1 - File2)- \n\n") for i, f := range inputs { fmt.Printf("File %d: %v\n", i+1, f) } outputProto := checkindelta.ComputeDelta(stats[0], stats[1]) if outputProto == nil { log.Fatalf("empty result") } printResults(outputProto, *deltaFileName, dir) } }