summaryrefslogtreecommitdiff
path: root/internal/tools
diff options
context:
space:
mode:
Diffstat (limited to 'internal/tools')
-rw-r--r--internal/tools/common/data_generator.go32
-rw-r--r--internal/tools/profile/analyze.go48
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
+}