Skip to content

feat: auto-provision Cloudflare Workers Observability trace/log destinations#193

Open
devin-ai-integration[bot] wants to merge 3 commits into
mainfrom
devin/cloudflare-observability-destinations
Open

feat: auto-provision Cloudflare Workers Observability trace/log destinations#193
devin-ai-integration[bot] wants to merge 3 commits into
mainfrom
devin/cloudflare-observability-destinations

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Jul 8, 2026

Copy link
Copy Markdown

Auto-provision Cloudflare Workers Observability telemetry destinations (traces + logs) after OAuth connection and expose their status in the Cloudflare integration UI.

What changed:

  • Added cloudflare_observability_destinations table + Drizzle migration (packages/db, packages/db/drizzle/0012_gigantic_night_thrasher.sql), keyed by (orgId, dataset).
  • Added CloudflareObservabilityDestination domain type and extended CloudflareIntegrationStatus with observabilityCapable/observabilityDestinations (packages/domain/src/http/integrations.ts).
  • Wrapped Workers.list/create/deleteObservabilityDestinations from @distilled.cloud/cloudflare in apps/api/src/lib/CloudflareApi.ts.
  • Added CloudflareObservabilityService that:
    • reads the Cloudflare OAuth token and org public ingest key
    • ensures Maple Traces${ingest}/v1/traces and Maple Logs${ingest}/v1/logs Workers Observability destinations
    • persists destination state (slug, enabled, last error, last sync), keyed by (orgId, dataset) to handle slug changes
    • skips the stale-row DELETE when the filtered list is empty
    • best-effort deletes Cloudflare-side destinations on disconnect
  • Added CloudflareObservabilityService.getDestinations for the status endpoint.
  • Wired CloudflareObservabilityService into MainLive (apps/api/src/app.ts) and the cloudflareDisconnect handler (apps/api/src/routes/integrations.http.ts) so cleanup runs while the OAuth token is still valid.
  • Provisioning is triggered only from the OAuth completeConnect callback, while cloudflareStatus remains a read-only GET.
  • Updated CloudflareAnalyticsService.getIntegrationStatus to set observabilityCapable.
  • Added an "Observability destinations" section to cloudflare-account-card.tsx showing each destination with status dots.

All provisioning errors are logged and swallowed (Effect.option + Effect.catchCause) so the connect and status endpoints cannot fail because of observability setup.

Validation:

  • Rebased on origin/main and re-generated the migration as 0012 to resolve a snapshot/journal conflict.
  • bun typecheck passes across all packages.
  • @maple/web builds successfully.
  • @maple/api vitest run passes (737 tests).
  • packages/db tests pass (journal timestamps + bundled migrations in PGlite).

Link to Devin session: https://app.devin.ai/sessions/52dd34fa74bc48c0bfd9ee31931b33be
Requested by: @Makisuo


Open in Devin Review

@Makisuo Makisuo self-assigned this Jul 8, 2026
@devin-ai-integration

Copy link
Copy Markdown
Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@pullfrog

pullfrog Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Your LLM provider API key was rejected. Rotate the key in your provider dashboard, then update the matching GitHub Actions secret.

Update repo secret → · Model settings → · Setup docs → · Ask in Discord →

Pullfrog  | ⚠️ this action is pinned to a commit SHA, which freezes the cleanup step — switch to @v0 or keep the SHA fresh with Dependabot | Rerun failed job ➔View workflow run | via Pullfrog | Using Claude Opus𝕏

devin-ai-integration[bot]

This comment was marked as resolved.

@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown

Ingest Rust Test + Benchmark Results

Commit: a327d5f852c83cc5f2af942e54ee2927c9bd544e

Load Benchmark — tinybird mode, median of 3 run(s) vs main

Metric main (median) PR (median) Delta
Requests/sec 2561.71 2670.08 +4.2% better
Rows/sec 25617.06 26700.75 +4.2% better
p50 latency 24.17 ms 23.68 ms -2.0% better
p95 latency 29.20 ms 25.84 ms -11.5% better
p99 latency 46.65 ms 35.23 ms -24.5% better
Export catch-up 0.026 s 0.026 s +1.8% worse
Max RSS 100.79 MiB 101.96 MiB +1.2% worse
Failures 0 0 same

Same code path on both sides (same LOAD_TEST_INGEST_MODE), so the delta column is meaningful. Numbers come from ubuntu-latest, which is noisy — treat single-digit-percent deltas as noise.

PR load benchmark JSON (per-iteration)
[
  {
    "ingest_mode": "tinybird",
    "requests": 2000,
    "successes": 2000,
    "failures": 0,
    "rows_sent": 20000,
    "rows_exported": 20000,
    "imports": 24,
    "duration_seconds": 0.827961391,
    "export_catchup_seconds": 0.026024879,
    "request_rps": 2415.5715734334285,
    "row_rps": 24155.715734334284,
    "p50_ms": 25.875,
    "p95_ms": 29.04,
    "p99_ms": 32.529,
    "max_rss_mb": 101.75390625,
    "max_cpu_percent": 77.1,
    "avg_cpu_percent": 46.849999999999994
  },
  {
    "ingest_mode": "tinybird",
    "requests": 2000,
    "successes": 2000,
    "failures": 0,
    "rows_sent": 20000,
    "rows_exported": 20000,
    "imports": 25,
    "duration_seconds": 0.749042597,
    "export_catchup_seconds": 0.025371999,
    "request_rps": 2670.0751172366236,
    "row_rps": 26700.751172366236,
    "p50_ms": 23.68,
    "p95_ms": 25.841,
    "p99_ms": 35.232,
    "max_rss_mb": 104.41796875,
    "max_cpu_percent": 85.7,
    "avg_cpu_percent": 59.5
  },
  {
    "ingest_mode": "tinybird",
    "requests": 2000,
    "successes": 2000,
    "failures": 0,
    "rows_sent": 20000,
    "rows_exported": 20000,
    "imports": 24,
    "duration_seconds": 0.726966866,
    "export_catchup_seconds": 0.026135321,
    "request_rps": 2751.1570245348703,
    "row_rps": 27511.570245348703,
    "p50_ms": 22.779,
    "p95_ms": 24.961,
    "p99_ms": 44.243,
    "max_rss_mb": 101.95703125,
    "max_cpu_percent": 85.7,
    "avg_cpu_percent": 51.150000000000006
  }
]
main load benchmark JSON (per-iteration)
[
  {
    "ingest_mode": "tinybird",
    "requests": 2000,
    "successes": 2000,
    "failures": 0,
    "rows_sent": 20000,
    "rows_exported": 20000,
    "imports": 24,
    "duration_seconds": 0.878115308,
    "export_catchup_seconds": 0.025308303,
    "request_rps": 2277.605209451604,
    "row_rps": 22776.052094516042,
    "p50_ms": 24.384,
    "p95_ms": 30.068,
    "p99_ms": 119.807,
    "max_rss_mb": 103.515625,
    "max_cpu_percent": 82.1,
    "avg_cpu_percent": 57.699999999999996
  },
  {
    "ingest_mode": "tinybird",
    "requests": 2000,
    "successes": 2000,
    "failures": 0,
    "rows_sent": 20000,
    "rows_exported": 20000,
    "imports": 24,
    "duration_seconds": 0.780729726,
    "export_catchup_seconds": 0.025556586,
    "request_rps": 2561.7059699351066,
    "row_rps": 25617.059699351066,
    "p50_ms": 24.166,
    "p95_ms": 29.202,
    "p99_ms": 46.651,
    "max_rss_mb": 100.03125,
    "max_cpu_percent": 82.4,
    "avg_cpu_percent": 57.85
  },
  {
    "ingest_mode": "tinybird",
    "requests": 2000,
    "successes": 2000,
    "failures": 0,
    "rows_sent": 20000,
    "rows_exported": 20000,
    "imports": 23,
    "duration_seconds": 0.705532514,
    "export_catchup_seconds": 0.026658466,
    "request_rps": 2834.7382442533326,
    "row_rps": 28347.382442533326,
    "p50_ms": 22.182,
    "p95_ms": 25.168,
    "p99_ms": 42.959,
    "max_rss_mb": 100.79296875,
    "max_cpu_percent": 85.9,
    "avg_cpu_percent": 50.050000000000004
  }
]

WAL-acked microbench (cargo bench --bench ingest_bench)

   Compiling maple-ingest v0.1.0 (/home/runner/work/maple/maple/apps/ingest)
    Finished `bench` profile [optimized] target(s) in 40.04s
     Running benches/ingest_bench.rs (target/release/deps/ingest_bench-581d2100de893627)
Gnuplot not found, using plotters backend
test ingest_accept/logs_10_rows_wal_ack ... bench:      444552 ns/iter (+/- 51487)
test ingest_accept/traces_10_spans_wal_ack ... bench:      416900 ns/iter (+/- 25972)

cargo test

test telemetry::tests::metrics_emit_exactly_the_jsonpaths_declared_in_datasources_ts ... ok
test telemetry::tests::metrics_summary_data_points_are_dropped ... ok
test telemetry::tests::pipeline_can_start_for_clickhouse_only_without_tinybird_credentials ... ok
test telemetry::tests::clickhouse_export_drops_passworded_non_https_endpoint_without_sending ... ok
test telemetry::tests::migrate_legacy_shard_relocates_frames_into_lanes ... ok
test telemetry::tests::pipeline_e2e_exports_gzip_ndjson_to_fake_tinybird ... ok
test telemetry::tests::pipeline_e2e_exports_traces_to_fake_tinybird ... ok
test telemetry::tests::sampling_keeps_errors_even_when_ratio_low ... ok
test telemetry::tests::scraper_contract::scraper_otlp_json_decodes_with_gateway_serde_and_encodes_to_rows ... ok
test telemetry::tests::signal_tag_round_trips_all_variants ... ok
test telemetry::tests::pipeline_e2e_exports_metrics_to_fake_tinybird ... ok
test telemetry::tests::telemetry_signal_as_str_is_canonical_lowercase ... ok
test telemetry::tests::timestamp_has_nano_precision ... ok
test telemetry::tests::timestamps_match_clickhouse_datetime64_nine_format ... ok
test telemetry::tests::trace_encoder_matches_tinybird_row_shape ... ok
test telemetry::tests::traces_emit_exactly_the_jsonpaths_declared_in_datasources_ts ... ok
test telemetry::tests::clickhouse_breaker_sheds_after_threshold_failures ... ok
test telemetry::tests::pipeline_exports_ready_org_to_clickhouse_without_tinybird_calls ... ok
test telemetry::tests::wal_round_trips_frame ... ok
test telemetry::tests::wal_partial_drain_advances_cursor_without_truncating ... ok
test telemetry::tests::slow_clickhouse_lane_does_not_block_cosharded_tinybird_org ... ok
test telemetry::tests::wal_truncates_after_full_drain_allowing_further_appends ... ok

test result: ok. 36 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.39s

     Running unittests src/bin/load_test.rs (target/debug/deps/load_test-661a0aa1eb3f6d6d)

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

     Running unittests src/main.rs (target/debug/deps/maple_ingest-c33bf80c577edb95)

running 38 tests
test autumn::tests::allowed_only_no_balance_field ... ok
test autumn::tests::flat_overage_allows ... ok
test autumn::tests::flat_hardcap_depleted_blocks ... ok
test autumn::tests::flat_hardcap_with_remaining_allows ... ok
test autumn::tests::flat_sub_one_gb_remaining_still_allows ... ok
test autumn::tests::flat_unlimited_allows ... ok
test autumn::tests::nested_overage_allows ... ok
test autumn::tests::null_balance_no_subscription_blocks ... ok
test autumn::tests::nested_balance_object_depleted_blocks ... ok
test autumn::tests::unrecognized_shape_returns_none ... ok
test tests::api_error_from_pipeline_maps_variants_to_status ... ok
test autumn::tests::nested_balance_object_with_remaining_allows ... ok
test tests::api_error_kind_maps_status_to_stable_label ... ok
test tests::clickhouse_destination_is_terminal_in_dual_mode ... ok
test tests::clickhouse_destination_uses_native_pipeline_even_in_forward_mode ... ok
test tests::clickhouse_target_resolver_rejects_password_over_http ... ok
test tests::cloudflare_log_record_maps_body_severity_and_attributes ... ok
test tests::clickhouse_target_resolver_requires_current_schema ... ok
test tests::cloudflare_ndjson_payload_parses_multiple_records ... ok
test tests::cloudflare_timestamps_support_rfc3339_unix_and_unix_nano ... ok
test tests::clickhouse_target_resolver_decrypts_current_schema_password ... ok
test tests::cloudflare_validation_payload_is_detected ... ok
test tests::decrypt_aes256_gcm_matches_node_crypto_fixture ... ok
test tests::enrichment_overwrites_tenant_fields ... ok
test tests::hash_is_deterministic ... ok
test tests::extract_ingest_key_returns_sentinel_literal_unchanged ... ok
test tests::rejection_span_status_is_error_only_for_5xx ... ok
test tests::resolve_ingest_key_keeps_stale_schema_on_managed_native_path ... ok
test tests::resolve_connector_refreshes_routing_before_auth_cache_expires ... ok
test tests::resolve_ingest_key_refreshes_routing_before_auth_cache_expires ... ok
test tests::resolve_ingest_key_returns_none_when_hash_missing ... ok
test tests::resolve_ingest_key_returns_self_managed_false_when_no_settings_row ... ok
test tests::resolve_ingest_key_returns_self_managed_true_when_active_settings_row ... ok
test tests::sentinel_token_matches_only_exact_literal ... ok
test tests::tinybird_destination_keeps_forward_mode_on_forward_path ... ok
test autumn::tests::fails_open_on_transport_error ... ok
test tests::resolve_ingest_key_serves_last_known_routing_when_refresh_fails ... ok
test tests::forward_mode_switches_ready_org_to_clickhouse_without_forwarding_again ... ok

test result: ok. 38 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.30s

   Doc-tests maple_ingest

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s

devin-ai-integration[bot]

This comment was marked as resolved.

devin-ai-integration Bot and others added 3 commits July 8, 2026 22:46
…nations and display them in the UI

Co-Authored-By: David Granzin <minetoaster12@gmail.com>
…ycle

Co-Authored-By: David Granzin <minetoaster12@gmail.com>
Co-Authored-By: David Granzin <minetoaster12@gmail.com>
@devin-ai-integration devin-ai-integration Bot force-pushed the devin/cloudflare-observability-destinations branch from a50c862 to 07184e8 Compare July 8, 2026 22:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant