Task board
sf2loki
Streams Salesforce Event Monitoring into Grafana Loki — Pub/Sub API, SOQL and EventLogFile ingestion, cardinality-disciplined by default.
71 open, 2 completed ·Completed work · Milestones· Repository
No tasks match these filters. Clear them to see all tasks.
To Do71
SFL-0001Don't promote service.version to a per-series metric label (OTLP→Prometheus: version belongs on target_info/build_info)SFL-0002pipeline: a shutdown-abandoned batch is silently leapfrogged by the next same-key commit - undelivered events lostSFL-0003eventlog_objects: no visibility-lag bound - rows that become queryable after the watermark passed their timestamp are lost silentlySFL-0004egress: only one of two budget-pause waiters detects the UTC-day rollover - the other lane stalls ~24h while readiness reports readySFL-0005backfill: entries omit the deployment identity labels (job/service_name/environment/sf_org_id) and the org labelSFL-0006obs: idle/transition-only gauges stop exporting and noDataState: Ok hides it - no-recent-push, leader-anomaly and api-limit-low alerts can't be trustedSFL-0007sources: dual wildcard (pubsub `topics: ["*"]` + eventlogfile `event_types: ["*"]`) silently double-ingests every shared categorySFL-0008pubsub: bridge byte budget is never reset per run - charges leaked on a mid-drain teardown stall every topic after leadership re-acquisitionSFL-0009apexlog: a single transient body-download failure permanently loses the log body — no retry, and the checkpoint advances past itSFL-0010salesforce: a 2xx SOQL response with a non-JSON body escapes the SoqlError family and crash-loops the processSFL-0011eventlog_objects: the big-object tie escape grows Id NOT IN without bound - a >~500-row tie group halts the object permanentlySFL-0012coordinate: file lease blind-rewrites the lease when the verify re-read also fails — residual #50 window, and the epoch fence regressesSFL-0013ha: an epoch-fenced stale leader shuts the whole process down (exit 0) instead of demoting to standbySFL-0014coordinate: k8s_lease has no epoch fence - a stale leader can still regress a shared file checkpoint storeSFL-0015coordinate: a lost/corrupt lease file resets the fence epoch to 1 and the legitimate leader fences itself out of its own checkpointsSFL-0016obs: multi-org deployments emit no watermark_ts / last_replay_commit_ts (the org= key prefix defeats the prefix match)SFL-0017cli: doctor never probes the real state file, its .lock sidecar, or the lease file - an unreadable one passes preflight and crash-loops the daemonSFL-0018cli: `sf2loki state` lock refusal never fires under a non-noop coordinator - the live leader silently reverts an operator's checkpoint repairSFL-0019eventlogfile: guard the checkpoint decode - a bare-timestamp or garbage watermark crash-loops the daemon or permanently stalls the typeSFL-0020backfill: unbounded memory - whole ELF CSVs materialized as row lists, with download lookahead bounded only by page_sizeSFL-0021obs: ingest-lag alert breaches on every EventLogFile drain - label sf2loki_ingest_lag_seconds by source and alert per sourceSFL-0022grafana: ELF-scoped Loki alert and recording rules query trailing 5-10m windows EventLogFile timestamps never occupy - they can never fire or recordSFL-0023grafana: security dashboard country panels extract COUNTRY_CODE, a field the Login EventLogFile row does not haveSFL-0024obs: apex-performance callout latency panels unwrap RUN_TIME, which Salesforce leaves unpopulated for ApexCallout - use TIMESFL-0025auth: org_id() userinfo auth failure never invalidates the cached token - multi-org pubsub topics stay unsubscribed for up to token_ttlSFL-0026sources: multi-org org-id resolution re-runs a failing userinfo fetch per entry, silently — negative-cache it, log once, and resolve it in the startup probeSFL-0027tests: k8s lease hold/acquire error branches are untested - the renew-409 CAS surrender has no covering testSFL-0028tests: the ApexLog compound (StartTime, Id) cursor SOQL from the #39 fix is asserted nowhereSFL-0029tests: pin the ApexLog error-recovery paths - listing failure, mid-page throttle abort, body-download fallbackSFL-0030tests: pin the leadership-lifecycle paths in app.py that no test executes (fence absorption, poller teardown, finite-run completion)SFL-0031tests: the CLI backfill success path is entirely uncovered - org identity and argument wiring can regress silentlySFL-0032cli: doctor's Loki test write uses a bare payload — a backend that rejects structured metadata passes preflight, then drops 100% of real dataSFL-0033sink: dead-letter capture + replay for permanently dropped entriesSFL-0034shaping: runtime cardinality guard for promoted per-type stream labelsSFL-0035cli: doctor's pubsub probe discards TopicInfo.can_subscribe - a topic the integration user cannot subscribe to reports PASSSFL-0036obs: local /statusz snapshot endpoint - runtime state is unreachable when OTLP metrics are off or the collector is downSFL-0037cli: backfill --dry-run — preview file count, source bytes and API calls before pushing a historical windowSFL-0038pubsub: wildcard topic discovery only matches *EventStream - the Event/EventStore RTEM family (Threat Detection anomaly channels) is never discoveredSFL-0039sink: per-org Loki tenant fan-out (X-Scope-OrgID routing) for multi-org isolationSFL-0040ha: object-store lease coordinator (s3_lease / gcs_lease) for stateless platformsSFL-0041security: scrub inline URL credentials from the startup banner and doctor endpoint outputSFL-0042eventlogfile: a throttled EventType discovery doesn't seed the cycle's throttle gate - the first `concurrency` types still burn the exhausted budget and the tail types silently starveSFL-0043eventlog_objects: big-object drain re-emits a >500-row timestamp tie group every poll cycle (capped dedup window has no at-watermark exemption)SFL-0044config: reject org/sf_org_id/environment in sink.loki.labels under multi-org (static labels silently clobber per-org identity)SFL-0045state: a retried s3/gcs conditional write manufactures a false CAS conflict after a lost response - verify before crashingSFL-0046state: the s3 checkpoint body read and JSON parse sit outside the transient-retry envelope (#44 follow-up)SFL-0047config: a blank secret is treated as present — an empty inline/env value shadows *_file and an empty secret file resolves to SecretStr('')SFL-0048cli: run/backfill dump a traceback (exit 1) for non-ConfigError wiring failures - overlap and label-guard errors bypass the documented exit-2 contractSFL-0049backfill: checkpoints always go to a local file derived from state.file.path, ignoring state.store — no resumable backfill on s3/gcs deploymentsSFL-0050cli: backfill --event-types skips the SOQL-identifier guard config enforces, and "*" silently backfills nothingSFL-0051deploy: docker-compose/Helm memory sizing predates the per-lane queue split - stated ceiling is 256 MiB below the documented worst caseSFL-0052auth: invalidate() clears any cached token, so a stale-token 401 discards a freshly minted one (redundant re-mint churn)SFL-0053config: salesforce.token_ttl has no lower bound - a value at or below the 60s refresh skew re-mints a token on every Salesforce API callSFL-0054tests: pin the untested legs of the s3/gcs checkpoint retry classifier (raw 5xx, OSError family, non-Exception)SFL-0055tests: big-object drain SoqlError containment and the DESC no-progress stall guard are untestedSFL-0056tests: multi-org App.run() startup branch is never executed - deployment_static_labels has no testSFL-0057tests: pin the file-lease coordinator's write-failure, verify-read-error, renewal-tolerance and corrupt-lease branchesSFL-0058tests: pin the EventLogFile cycle unwind on early aclose/cancel and the mid-file throttle abortSFL-0059cli: state export/import for migrating checkpoints between backends (file -> s3/gcs)SFL-0060cli: doctor only ever checks one org — add `--all-orgs` for a whole-deployment preflightSFL-0061obs: sf2loki_loki_entries_dropped carries only `reason` - attribute drops by source/event_type/orgSFL-0062pubsub: opt-in ManagedSubscribe mode - server-side replay commits via Managed Event SubscriptionsSFL-0063sink: optional S3 archive tee (WORM/Object Lock) for long-term compliance retentionSFL-0064state: Azure Blob checkpoint store backendSFL-0065obs: optional OTel traces over the already-shipped OTLP exporter for per-stage pipeline timelinesSFL-0066salesforce: SOQL interpolation guards are inconsistent - apexlog Id cursor unescaped, backfill --event-types unvalidatedSFL-0067helm: don't automount the ServiceAccount API token unless the pod actually talks to the API serverSFL-0068deploy: docker-compose runs unhardened (no read_only / cap_drop / no-new-privileges) and the image chowns /app to the runtime uidSFL-0069dist: pin the build toolchain for the PyPI publish job - uv and the hatchling build backend resolve unpinned at release timeSFL-0070helm: lease RBAC silently binds to the namespace `default` ServiceAccount when serviceAccount.create=false with no nameSFL-0071docs: the Kubernetes hardening claim is false - podSecurityContext/securityContext are plain overridable values