### Install go-torch via go get Source: https://github.com/uber-archive/go-torch/blob/master/README.md Command to install the go-torch utility using the go get command. This is a standard method for obtaining Go command-line tools and their dependencies. ```bash $ go get github.com/uber/go-torch ``` -------------------------------- ### Install Go Dependencies with Glide Source: https://github.com/uber-archive/go-torch/blob/master/README.md Commands to install the Go dependencies for the go-torch project using the Glide package manager. This step is part of the local development setup. ```bash $ go get github.com/Masterminds/glide $ cd $GOPATH/src/github.com/uber/go-torch $ glide install ``` -------------------------------- ### End-to-End Profiling Workflow - Go Source: https://context7.com/uber-archive/go-torch/llms.txt Complete workflow demonstrating pprof data fetching, parsing, sample selection, and flame graph generation. Covers configuring pprof options, getting raw data, parsing into structured profile, selecting visualization metrics, converting to flame input format, and generating final SVG output with custom styling. ```go package main import ( "fmt" "io/ioutil" "log" "github.com/uber/go-torch/pprof" "github.com/uber/go-torch/renderer" "github.com/uber/go-torch/torchlog" ) func main() { // Step 1: Configure pprof options opts := pprof.Options{ BaseURL: "http://localhost:8080", URLSuffix: "/debug/pprof/profile", TimeSeconds: 30, } // Step 2: Fetch raw pprof data torchlog.Printf("Fetching profile from %s", opts.BaseURL+opts.URLSuffix) rawOutput, err := pprof.GetRaw(opts, nil) if err != nil { torchlog.Fatalf("Failed to get raw pprof output: %v", err) } torchlog.Printf("Received %d bytes of profiling data", len(rawOutput)) // Step 3: Parse raw output into structured profile profile, err := pprof.ParseRaw(rawOutput) if err != nil { torchlog.Fatalf("Failed to parse pprof output: %v", err) } torchlog.Printf("Parsed profile with %d unique stacks", len(profile.Samples)) // Step 4: Select which sample metric to visualize args := []string{} // Use default (first sample) sampleIdx := pprof.SelectSample(args, profile.SampleNames) torchlog.Printf("Using sample: %s", profile.SampleNames[sampleIdx]) // Step 5: Convert to flamegraph input format flameInput, err := renderer.ToFlameInput(profile, sampleIdx) if err != nil { torchlog.Fatalf("Failed to convert to flamegraph input: %v", err) } // Step 6: Generate SVG flame graph flameGraphArgs := []string{ "--title", "CPU Profile", "--width", "1200", "--colors", "hot", } svg, err := renderer.GenerateFlameGraph(flameInput, flameGraphArgs...) if err != nil { torchlog.Fatalf("Failed to generate flame graph: %v", err) } // Step 7: Write to file outputFile := "torch.svg" err = ioutil.WriteFile(outputFile, svg, 0644) if err != nil { torchlog.Fatalf("Failed to write output file: %v", err) } torchlog.Printf("Flame graph written to %s", outputFile) fmt.Printf("Success! Open %s in a web browser to view the flame graph.\n", outputFile) } ``` -------------------------------- ### Run go-torch using Docker Source: https://github.com/uber-archive/go-torch/blob/master/README.md Instructions for running the go-torch profiler using a Docker container. This method is useful for environments where direct installation is not preferred. The `-p` flag outputs SVG to stdout. ```bash $ docker run uber/go-torch -u http://[address-of-host] -p > torch.svg ``` -------------------------------- ### Convert Profile to Flamegraph in Go Source: https://context7.com/uber-archive/go-torch/llms.txt This example converts a profiling data structure to flamegraph input format using renderer.ToFlameInput from go-torch. It takes a profile and an index for the sample type as inputs, relying on github.com/uber/go-torch/stack and renderer packages. Outputs the flamegraph-ready strings for count or time-based samples, suitable for piping to flamegraph tools like flamegraph.pl. ```go package main import ( "fmt" "log" "github.com/uber/go-torch/stack" "github.com/uber/go-torch/renderer" ) func main() { // Create a profile profile, _ := stack.NewProfile([]string{"samples/count", "cpu/nanoseconds"}) // Add samples sample1 := stack.NewSample([]string{"main", "fib", "fib"}, []int64{100, 1000000}) sample2 := stack.NewSample([]string{"main", "loop"}, []int64{50, 500000}) sample3 := stack.NewSample([]string{"runtime.main", "main"}, []int64{200, 2000000}) profile.Samples = []*stack.Sample{sample1, sample2, sample3} // Convert to flamegraph input format (using first sample: samples/count) flameInput, err := renderer.ToFlameInput(profile, 0) if err != nil { log.Fatalf("Failed to convert to flame input: %v", err) } fmt.Printf("Flamegraph input format:\n%s", string(flameInput)) // Output: // Flamegraph input format: // main;fib;fib 100 // main;loop 50 // runtime.main;main 200 // Convert using second sample (cpu/nanoseconds) flameInputTime, err := renderer.ToFlameInput(profile, 1) if err != nil { log.Fatalf("Failed to convert to flame input: %v", err) } fmt.Printf("\nFlamegraph input (time-based):\n%s", string(flameInputTime)) // Output: // Flamegraph input (time-based): // main;fib;fib 1000000 // main;loop 500000 // runtime.main;main 2000000 // This format can be piped to flamegraph.pl: // echo "main;fib;fib 100" | flamegraph.pl > graph.svg } ``` -------------------------------- ### Run go-torch Tests Source: https://github.com/uber-archive/go-torch/blob/master/README.md Command to execute the test suite for the go-torch project. This verifies the functionality and correctness of the codebase. ```bash $ go test ./... ok github.com/uber/go-torch 0.012s ok github.com/uber/go-torch/graph 0.017s ok github.com/uber/go-torch/visualization 0.052s ``` -------------------------------- ### Create and Aggregate Samples in Go Source: https://context7.com/uber-archive/go-torch/llms.txt This code creates stack samples using stack.NewSample, aggregates additional counts, and builds a complete profile. It requires function names and value arrays as inputs, depending on the github.com/uber/go-torch/stack package. Outputs include the created sample data and aggregated counts, with limitations on matching count lengths between additions. ```go package main import ( "fmt" "log" "github.com/uber/go-torch/stack" ) func main() { // Create a sample representing a call stack funcNames := []string{"main", "processRequest", "queryDatabase"} counts := []int64{5, 500000} // 5 samples, 500,000 nanoseconds sample := stack.NewSample(funcNames, counts) fmt.Printf("Sample created:\n") fmt.Printf(" Functions: %v\n", sample.Funcs) fmt.Printf(" Counts: %v\n", sample.Counts) // Output: // Sample created: // Functions: [main processRequest queryDatabase] // Counts: [5 500000] // Add more observations to the same stack additionalCounts := []int64{3, 300000} err := sample.Add(additionalCounts) if err != nil { log.Fatalf("Failed to add counts: %v", err) } fmt.Printf("After aggregation:\n") fmt.Printf(" Counts: %v\n", sample.Counts) // Output: // After aggregation: // Counts: [8 800000] // Error handling: mismatched count lengths wrongCounts := []int64{10} // Only 1 value instead of 2 err = sample.Add(wrongCounts) if err != nil { fmt.Printf("Error: %v\n", err) // Output: Error: cannot add 1 values to sample with 2 values } // Build a complete profile profile, _ := stack.NewProfile([]string{"samples/count", "cpu/nanoseconds"}) sample1 := stack.NewSample([]string{"main", "handlerA"}, []int64{10, 1000000}) sample2 := stack.NewSample([]string{"main", "handlerB"}, []int64{5, 500000}) profile.Samples = []*stack.Sample{sample1, sample2} fmt.Printf("\nComplete profile:\n") fmt.Printf("Sample types: %v\n", profile.SampleNames) for i, s := range profile.Samples { fmt.Printf("Sample %d: %v = %v\n", i, s.Funcs, s.Counts) } // Output: // Complete profile: // Sample types: [samples/count cpu/nanoseconds] // Sample 0: [main handlerA] = [10 1000000] // Sample 1: [main handlerB] = [5 500000] } ``` -------------------------------- ### Colored Logging with torchlog - Go Source: https://context7.com/uber-archive/go-torch/llms.txt Shows usage of torchlog package for colored logging with timestamps. Demonstrates info and fatal log levels with color coding. Fatal level logs exit the program with status 1. Supports formatted output similar to Printf with automatic timestamping. ```go package main import ( "github.com/uber/go-torch/torchlog" ) func main() { // Info level logging (blue color) torchlog.Print("Starting profiling process") // Output: INFO[14:30:45] Starting profiling process torchlog.Printf("Profiling %s for %d seconds", "http://localhost:8080", 30) // Output: INFO[14:30:45] Profiling http://localhost:8080 for 30 seconds // Fatal level logging (red color, exits program) err := validateConfig() if err != nil { torchlog.Fatalf("Configuration error: %v", err) // Output: FATAL[14:30:45] Configuration error: invalid port // Program exits with status 1 } torchlog.Printf("Flame graph written to %s", "torch.svg") // Output: INFO[14:30:50] Flame graph written to torch.svg } func validateConfig() error { return nil // Example function } ``` -------------------------------- ### Go: Select Sample Metric with pprof.SelectSample Source: https://context7.com/uber-archive/go-torch/llms.txt This snippet demonstrates how to use `pprof.SelectSample` to select a specific sample metric based on command-line arguments. The function takes a slice of arguments and a list of sample names, returning the index of the selected metric. It handles numeric indices and default selection. ```Go package main import ( "fmt" "github.com/uber/go-torch/pprof" ) func main() { // Sample names from a memory profile sampleNames := []string{ "alloc_objects/count", "alloc_space/bytes", "inuse_objects/count", "inuse_space/bytes", } // Command-line arguments from user args1 := []string{"alloc_space"} selectedIdx1 := pprof.SelectSample(args1, sampleNames) fmt.Printf("Selected index for -alloc_space: %d (%s)\n", selectedIdx1, sampleNames[selectedIdx1]) // Output: Selected index for -alloc_space: 1 (alloc_space/bytes) args2 := []string{"inuse_objects"} selectedIdx2 := pprof.SelectSample(args2, sampleNames) fmt.Printf("Selected index for -inuse_objects: %d (%s)\n", selectedIdx2, sampleNames[selectedIdx2]) // Output: Selected index for -inuse_objects: 2 (inuse_objects/count) // Numeric index selection args3 := []string{"sample_index", "3"} selectedIdx3 := pprof.SelectSample(args3, sampleNames) fmt.Printf("Selected index for -sample_index 3: %d (%s)\n", selectedIdx3, sampleNames[selectedIdx3]) // Output: Selected index for -sample_index 3: 3 (inuse_space/bytes) // Default (no matching args) args4 := []string{"--other-flag"} selectedIdx4 := pprof.SelectSample(args4, sampleNames) fmt.Printf("Default selected index: %d (%s)\n", selectedIdx4, sampleNames[selectedIdx4]) // Output: Default selected index: 0 (alloc_objects/count) } ``` -------------------------------- ### Integrate pprof in Go Application Source: https://github.com/uber-archive/go-torch/blob/master/README.md This code snippet demonstrates how to add profiling endpoints to a Go application by importing the net/http/pprof package. It's essential for enabling performance monitoring and debugging features offered by go-torch. ```go import _ "net/http/pprof" ``` -------------------------------- ### Create Profile in Go Source: https://context7.com/uber-archive/go-torch/llms.txt This function creates a new profile data structure using the stack.NewProfile method from go-torch. It takes a list of sample names as input and returns a profile or an error if the list is invalid (e.g., empty or contains empty strings). The code depends on the github.com/uber/go-torch/stack package and outputs the created profile with sample types. ```go package main import ( "fmt" "log" "github.com/uber/go-torch/stack" ) func main() { // Create a profile with sample names sampleNames := []string{"samples/count", "cpu/nanoseconds"} profile, err := stack.NewProfile(sampleNames) if err != nil { log.Fatalf("Failed to create profile: %v", err) } fmt.Printf("Profile created with sample types: %v\n", profile.SampleNames) // Output: Profile created with sample types: [samples/count cpu/nanoseconds] // Invalid: empty sample names _, err = stack.NewProfile([]string{}) if err != nil { fmt.Printf("Error: %v\n", err) // Output: Error: cannot create a profile with no samples } // Invalid: empty name in list _, err = stack.NewProfile([]string{"samples/count", ""}) if err != nil { fmt.Printf("Error: %v\n", err) // Output: Error: cannot have empty sample names in profile } } ``` -------------------------------- ### Go: Parse Raw pprof Output with pprof.ParseRaw Source: https://context7.com/uber-archive/go-torch/llms.txt This snippet shows how to parse raw pprof output into a structured `Profile` object using `pprof.ParseRaw`. The raw output, typically a byte slice from `pprof.GetRaw`, is parsed to extract sample data, function calls, and other relevant information. The resulting profile can be used for further analysis. ```Go package main import ( "fmt" "log" "github.com/uber/go-torch/pprof" ) func main() { // Assume rawOutput was obtained from pprof.GetRaw rawOutput := []byte("Samples:\n" + \ "samples/count cpu/nanoseconds\n" + \ " 1 10000000: 1 2 3\n" + \ " 2 20000000: 4 5\n\n" + \ "Locations:\n" + \ " 1: 0x49dee1 main.fib :0 s=0\n" + \ " 2: 0x16e1 main.main :0 s=0\n" + \ " 3: 0x2e71 runtime.main :0 s=0\n" + \ " 4: 0x5c61 main.loop :0 s=0\n" + \ " 5: 0x3a12 runtime.goexit :0 s=0\n\n" + \ "Mappings:\n") // Parse the raw output into a Profile profile, err := pprof.ParseRaw(rawOutput) if err != nil { log.Fatalf("Failed to parse raw pprof output: %v", err) } // Access parsed data fmt.Printf("Sample types: %v\n", profile.SampleNames) // Output: Sample types: [samples/count cpu/nanoseconds] fmt.Printf("Total samples: %d\n", len(profile.Samples)) // Output: Total samples: 2 // Iterate through samples for i, sample := range profile.Samples { fmt.Printf("Sample %d:\n", i) fmt.Printf(" Call stack: %v\n", sample.Funcs) fmt.Printf(" Counts: %v\n", sample.Counts) } // Output: // Sample 0: // Call stack: [runtime.main main.main main.fib] // Counts: [1 10000000] // Sample 1: // Call stack: [runtime.goexit main.loop] // Counts: [2 20000000] } ``` -------------------------------- ### Go: Fetch Raw Profiling Data with pprof.GetRaw Source: https://context7.com/uber-archive/go-torch/llms.txt This snippet demonstrates how to use `pprof.GetRaw` to retrieve raw profiling data from either a remote endpoint or a profile file. The function takes configuration options for the target and returns the raw output as a byte slice, or an error if retrieval fails. Supports both remote and local profile file inputs. ```Go package main import ( "fmt" "log" "github.com/uber/go-torch/pprof" ) func main() { // Configure pprof options for remote profiling opts := pprof.Options{ BaseURL: "http://localhost:8080", URLSuffix: "/debug/pprof/profile", TimeSeconds: 30, ExtraArgs: []string{}, } // Fetch raw pprof output rawOutput, err := pprof.GetRaw(opts, nil) if err != nil { log.Fatalf("Failed to get raw pprof output: %v", err) } fmt.Printf("Received %d bytes of profiling data\n", len(rawOutput)) // Example with binary profile file fileOpts := pprof.Options{ BinaryName: "myapp.test", BinaryFile: "cpu.prof", TimeSeconds: 0, // Not used for file input } rawFileOutput, err := pprof.GetRaw(fileOpts, nil) if err != nil { log.Fatalf("Failed to read profile file: %v", err) } fmt.Printf("Loaded %d bytes from profile file\n", len(rawFileOutput)) } ``` -------------------------------- ### Integrate pprof endpoints in Go application Source: https://context7.com/uber-archive/go-torch/llms.txt This code snippet shows how to integrate pprof endpoints in a Go web application. It imports the net/http/pprof package for side effects (registering handlers) and demonstrates basic HTTP handlers with simulated work. The pprof endpoints are automatically registered at various debug paths for different profiling types. ```go package main import ( "fmt" "log" "net/http" _ "net/http/pprof" // Import for side effects: registers handlers "time" ) func main() { // Register application handlers http.HandleFunc("/", handleRequest) http.HandleFunc("/api/users", handleUsers) // pprof endpoints are automatically registered at: // /debug/pprof/ // /debug/pprof/profile (CPU profile) // /debug/pprof/heap (memory profile) // /debug/pprof/goroutine (goroutine profile) // /debug/pprof/block (blocking profile) // /debug/pprof/threadcreate (thread creation profile) // /debug/pprof/mutex (mutex contention profile) fmt.Println("Server starting on :8080") fmt.Println("Profile with: go-torch -u http://localhost:8080") log.Fatal(http.ListenAndServe(":8080", nil)) } func handleRequest(w http.ResponseWriter, r *http.Request) { // Simulate work time.Sleep(10 * time.Millisecond) fmt.Fprintf(w, "Hello, World!") } func handleUsers(w http.ResponseWriter, r *http.Request) { // Simulate database query time.Sleep(50 * time.Millisecond) fmt.Fprintf(w, "Users list") } ``` -------------------------------- ### Clone FlameGraph Scripts Source: https://github.com/uber-archive/go-torch/blob/master/README.md Command to clone the FlameGraph repository, which contains necessary scripts for generating flame graphs. These scripts need to be in your system's PATH when using go-torch locally. ```bash cd $GOPATH/src/github.com/uber/go-torch git clone https://github.com/brendangregg/FlameGraph.git ``` -------------------------------- ### Generate Flame Graph SVG - Go Source: https://context7.com/uber-archive/go-torch/llms.txt Demonstrates how to use renderer.GenerateFlameGraph to create SVG flame graphs from profiling data. Shows default and custom options including title, width, colors, and graph inversion. Input expects semicolon-separated stacks with counts. Requires flamegraph.pl in PATH for execution. ```go package main import ( "fmt" "io/ioutil" "log" "github.com/uber/go-torch/renderer" ) func main() { // Flamegraph input data (semicolon-separated stacks with counts) flameInput := []byte(`main;processRequest;queryDatabase 150 main;processRequest;renderTemplate 80 main;healthCheck 20 runtime.main;main 50 `) // Generate SVG with default options svg, err := renderer.GenerateFlameGraph(flameInput) if err != nil { log.Fatalf("Failed to generate flame graph: %v", err) // Note: This will fail if flamegraph.pl is not in PATH } // Write to file err = ioutil.WriteFile("profile.svg", svg, 0644) if err != nil { log.Fatalf("Failed to write SVG: %v", err) } fmt.Printf("Flame graph written to profile.svg (%d bytes)\n", len(svg)) // Generate with custom options args := []string{ "--title", "API Server CPU Profile", "--width", "1600", "--colors", "mem", "--hash", } customSvg, err := renderer.GenerateFlameGraph(flameInput, args...) if err != nil { log.Fatalf("Failed to generate custom flame graph: %v", err) } err = ioutil.WriteFile("custom-profile.svg", customSvg, 0644) if err != nil { log.Fatalf("Failed to write custom SVG: %v", err) } fmt.Printf("Custom flame graph written to custom-profile.svg (%d bytes)\n", len(customSvg)) // Generate inverted flame graph (icicle) icicleArgs := []string{"--inverted"} icicleSvg, err := renderer.GenerateFlameGraph(flameInput, icicleArgs...) if err != nil { log.Fatalf("Failed to generate icicle graph: %v", err) } fmt.Printf("Icicle graph generated (%d bytes)\n", len(icicleSvg)) } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.