Skip to content

feat: add provider_init_rate to telemetry - #485

Merged
nicklasl merged 9 commits into
mainfrom
session/grumpy-shrike-js36
Aug 24, 2026
Merged

feat: add provider_init_rate to telemetry#485
nicklasl merged 9 commits into
mainfrom
session/grumpy-shrike-js36

Conversation

@nicklasl

@nicklasl nicklasl commented Jul 16, 2026

Copy link
Copy Markdown
Member

Summary

  • Adds ProviderInitRate message to TelemetryData proto (field 9) with count and map<string, string> labels
  • On the first telemetry flush after provider initialization, each provider includes a ProviderInitRate{count: 1, labels: {encryption: "true"/"false"}} entry
  • Subsequent flushes carry no init data
  • WASM-based providers (JS, Java, Go, Python) deserialize the flush output, add the entry, and re-serialize — only on the first flush
  • Rust native provider sets it directly on TelemetryData

Companion backend PR: https://ghe.spotify.net/konfidens/epx-flags-resolver/pull/1699

Test plan

  • JS demo app verified: first flush contains provider_init_rate with correct labels, subsequent flushes do not
  • Run provider test suites (make test per provider)
  • Docker build (docker build .)
  • Verify confidence_resolver_sdk_provider_init_rate_total metric appears in VictoriaMetrics after backend PR lands

🤖 Generated with Claude Code

@nicklasl
nicklasl force-pushed the session/grumpy-shrike-js36 branch from 70c9540 to 2481fc6 Compare July 17, 2026 12:48
@nicklasl nicklasl changed the title feat: add encryption_enabled to telemetry feat: add provider_init_rate to telemetry Jul 17, 2026
@nicklasl
nicklasl force-pushed the session/grumpy-shrike-js36 branch from 2481fc6 to 7b04cc7 Compare July 17, 2026 13:23
@nicklasl
nicklasl marked this pull request as ready for review July 17, 2026 13:24
@nicklasl
nicklasl force-pushed the session/grumpy-shrike-js36 branch 6 times, most recently from a2f4e12 to 3505a52 Compare July 17, 2026 14:11
@nicklasl
nicklasl force-pushed the session/grumpy-shrike-js36 branch 2 times, most recently from 04960bb to 27d466f Compare August 21, 2026 11:53
nicklasl and others added 7 commits August 24, 2026 11:40
On the first telemetry flush after provider initialization, include
a ProviderInitRate entry with labels describing the SDK configuration
(e.g. encryption: true/false). This lets the backend track which
customers have adopted encryption without tagging every metric.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Codex <noreply@openai.com>
@nicklasl
nicklasl force-pushed the session/grumpy-shrike-js36 branch from 27d466f to 89fb845 Compare August 24, 2026 09:43
@nicklasl
nicklasl requested a review from vahidlazio August 24, 2026 11:25
id: SdkId.SDK_ID_JS_LOCAL_SERVER_PROVIDER,
version: VERSION,
};
decoded.telemetryData!.providerInitRate = [{ count: 1, labels: this.initLabels }];

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

other providers push but here we replace, can we use decoded.telemetryData!.providerInitRate.push({ count: 1, labels: this.initLabels }); to be consistent?

logger.warn('Primary flag log destination returned error, trying fallback');
continue;
}
throw new Error('Failed to send flag logs to all destinations');

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we didn't throw before, means failures were silently dropped, did we check that all callers handle this?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also, like other providers, js must also have some emit if not send in onClose i think like:

async onClose(): Promise<void> {
  await this.flush(timeoutSignal(3000));
  // Guarantee init telemetry even if flush() failed or returned empty
  if (this.initTelemetryState !== 'sent') {
    try {
      const request = WriteFlagLogsRequest.encode(
        WriteFlagLogsRequest.create({
          telemetryData: {
            sdk: { id: SdkId.SDK_ID_JS_LOCAL_SERVER_PROVIDER, version: VERSION },
            providerInitRate: [{ count: 1, labels: this.initLabels }],
          },
        }),
      ).finish();
      await this.sendFlagLogs(request, timeoutSignal(3000));
      this.initTelemetryState = 'sent';
    } catch {
      // best-effort — provider is shutting down
    }
  }
  this.main.abort();
}

if (!decoded.telemetryData) {
decoded.telemetryData = { resolverVersion: '', providerInitRate: [] };
}
decoded.telemetryData.sdk ??= {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: go and java always replace

@nicklasl
nicklasl merged commit c0e7dbe into main Aug 24, 2026
10 checks passed
@nicklasl
nicklasl deleted the session/grumpy-shrike-js36 branch August 24, 2026 13:23
@github-actions github-actions Bot mentioned this pull request Aug 24, 2026
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.

2 participants