Graham Dumpleton: Finding slow... Note

Graham Dumpleton: Finding slow code with wrapture

The Flask shop's /order endpoint is slow, and the goal is to identify the bottleneck. Traditional stopwatch methods require code changes, produce unlinked log lines, and struggle with intermittent slowness. Profilers offer too much detail, obscuring request-specific information.Using the existing config, initial tracing immediately reveals a breakdown of times. The request takes 37.3ms, the view 36.3ms, the service 35.9ms, and the ledger 35.1ms, while the gateway is only 8us. This indicates the ledger is the primary cause of slowness.The concept of "self time" distinguishes operations that are slow themselves from those slow due to their children. Wrapture computes this, showing the ledger is slow in its own right, while the service and view are slow because they call the ledger.A test using wrapture.instrumentation and wrapture.timeline confirms this: the OrderService.place has a self time of 173us out of 31.0ms, while Ledger.record accounts for most of the duration. This level of detail is unavailable from standard profilers.For long-term monitoring, the Aggregate collector gathers statistics across many requests, including total, self, min, and max times. A report from sending thirty requests to the server confirms Ledger.record as the top contributor by self time.To track slowness per tenant, wrapture.annotate allows adding custom data like "X-Tenant" to in-flight events. This enables filtering traces to identify which tenants experience slower requests.The Counter collector provides a cheaper alternative, only counting operations without retaining durations, suitable for budget-based assertions in test suites (e.g., detecting N+1 query problems). The next step is feeding these events to a tracing backend.