diff options
Diffstat (limited to 'internal/tools')
| -rw-r--r-- | internal/tools/common/data_generator.go | 32 | ||||
| -rw-r--r-- | internal/tools/profile/analyze.go | 48 |
2 files changed, 41 insertions, 39 deletions
diff --git a/internal/tools/common/data_generator.go b/internal/tools/common/data_generator.go index 9446d8a..d3d4225 100644 --- a/internal/tools/common/data_generator.go +++ b/internal/tools/common/data_generator.go @@ -12,11 +12,13 @@ import ( // DataFormat represents the format of generated data type DataFormat string +// Supported data generator output formats. const ( - FormatLog DataFormat = "log" - FormatCSV DataFormat = "csv" - FormatDTail DataFormat = "dtail" - FormatMapReduce DataFormat = "mapreduce" + // FormatLog generates generic log lines. + FormatLog DataFormat = "log" + FormatCSV DataFormat = "csv" + FormatDTail DataFormat = "dtail" + FormatMapReduce DataFormat = "mapreduce" ) // DataGenerator generates test data for profiling and benchmarking @@ -112,7 +114,7 @@ func (g *DataGenerator) generateLogFile(filename string, targetSize int64) error line := fmt.Sprintf("[%s] %s - User %s performed %s action (duration: %dms, status: %s)\n", timestamp, level, user, action, duration, status) - + n, err := writer.WriteString(line) if err != nil { return err @@ -157,7 +159,7 @@ func (g *DataGenerator) generateCSVFile(filename string, targetSize int64) error } line := fmt.Sprintf("%s,%s,%s,%d,%s\n", timestamp, user, action, duration, status) - + n, err := writer.WriteString(line) if err != nil { return err @@ -180,14 +182,14 @@ func (g *DataGenerator) generateDTailFormatFile(filename string, targetSize int6 var currentSize int64 lineNum := 0 - hostnames := []string{"server01", "server02", "server03", "server04", "server05", + hostnames := []string{"server01", "server02", "server03", "server04", "server05", "server06", "server07", "server08", "server09", "server10"} for currentSize < targetSize { lineNum++ hostname := hostnames[lineNum%len(hostnames)] - timestamp := fmt.Sprintf("%02d%02d-%02d%02d%02d", - 10+(lineNum/86400)%12, (lineNum/3600)%30+1, + timestamp := fmt.Sprintf("%02d%02d-%02d%02d%02d", + 10+(lineNum/86400)%12, (lineNum/3600)%30+1, (lineNum/3600)%24, (lineNum/60)%60, lineNum%60) goroutines := 10 + (lineNum % 50) cgocalls := lineNum % 100 @@ -199,7 +201,7 @@ func (g *DataGenerator) generateDTailFormatFile(filename string, targetSize int6 line := fmt.Sprintf("INFO|%s|1|stats.go:56|%d|%d|%d|%.2f|%s|MAPREDUCE:STATS|hostname=%s|currentConnections=%d|lifetimeConnections=%d\n", timestamp, cpus, goroutines, cgocalls, loadavg, uptime, hostname, currentConnections, lifetimeConnections) - + n, err := writer.WriteString(line) if err != nil { return err @@ -220,13 +222,13 @@ func (g *DataGenerator) generateDTailFormatFileWithLines(filename string, lines writer := bufio.NewWriter(file) defer writer.Flush() - hostnames := []string{"server01", "server02", "server03", "server04", "server05", + hostnames := []string{"server01", "server02", "server03", "server04", "server05", "server06", "server07", "server08", "server09", "server10"} for i := 1; i <= lines; i++ { hostname := hostnames[i%len(hostnames)] - timestamp := fmt.Sprintf("%02d%02d-%02d%02d%02d", - 10+(i/86400)%12, (i/3600)%30+1, + timestamp := fmt.Sprintf("%02d%02d-%02d%02d%02d", + 10+(i/86400)%12, (i/3600)%30+1, (i/3600)%24, (i/60)%60, i%60) goroutines := 10 + (i % 50) cgocalls := i % 100 @@ -238,7 +240,7 @@ func (g *DataGenerator) generateDTailFormatFileWithLines(filename string, lines line := fmt.Sprintf("INFO|%s|1|stats.go:56|%d|%d|%d|%.2f|%s|MAPREDUCE:STATS|hostname=%s|currentConnections=%d|lifetimeConnections=%d\n", timestamp, cpus, goroutines, cgocalls, loadavg, uptime, hostname, currentConnections, lifetimeConnections) - + if _, err := writer.WriteString(line); err != nil { return err } @@ -263,4 +265,4 @@ func GenerateCSVFile(filename string, lines int) error { // Estimate size based on average line length (about 50 bytes per line) estimatedSize := int64(lines * 50) return g.generateCSVFile(filename, estimatedSize) -}
\ No newline at end of file +} diff --git a/internal/tools/profile/analyze.go b/internal/tools/profile/analyze.go index f27841a..59503b2 100644 --- a/internal/tools/profile/analyze.go +++ b/internal/tools/profile/analyze.go @@ -13,13 +13,13 @@ import ( "github.com/mimecast/dtail/internal/tools/common" ) -// ProfileInfo holds information about a profile file -type ProfileInfo struct { - Path string - Tool string - Type string // cpu, mem, alloc - ModTime string - Size int64 +// Info holds information about a profile file. +type Info struct { + Path string + Tool string + Type string // cpu, mem, alloc + ModTime string + Size int64 } func runAnalyze(cfg *Config) error { @@ -58,7 +58,7 @@ func listProfiles(cfg *Config) error { } // Group by tool - byTool := make(map[string][]ProfileInfo) + byTool := make(map[string][]Info) for _, p := range profiles { byTool[p.Tool] = append(byTool[p.Tool], p) } @@ -74,26 +74,26 @@ func listProfiles(cfg *Config) error { for _, tool := range tools { fmt.Printf("\n%s profiles:\n", tool) toolProfiles := byTool[tool] - + // Sort by modification time (newest first) sort.Slice(toolProfiles, func(i, j int) bool { return toolProfiles[i].ModTime > toolProfiles[j].ModTime }) for _, p := range toolProfiles { - fmt.Printf(" %-8s %s %8s %s\n", + fmt.Printf(" %-8s %s %8s %s\n", p.Type, p.ModTime, common.FormatSize(p.Size), filepath.Base(p.Path)) } } fmt.Printf("\nTotal: %d profiles\n", len(profiles)) fmt.Printf("\nUsage: dtail-tools profile -mode analyze <profile_file>\n") - + return nil } -func findProfiles(dir string) ([]ProfileInfo, error) { - var profiles []ProfileInfo +func findProfiles(dir string) ([]Info, error) { + var profiles []Info pattern := filepath.Join(dir, "*.prof") matches, err := filepath.Glob(pattern) @@ -117,7 +117,7 @@ func findProfiles(dir string) ([]ProfileInfo, error) { tool := parts[0] profType := parts[1] - profiles = append(profiles, ProfileInfo{ + profiles = append(profiles, Info{ Path: path, Tool: tool, Type: profType, @@ -158,11 +158,11 @@ func analyzeProfile(profilePath string, args ...string) error { func showTopFunctions(profilePath string, count int, isMemProfile bool) error { args := []string{"tool", "pprof", "-top", fmt.Sprintf("-nodecount=%d", count)} - + if isMemProfile { args = append(args, "-alloc_space") } - + args = append(args, profilePath) cmd := exec.Command("go", args...) @@ -178,22 +178,22 @@ func showTopFunctions(profilePath string, count int, isMemProfile bool) error { fmt.Printf("Top %d functions (sorted by flat):\n", count) fmt.Println("================================================================") - + for scanner.Scan() { line := scanner.Text() - + // Skip header lines - if strings.HasPrefix(line, "File:") || strings.HasPrefix(line, "Type:") || - strings.HasPrefix(line, "Time:") || strings.HasPrefix(line, "Duration:") { + if strings.HasPrefix(line, "File:") || strings.HasPrefix(line, "Type:") || + strings.HasPrefix(line, "Time:") || strings.HasPrefix(line, "Duration:") { continue } - + // Start printing from the table header if strings.Contains(line, "flat") && strings.Contains(line, "cum") { inTop = true fmt.Println("# Command: go " + strings.Join(args[1:], " ")) } - + if inTop { fmt.Println(line) if line != "" { @@ -216,6 +216,6 @@ func openWebProfile(profilePath string) error { cmd := exec.Command("go", "tool", "pprof", "-http=:8080", profilePath) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr - + return cmd.Run() -}
\ No newline at end of file +} |
