CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-py-spy

Sampling profiler for Python programs written in Rust with extremely low overhead

Pending
Overview
Eval results
Files

config.mddocs/

Configuration and Output

Comprehensive configuration system supporting multiple profiling modes, output formats, and platform-specific options. Enables fine-tuned control over profiling behavior for different use cases from development to production.

Capabilities

Config Struct

Main configuration object controlling all aspects of py-spy behavior. Provides sensible defaults while allowing customization for specific profiling scenarios.

pub struct Config {
    /// Process locking strategy during sampling
    pub blocking: LockingStrategy,
    /// Whether to profile native C/C++/Cython extensions
    pub native: bool,
    /// Sampling rate in Hz (samples per second)
    pub sampling_rate: u64,
    /// Output file format for record command
    pub format: Option<FileFormat>,
    /// Whether to include line numbers in output
    pub show_line_numbers: bool,
    /// Recording duration for record command
    pub duration: RecordDuration,
    /// Include idle/sleeping threads in results
    pub include_idle: bool,
    /// Include thread IDs in flamegraph output
    pub include_thread_ids: bool,
    /// Profile child processes and subprocesses
    pub subprocesses: bool,
    /// Only show threads holding the GIL
    pub gil_only: bool,
    /// Hide progress bar output
    pub hide_progress: bool,
    /// Capture stdout/stderr from spawned processes
    pub capture_output: bool,
    /// Output format for dump command (JSON vs text)
    pub dump_json: bool,
    /// Number of local variables to collect (0 = none)
    pub dump_locals: u64,
    /// Show full file paths vs shortened versions
    pub full_filenames: bool,
    /// Line number reporting mode
    pub lineno: LineNo,
    /// Console refresh rate for top command
    pub refresh_seconds: f64,
    // Additional private fields for CLI usage...
}

impl Config {
    /// Creates Config from command line arguments
    pub fn from_commandline() -> Config;
    
    /// Creates Config from specific argument list
    pub fn from_args(args: &[String]) -> clap::Result<Config>;
}

impl Default for Config {
    fn default() -> Config;
}

Default Configuration:

Config {
    blocking: LockingStrategy::Lock,
    native: false,
    sampling_rate: 100,
    format: None,
    show_line_numbers: false,
    duration: RecordDuration::Unlimited,
    include_idle: false,
    include_thread_ids: false,
    subprocesses: false,
    gil_only: false,
    hide_progress: false,
    capture_output: true,
    dump_json: false,
    dump_locals: 0,
    full_filenames: false,
    lineno: LineNo::LastInstruction,
    refresh_seconds: 1.0,
    // CLI-specific fields omitted...
}

Locking Strategy

Controls how py-spy interacts with the target process during sampling, affecting both accuracy and performance impact.

pub enum LockingStrategy {
    /// Standard mode: pause process during sampling for accurate results
    Lock,
    
    /// Non-blocking mode: sample without pausing (lower impact, potential inaccuracy)
    NonBlocking,
    
    /// Process is already locked by another tool
    AlreadyLocked,
}

Usage Examples:

// Standard mode - most accurate, slight performance impact
let mut config = Config::default();
config.blocking = LockingStrategy::Lock;

// Production mode - minimal impact, potential sampling errors
let mut config = Config::default();
config.blocking = LockingStrategy::NonBlocking;

Output Formats

Multiple output formats for different analysis tools and workflows.

pub enum FileFormat {
    /// SVG flamegraph for visual analysis
    flamegraph,
    
    /// Raw flamegraph data (text format)
    raw,
    
    /// Speedscope JSON format for speedscope.app
    speedscope,
    
    /// Chrome trace format for chrome://tracing
    chrometrace,
}

impl std::str::FromStr for FileFormat {
    type Err = String;
    fn from_str(s: &str) -> Result<Self, Self::Err>;
}

Format Descriptions:

  • flamegraph: Interactive SVG visualization showing call stack hierarchy and time distribution
  • speedscope: JSON format compatible with speedscope.app for detailed analysis
  • chrometrace: JSON format for Chrome DevTools or Perfetto for timeline analysis
  • raw: Text format compatible with flamegraph.pl script for custom processing

Recording Duration

Controls how long profiling sessions run, useful for automated profiling and resource management.

pub enum RecordDuration {
    /// Continue recording until manually stopped (Ctrl-C)
    Unlimited,
    
    /// Record for specified number of seconds
    Seconds(u64),
}

Usage Examples:

// Short burst profiling
let mut config = Config::default();
config.duration = RecordDuration::Seconds(30);

// Continuous profiling until stopped
let mut config = Config::default();
config.duration = RecordDuration::Unlimited;

Line Number Reporting

Controls how line numbers are reported in stack traces.

pub enum LineNo {
    /// Don't include line numbers
    NoLine,
    
    /// Use first line of function definition
    First,
    
    /// Use line of last executed instruction (default)
    LastInstruction,
}

Configuration Patterns

Development Profiling

Optimized for detailed analysis during development with comprehensive information collection.

use py_spy::{Config, LockingStrategy, RecordDuration, LineNo};

fn development_config() -> Config {
    let mut config = Config::default();
    config.blocking = LockingStrategy::Lock;      // Accurate sampling
    config.show_line_numbers = true;             // Include line numbers
    config.include_idle = false;                 // Skip idle threads
    config.sampling_rate = 100;                  // Standard rate
    config.lineno = LineNo::LastInstruction;     // Precise line info
    config.full_filenames = true;                // Full paths for debugging
    config
}

Production Profiling

Minimizes performance impact while collecting useful profiling data.

use py_spy::{Config, LockingStrategy, RecordDuration};

fn production_config() -> Config {
    let mut config = Config::default();
    config.blocking = LockingStrategy::NonBlocking; // Minimal impact
    config.sampling_rate = 50;                      // Lower sampling rate
    config.duration = RecordDuration::Seconds(60);  // Limited duration
    config.hide_progress = true;                    // No UI interference
    config.gil_only = true;                         // Focus on active threads
    config
}

Native Extension Analysis

Configured for profiling applications using C/C++/Cython extensions.

use py_spy::{Config, LockingStrategy};

fn native_extension_config() -> Config {
    let mut config = Config::default();
    config.native = true;                        // Enable native profiling
    config.blocking = LockingStrategy::Lock;     // Required for native traces
    config.show_line_numbers = true;             // Helpful for mixed code
    config.sampling_rate = 200;                  // Higher rate for detail
    config
}

Subprocess Profiling

Configured for profiling applications that spawn child processes.

use py_spy::{Config, RecordDuration};

fn subprocess_config() -> Config {
    let mut config = Config::default();
    config.subprocesses = true;                  // Follow child processes
    config.include_thread_ids = true;            // Distinguish processes
    config.duration = RecordDuration::Seconds(120); // Longer duration
    config.sampling_rate = 50;                   // Manage overhead
    config
}

Output Format Details

Flamegraph Output

SVG format providing interactive visualization of call stack hierarchies.

use py_spy::{Config, FileFormat};

let mut config = Config::default();
config.format = Some(FileFormat::flamegraph);
config.show_line_numbers = true;           // Include line info in frames
config.include_thread_ids = false;         // Clean visualization

Features:

  • Interactive SVG with zoom and search
  • Proportional width showing time spent
  • Hover tooltips with frame information
  • Opens automatically in browser on macOS

Speedscope Output

JSON format optimized for detailed analysis in speedscope.app.

use py_spy::{Config, FileFormat};

let mut config = Config::default();
config.format = Some(FileFormat::speedscope);
config.include_thread_ids = true;          // Thread separation
config.show_line_numbers = true;           // Detailed frame info

Features:

  • Timeline view showing execution over time
  • Left Heavy view for hotspot identification
  • Sandwich view for caller/callee analysis
  • Load at https://www.speedscope.app/

Chrome Trace Output

JSON format compatible with Chrome DevTools and Perfetto.

use py_spy::{Config, FileFormat};

let mut config = Config::default();
config.format = Some(FileFormat::chrometrace);
config.include_thread_ids = true;          // Thread-based visualization
config.sampling_rate = 1000;               // High resolution

Features:

  • Timeline visualization with thread separation
  • Precise timing information
  • Compatible with chrome://tracing
  • Works with https://ui.perfetto.dev/

Raw Output

Text format compatible with flamegraph.pl and custom processing tools.

use py_spy::{Config, FileFormat};

let mut config = Config::default();
config.format = Some(FileFormat::raw);
config.full_filenames = true;              // Complete paths
config.show_line_numbers = true;           // Line information

Features:

  • Plain text format for scripting
  • Compatible with flamegraph.pl
  • Easy parsing for custom analysis
  • Suitable for CI/CD integration

Platform-Specific Configuration

Linux Configuration

// Core dump analysis (Linux only)
let mut config = Config::default();
config.core_filename = Some("/path/to/core.dump".to_string());

// Docker-aware profiling
config.blocking = LockingStrategy::NonBlocking; // May be required in containers

macOS Configuration

// macOS requires more conservative settings
let mut config = Config::default();
config.sampling_rate = 50;                 // Lower rate for stability
// Note: Requires root privileges (sudo)

Windows Configuration

// Windows-specific optimizations
let mut config = Config::default();
config.sampling_rate = 100;                // Standard rate works well
config.hide_progress = true;                // Better console compatibility

Error Handling

Configuration errors are typically reported through clap's error system when using from_args(), or through Result types in the library API.

use py_spy::Config;

// Handle CLI parsing errors
let config = match Config::from_args(&args) {
    Ok(config) => config,
    Err(e) => {
        eprintln!("Configuration error: {}", e);
        std::process::exit(1);
    }
};

// Validate configuration compatibility
if config.native && config.blocking == LockingStrategy::NonBlocking {
    eprintln!("Error: Native profiling requires blocking mode");
    std::process::exit(1);
}

Install with Tessl CLI

npx tessl i tessl/pypi-py-spy

docs

cli.md

config.md

index.md

rust-api.md

tile.json