chore(contrib): decouple HTTP client events with class-based subscribers#16374
chore(contrib): decouple HTTP client events with class-based subscribers#16374
Conversation
Codeowners resolved as |
a9f517b to
7ac8abe
Compare
|
b838b37 to
2168b78
Compare
Refactor the events API to separate pure data events from tracing logic: - Add TracedEvent base class (pure data, no tracing imports) - Rewrite HttpClientRequestEvent to extend TracedEvent with HTTP-specific fields - Create trace_subscribers package with SpanTracingSubscriber base class - Add HttpClientTracingSubscriber for shared HTTP client tracing logic - Update httpx and requests integrations to use new event field names - Update appsec handlers to use new event name (http.client.request) This enables integrations to publish events without importing tracing, while tracing, AppSec, and future products subscribe independently. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2168b78 to
4a11519
Compare
Performance SLOsComparing candidate conti/events-api-decoupled (4a11519) with baseline main (bbf9344) 📈 Performance Regressions (3 suites)📈 iastaspects - 118/118✅ add_aspectTime: ✅ 105.133µs (SLO: <130.000µs 📉 -19.1%) vs baseline: +4.2% Memory: ✅ 42.939MB (SLO: <46.000MB -6.7%) vs baseline: +4.4% ✅ add_inplace_aspectTime: ✅ 102.605µs (SLO: <130.000µs 📉 -21.1%) vs baseline: +0.5% Memory: ✅ 42.920MB (SLO: <46.000MB -6.7%) vs baseline: +4.9% ✅ add_inplace_noaspectTime: ✅ 28.319µs (SLO: <40.000µs 📉 -29.2%) vs baseline: +0.3% Memory: ✅ 43.214MB (SLO: <46.000MB -6.1%) vs baseline: +5.2% ✅ add_noaspectTime: ✅ 48.909µs (SLO: <70.000µs 📉 -30.1%) vs baseline: +0.4% Memory: ✅ 43.077MB (SLO: <46.000MB -6.4%) vs baseline: +4.5% ✅ bytearray_aspectTime: ✅ 249.576µs (SLO: <400.000µs 📉 -37.6%) vs baseline: -0.7% Memory: ✅ 43.136MB (SLO: <46.000MB -6.2%) vs baseline: +5.1% ✅ bytearray_extend_aspectTime: ✅ 654.523µs (SLO: <800.000µs 📉 -18.2%) vs baseline: +1.4% Memory: ✅ 42.939MB (SLO: <46.000MB -6.7%) vs baseline: +4.2% ✅ bytearray_extend_noaspectTime: ✅ 270.554µs (SLO: <400.000µs 📉 -32.4%) vs baseline: +0.7% Memory: ✅ 42.998MB (SLO: <46.000MB -6.5%) vs baseline: +4.5% ✅ bytearray_noaspectTime: ✅ 141.189µs (SLO: <300.000µs 📉 -52.9%) vs baseline: +1.3% Memory: ✅ 42.998MB (SLO: <46.000MB -6.5%) vs baseline: +4.5% ✅ bytes_aspectTime: ✅ 218.628µs (SLO: <300.000µs 📉 -27.1%) vs baseline: -0.8% Memory: ✅ 42.979MB (SLO: <46.000MB -6.6%) vs baseline: +4.6% ✅ bytes_noaspectTime: ✅ 134.057µs (SLO: <200.000µs 📉 -33.0%) vs baseline: -1.0% Memory: ✅ 43.155MB (SLO: <46.000MB -6.2%) vs baseline: +5.0% ✅ bytesio_aspectTime: ✅ 3.885ms (SLO: <5.000ms 📉 -22.3%) vs baseline: ~same Memory: ✅ 43.155MB (SLO: <46.000MB -6.2%) vs baseline: +5.1% ✅ bytesio_noaspectTime: ✅ 319.200µs (SLO: <420.000µs 📉 -24.0%) vs baseline: -0.7% Memory: ✅ 43.116MB (SLO: <46.000MB -6.3%) vs baseline: +5.2% ✅ capitalize_aspectTime: ✅ 88.899µs (SLO: <300.000µs 📉 -70.4%) vs baseline: +0.5% Memory: ✅ 43.077MB (SLO: <46.000MB -6.4%) vs baseline: +4.9% ✅ capitalize_noaspectTime: ✅ 259.437µs (SLO: <300.000µs 📉 -13.5%) vs baseline: +2.5% Memory: ✅ 43.037MB (SLO: <46.000MB -6.4%) vs baseline: +4.8% ✅ casefold_aspectTime: ✅ 88.954µs (SLO: <500.000µs 📉 -82.2%) vs baseline: ~same Memory: ✅ 42.998MB (SLO: <46.000MB -6.5%) vs baseline: +4.2% ✅ casefold_noaspectTime: ✅ 312.247µs (SLO: <500.000µs 📉 -37.6%) vs baseline: +0.2% Memory: ✅ 42.979MB (SLO: <46.000MB -6.6%) vs baseline: +4.7% ✅ decode_aspectTime: ✅ 87.018µs (SLO: <100.000µs 📉 -13.0%) vs baseline: ~same Memory: ✅ 43.136MB (SLO: <46.000MB -6.2%) vs baseline: +5.1% ✅ decode_noaspectTime: ✅ 153.580µs (SLO: <210.000µs 📉 -26.9%) vs baseline: -1.6% Memory: ✅ 43.077MB (SLO: <46.000MB -6.4%) vs baseline: +5.1% ✅ encode_aspectTime: ✅ 85.059µs (SLO: <200.000µs 📉 -57.5%) vs baseline: ~same Memory: ✅ 43.018MB (SLO: <46.000MB -6.5%) vs baseline: +4.8% ✅ encode_noaspectTime: ✅ 141.469µs (SLO: <200.000µs 📉 -29.3%) vs baseline: -2.0% Memory: ✅ 43.037MB (SLO: <46.000MB -6.4%) vs baseline: +4.9% ✅ format_aspectTime: ✅ 14.656ms (SLO: <19.200ms 📉 -23.7%) vs baseline: +0.2% Memory: ✅ 43.096MB (SLO: <46.000MB -6.3%) vs baseline: +4.6% ✅ format_map_aspectTime: ✅ 16.453ms (SLO: <21.500ms 📉 -23.5%) vs baseline: +0.2% Memory: ✅ 43.155MB (SLO: <46.000MB -6.2%) vs baseline: +4.7% ✅ format_map_noaspectTime: ✅ 376.592µs (SLO: <500.000µs 📉 -24.7%) vs baseline: -1.0% Memory: ✅ 43.037MB (SLO: <46.000MB -6.4%) vs baseline: +4.8% ✅ format_noaspectTime: ✅ 304.986µs (SLO: <500.000µs 📉 -39.0%) vs baseline: +0.9% Memory: ✅ 43.077MB (SLO: <46.000MB -6.4%) vs baseline: +4.9% ✅ index_aspectTime: ✅ 124.637µs (SLO: <300.000µs 📉 -58.5%) vs baseline: +3.8% Memory: ✅ 43.037MB (SLO: <46.000MB -6.4%) vs baseline: +4.7% ✅ index_noaspectTime: ✅ 40.552µs (SLO: <300.000µs 📉 -86.5%) vs baseline: +1.0% Memory: ✅ 43.077MB (SLO: <46.000MB -6.4%) vs baseline: +5.0% ✅ join_aspectTime: ✅ 212.709µs (SLO: <300.000µs 📉 -29.1%) vs baseline: ~same Memory: ✅ 43.175MB (SLO: <46.000MB -6.1%) vs baseline: +5.1% ✅ join_noaspectTime: ✅ 140.159µs (SLO: <300.000µs 📉 -53.3%) vs baseline: +0.2% Memory: ✅ 42.939MB (SLO: <46.000MB -6.7%) vs baseline: +4.3% ✅ ljust_aspectTime: ✅ 603.846µs (SLO: <700.000µs 📉 -13.7%) vs baseline: 📈 +16.9% Memory: ✅ 43.096MB (SLO: <46.000MB -6.3%) vs baseline: +4.8% ✅ ljust_noaspectTime: ✅ 257.465µs (SLO: <300.000µs 📉 -14.2%) vs baseline: ~same Memory: ✅ 42.900MB (SLO: <46.000MB -6.7%) vs baseline: +4.5% ✅ lower_aspectTime: ✅ 296.674µs (SLO: <500.000µs 📉 -40.7%) vs baseline: -0.4% Memory: ✅ 43.096MB (SLO: <46.000MB -6.3%) vs baseline: +4.8% ✅ lower_noaspectTime: ✅ 235.332µs (SLO: <300.000µs 📉 -21.6%) vs baseline: -0.3% Memory: ✅ 42.959MB (SLO: <46.000MB -6.6%) vs baseline: +4.6% ✅ lstrip_aspectTime: ✅ 0.279ms (SLO: <3.000ms 📉 -90.7%) vs baseline: +0.5% Memory: ✅ 42.959MB (SLO: <46.000MB -6.6%) vs baseline: +5.0% ✅ lstrip_noaspectTime: ✅ 0.181ms (SLO: <3.000ms 📉 -94.0%) vs baseline: +2.1% Memory: ✅ 43.136MB (SLO: <46.000MB -6.2%) vs baseline: +4.9% ✅ modulo_aspectTime: ✅ 14.384ms (SLO: <18.750ms 📉 -23.3%) vs baseline: +0.3% Memory: ✅ 43.214MB (SLO: <46.000MB -6.1%) vs baseline: +5.1% ✅ modulo_aspect_for_bytearray_bytearrayTime: ✅ 14.813ms (SLO: <19.350ms 📉 -23.4%) vs baseline: +0.1% Memory: ✅ 43.116MB (SLO: <46.000MB -6.3%) vs baseline: +4.8% ✅ modulo_aspect_for_bytesTime: ✅ 14.435ms (SLO: <18.900ms 📉 -23.6%) vs baseline: +0.1% Memory: ✅ 43.057MB (SLO: <46.000MB -6.4%) vs baseline: +4.7% ✅ modulo_aspect_for_bytes_bytearrayTime: ✅ 14.619ms (SLO: <19.150ms 📉 -23.7%) vs baseline: -0.5% Memory: ✅ 43.077MB (SLO: <46.000MB -6.4%) vs baseline: +4.9% ✅ modulo_noaspectTime: ✅ 0.359ms (SLO: <3.000ms 📉 -88.0%) vs baseline: ~same Memory: ✅ 43.136MB (SLO: <46.000MB -6.2%) vs baseline: +5.0% ✅ replace_aspectTime: ✅ 18.435ms (SLO: <24.000ms 📉 -23.2%) vs baseline: ~same Memory: ✅ 43.048MB (SLO: <46.000MB -6.4%) vs baseline: +4.3% ✅ replace_noaspectTime: ✅ 281.301µs (SLO: <300.000µs -6.2%) vs baseline: +0.6% Memory: ✅ 43.057MB (SLO: <46.000MB -6.4%) vs baseline: +4.5% ✅ repr_aspectTime: ✅ 312.294µs (SLO: <420.000µs 📉 -25.6%) vs baseline: -0.5% Memory: ✅ 43.175MB (SLO: <46.000MB -6.1%) vs baseline: +5.1% ✅ repr_noaspectTime: ✅ 46.589µs (SLO: <90.000µs 📉 -48.2%) vs baseline: +0.3% Memory: ✅ 42.979MB (SLO: <46.000MB -6.6%) vs baseline: +4.9% ✅ rstrip_aspectTime: ✅ 392.988µs (SLO: <500.000µs 📉 -21.4%) vs baseline: +0.5% Memory: ✅ 43.057MB (SLO: <46.000MB -6.4%) vs baseline: +4.8% ✅ rstrip_noaspectTime: ✅ 186.939µs (SLO: <300.000µs 📉 -37.7%) vs baseline: +0.6% Memory: ✅ 43.057MB (SLO: <46.000MB -6.4%) vs baseline: +5.0% ✅ slice_aspectTime: ✅ 183.738µs (SLO: <300.000µs 📉 -38.8%) vs baseline: ~same Memory: ✅ 43.175MB (SLO: <46.000MB -6.1%) vs baseline: +5.3% ✅ slice_noaspectTime: ✅ 53.941µs (SLO: <90.000µs 📉 -40.1%) vs baseline: +0.2% Memory: ✅ 43.116MB (SLO: <46.000MB -6.3%) vs baseline: +4.8% ✅ stringio_aspectTime: ✅ 3.936ms (SLO: <5.000ms 📉 -21.3%) vs baseline: +0.7% Memory: ✅ 43.155MB (SLO: <46.000MB -6.2%) vs baseline: +5.3% ✅ stringio_noaspectTime: ✅ 386.269µs (SLO: <500.000µs 📉 -22.7%) vs baseline: +8.7% Memory: ✅ 42.959MB (SLO: <46.000MB -6.6%) vs baseline: +4.5% ✅ strip_aspectTime: ✅ 275.182µs (SLO: <350.000µs 📉 -21.4%) vs baseline: -1.3% Memory: ✅ 42.959MB (SLO: <46.000MB -6.6%) vs baseline: +4.4% ✅ strip_noaspectTime: ✅ 179.901µs (SLO: <240.000µs 📉 -25.0%) vs baseline: +1.5% Memory: ✅ 43.037MB (SLO: <46.000MB -6.4%) vs baseline: +4.9% ✅ swapcase_aspectTime: ✅ 338.556µs (SLO: <500.000µs 📉 -32.3%) vs baseline: -0.3% Memory: ✅ 43.037MB (SLO: <46.000MB -6.4%) vs baseline: +4.6% ✅ swapcase_noaspectTime: ✅ 274.846µs (SLO: <400.000µs 📉 -31.3%) vs baseline: ~same Memory: ✅ 43.254MB (SLO: <46.000MB -6.0%) vs baseline: +5.1% ✅ title_aspectTime: ✅ 323.496µs (SLO: <500.000µs 📉 -35.3%) vs baseline: +0.1% Memory: ✅ 43.096MB (SLO: <46.000MB -6.3%) vs baseline: +4.9% ✅ title_noaspectTime: ✅ 263.398µs (SLO: <400.000µs 📉 -34.2%) vs baseline: +0.1% Memory: ✅ 43.254MB (SLO: <46.000MB -6.0%) vs baseline: +5.4% ✅ translate_aspectTime: ✅ 501.561µs (SLO: <700.000µs 📉 -28.3%) vs baseline: ~same Memory: ✅ 43.018MB (SLO: <46.000MB -6.5%) vs baseline: +4.6% ✅ translate_noaspectTime: ✅ 424.296µs (SLO: <500.000µs 📉 -15.1%) vs baseline: -1.6% Memory: ✅ 43.077MB (SLO: <46.000MB -6.4%) vs baseline: +4.6% ✅ upper_aspectTime: ✅ 295.852µs (SLO: <500.000µs 📉 -40.8%) vs baseline: -0.5% Memory: ✅ 43.195MB (SLO: <46.000MB -6.1%) vs baseline: +5.4% ✅ upper_noaspectTime: ✅ 237.961µs (SLO: <400.000µs 📉 -40.5%) vs baseline: ~same Memory: ✅ 43.018MB (SLO: <46.000MB -6.5%) vs baseline: +4.6% 📈 iastaspectsospath - 24/24✅ ospathbasename_aspectTime: ✅ 507.473µs (SLO: <700.000µs 📉 -27.5%) vs baseline: 📈 +18.8% Memory: ✅ 42.979MB (SLO: <46.000MB -6.6%) vs baseline: +4.8% ✅ ospathbasename_noaspectTime: ✅ 425.208µs (SLO: <700.000µs 📉 -39.3%) vs baseline: -0.3% Memory: ✅ 42.998MB (SLO: <46.000MB -6.5%) vs baseline: +4.9% ✅ ospathjoin_aspectTime: ✅ 618.242µs (SLO: <700.000µs 📉 -11.7%) vs baseline: +0.3% Memory: ✅ 43.077MB (SLO: <46.000MB -6.4%) vs baseline: +4.8% ✅ ospathjoin_noaspectTime: ✅ 622.729µs (SLO: <700.000µs 📉 -11.0%) vs baseline: ~same Memory: ✅ 43.057MB (SLO: <46.000MB -6.4%) vs baseline: +5.2% ✅ ospathnormcase_aspectTime: ✅ 349.956µs (SLO: <700.000µs 📉 -50.0%) vs baseline: +0.1% Memory: ✅ 43.037MB (SLO: <46.000MB -6.4%) vs baseline: +5.1% ✅ ospathnormcase_noaspectTime: ✅ 360.256µs (SLO: <700.000µs 📉 -48.5%) vs baseline: +0.7% Memory: ✅ 43.018MB (SLO: <46.000MB -6.5%) vs baseline: +4.9% ✅ ospathsplit_aspectTime: ✅ 493.308µs (SLO: <700.000µs 📉 -29.5%) vs baseline: +0.8% Memory: ✅ 42.979MB (SLO: <46.000MB -6.6%) vs baseline: +4.9% ✅ ospathsplit_noaspectTime: ✅ 498.866µs (SLO: <700.000µs 📉 -28.7%) vs baseline: ~same Memory: ✅ 42.959MB (SLO: <46.000MB -6.6%) vs baseline: +4.8% ✅ ospathsplitdrive_aspectTime: ✅ 373.172µs (SLO: <700.000µs 📉 -46.7%) vs baseline: +0.7% Memory: ✅ 43.096MB (SLO: <46.000MB -6.3%) vs baseline: +4.9% ✅ ospathsplitdrive_noaspectTime: ✅ 73.646µs (SLO: <700.000µs 📉 -89.5%) vs baseline: +0.2% Memory: ✅ 42.998MB (SLO: <46.000MB -6.5%) vs baseline: +5.0% ✅ ospathsplitext_aspectTime: ✅ 459.862µs (SLO: <700.000µs 📉 -34.3%) vs baseline: +0.3% Memory: ✅ 42.939MB (SLO: <46.000MB -6.7%) vs baseline: +4.6% ✅ ospathsplitext_noaspectTime: ✅ 464.474µs (SLO: <700.000µs 📉 -33.6%) vs baseline: ~same Memory: ✅ 42.959MB (SLO: <46.000MB -6.6%) vs baseline: +4.7% 📈 telemetryaddmetric - 30/30✅ 1-count-metric-1-timesTime: ✅ 3.520µs (SLO: <20.000µs 📉 -82.4%) vs baseline: 📈 +17.2% Memory: ✅ 35.527MB (SLO: <38.000MB -6.5%) vs baseline: +4.3% ✅ 1-count-metrics-100-timesTime: ✅ 203.922µs (SLO: <220.000µs -7.3%) vs baseline: -0.6% Memory: ✅ 35.625MB (SLO: <38.000MB -6.2%) vs baseline: +5.2% ✅ 1-distribution-metric-1-timesTime: ✅ 3.342µs (SLO: <20.000µs 📉 -83.3%) vs baseline: -0.5% Memory: ✅ 35.684MB (SLO: <38.000MB -6.1%) vs baseline: +5.0% ✅ 1-distribution-metrics-100-timesTime: ✅ 217.875µs (SLO: <230.000µs -5.3%) vs baseline: +0.3% Memory: ✅ 35.684MB (SLO: <38.000MB -6.1%) vs baseline: +5.1% ✅ 1-gauge-metric-1-timesTime: ✅ 2.185µs (SLO: <20.000µs 📉 -89.1%) vs baseline: +0.3% Memory: ✅ 35.783MB (SLO: <38.000MB -5.8%) vs baseline: +5.4% ✅ 1-gauge-metrics-100-timesTime: ✅ 135.524µs (SLO: <150.000µs -9.7%) vs baseline: -1.2% Memory: ✅ 35.665MB (SLO: <38.000MB -6.1%) vs baseline: +5.1% ✅ 1-rate-metric-1-timesTime: ✅ 3.149µs (SLO: <20.000µs 📉 -84.3%) vs baseline: -0.8% Memory: ✅ 35.566MB (SLO: <38.000MB -6.4%) vs baseline: +4.9% ✅ 1-rate-metrics-100-timesTime: ✅ 218.712µs (SLO: <250.000µs 📉 -12.5%) vs baseline: +0.3% Memory: ✅ 35.645MB (SLO: <38.000MB -6.2%) vs baseline: +5.0% ✅ 100-count-metrics-100-timesTime: ✅ 20.370ms (SLO: <22.000ms -7.4%) vs baseline: -0.2% Memory: ✅ 35.625MB (SLO: <38.000MB -6.2%) vs baseline: +4.8% ✅ 100-distribution-metrics-100-timesTime: ✅ 2.271ms (SLO: <2.550ms 📉 -10.9%) vs baseline: +1.1% Memory: ✅ 35.684MB (SLO: <38.000MB -6.1%) vs baseline: +5.0% ✅ 100-gauge-metrics-100-timesTime: ✅ 1.393ms (SLO: <1.550ms 📉 -10.2%) vs baseline: ~same Memory: ✅ 35.684MB (SLO: <38.000MB -6.1%) vs baseline: +5.4% ✅ 100-rate-metrics-100-timesTime: ✅ 2.217ms (SLO: <2.550ms 📉 -13.1%) vs baseline: -0.3% Memory: ✅ 35.606MB (SLO: <38.000MB -6.3%) vs baseline: +5.0% ✅ flush-1-metricTime: ✅ 4.530µs (SLO: <20.000µs 📉 -77.4%) vs baseline: -0.3% Memory: ✅ 35.586MB (SLO: <38.000MB -6.4%) vs baseline: +4.9% ✅ flush-100-metricsTime: ✅ 172.903µs (SLO: <250.000µs 📉 -30.8%) vs baseline: -0.2% Memory: ✅ 35.625MB (SLO: <38.000MB -6.2%) vs baseline: +4.8% ✅ flush-1000-metricsTime: ✅ 2.185ms (SLO: <2.500ms 📉 -12.6%) vs baseline: ~same Memory: ✅ 36.372MB (SLO: <38.750MB -6.1%) vs baseline: +4.6%
|
Summary
Refactors the events API to cleanly separate pure data events from tracing logic, following the architecture where integrations publish events and products (tracing, AppSec, etc.) subscribe independently.
Key changes:
TracedEventbase class (events.py): Pure data class holding common span metadata (span_name, span_type, tags, integration_config, etc.). No tracing imports. Overrides__init_subclass__to skip ContextEvent's auto-registration since subscribers handle everything.HttpClientRequestEvent(contrib/events/http_client.py): Rewritten from 85 lines with tracing logic → 25 lines of pure data extending TracedEvent. Zero tracing imports.trace_subscriberspackage (_trace/trace_subscribers/): New class-based subscriber pattern withTracingSubscriber(auto-registers via__init_subclass__) andSpanTracingSubscriber(handles span lifecycle).HttpClientTracingSubscriber: Shared tracing logic for all HTTP client integrations — propagation injection,set_http_metafor tags.HttpClientRequestEventwith new field names and set response data viactx.set_item().httpx.request→http.client.request(now shared across all HTTP clients).Architecture:
Based on:
dubloom/events-apianddubloom/events-api-httpbranches, refactored per the decoupling plan.Test plan
ddtrace/contrib/events/http_client.pyhatch run lint:fmtandhatch run lint:checkspass🤖 Generated with Claude Code