[sdk/local-evaluation] getEnvironmentFlags() evaluations are not tracked for analytics
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 2/5
- Tempo stimato
- Meno di un'ora
- Idoneità per principianti
- 85/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Attiva
- Stack tecnologico
- nodejs, typescript
- Ambito
- analytics
Direzione di ricerca
La segnalazione punta a getEnvironmentFlagsFromDocument in sdk/index.ts intorno alla riga 640, dove Flags.fromEvaluationResult viene chiamato senza l'analytics processor. Confrontalo con getIdentityFlagsFromDocument vicino alla riga 669, che passa già this.analyticsProcessor. Esegui lo script di riproduzione della issue: è completato quando l'esecuzione locale riporta {"my_feature":5}, come quella remota.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Problem
With enableLocalEvaluation: true, flag evaluations from getEnvironmentFlags() are never counted towards analytics. The same code against the same environment reports usage correctly when local evaluation is off, so flag analytics are effectively unavailable to anyone evaluating locally.
The cause looks like a missed argument in getEnvironmentFlagsFromDocument:
// sdk/index.ts:640
const flags = Flags.fromEvaluationResult(evaluationResult);
The other three evaluation paths all pass the processor through:
getIdentityFlagsFromDocument(local) ->sdk/index.ts:669, passesthis.analyticsProcessorgetEnvironmentFlagsFromApi(remote) ->sdk/index.ts:689getIdentityFlagsFromApi(remote) ->sdk/index.ts:710
Since the other local path already tracks, this doesn't look like a deliberate decision to skip analytics during local evaluation.
For what it's worth, the Python client passes it in the equivalent method, so the two SDKs behave differently here:
# flagsmith/flagsmith.py:535, _get_environment_flags_from_document
return Flags.from_evaluation_result(
evaluation_result=evaluation_result,
analytics_processor=self._analytics_processor,
default_flag_handler=self.default_flag_handler,
)
Impact
getEnvironmentFlags() is the common path for server-side usage, and local evaluation is the recommended mode there, so this combination silently reports no usage at all. Nothing warns or errors, and the dashboard just shows the flag as unused. We ran into it while using analytics to decide which stale flags were safe to delete, where a flag wrongly showing zero evaluations is the dangerous direction to be wrong in.
Reproduction
Standalone script, no account needed; it stubs the API locally and compares the two modes.
const http = require('node:http');
const { Flagsmith } = require('flagsmith-nodejs');
const ENV_DOC = {
api_key: 'ser.repro',
project: { id: 1, name: 'repro', organisation: { id: 1, name: 'org', feature_analytics: true,
stop_serving_flags: false, persist_trait_data: true }, hide_disabled_flags: false, segments: [] },
feature_states: [{ feature: { id: 1, name: 'my_feature', type: 'STANDARD' },
enabled: true, feature_state_value: null, featurestate_uuid: 'fs-1', multivariate_feature_state_values: [] }],
identity_overrides: []
};
const API_FLAGS = [{ feature: { id: 1, name: 'my_feature', type: 'STANDARD' },
enabled: true, feature_state_value: null }];
(async () => {
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'application/json' });
if (req.url.includes('environment-document')) return res.end(JSON.stringify(ENV_DOC));
if (req.url.includes('/flags')) return res.end(JSON.stringify(API_FLAGS));
res.end('{}');
});
await new Promise(r => server.listen(0, '127.0.0.1', r));
const apiUrl = `http://127.0.0.1:${server.address().port}/api/v1/`;
async function run(local) {
const f = new Flagsmith({ environmentKey: 'ser.repro', apiUrl,
enableLocalEvaluation: local, enableAnalytics: true });
const flags = await f.getEnvironmentFlags();
for (let i = 0; i < 5; i++) await flags.isFeatureEnabled('my_feature');
const buf = { ...(f.analyticsProcessor?.analyticsData ?? {}) };
f.environmentDataPollingManager?.stop();
console.log(`${local ? 'LOCAL ' : 'REMOTE'} -> buffer ${JSON.stringify(buf)}`);
}
await run(true);
await run(false);
server.close();
})();
Observed:
LOCAL -> buffer {}
REMOTE -> buffer {"my_feature":5}
Expected: both report {"my_feature":5}.
Version: [email protected] (current npm latest), Node 24.13.0. Line numbers above are from main as of today, which still has the same call.
Workaround
Calling trackFeature(name) on the processor after each evaluation restores the counts, which is what we're doing for now.
- Lingua principale
- TypeScript
- Stelle
- 30
- Fork
- 28
- Merge medio
- 7g 23h
- PR unite (30g)
- 3
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di Flagsmith/flagsmith-nodejs-client
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 65/100
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 48/100
-
Dependency DashboardAperta
Difficoltà 4/5 3-5 giorni Idoneità per principianti 25/100
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 55/100
Flagsmith/flagsmith-nodejs-client#273 · 1 commento ·
-
[sdk/local-evaluation] Duplicate identity override entries silently drop feature overridesForse già presa @xolott-ark l’ha presa 158 giorni fa. Aperta
Difficoltà 3/5 1-2 giorni Idoneità per principianti 68/100
Flagsmith/flagsmith-nodejs-client#267 · 5 commenti ·
Tutte le issue di Flagsmith/flagsmith-nodejs-client
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
NaturalIntelligence/fast-xml-parser#890 · 1 commento ·
I maintainer di solito rispondono entro 3 giorni
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 62/100
zsviczian/obsidian-excalidraw-plugin#3000 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
pnpm/get.pnpm.io#68 ·
-
[BUG] Cloudflare KV binding 模式下 kvDriver.list() 沿用 EdgeOne 语义,字段名不匹配导致 key 格式下初始化 500 并耗尽 list 配额Forse già presa @wumingzhinu l’ha presa oggi. Apertabug
Difficoltà 2/5 1-3 ore Idoneità per principianti 64/100
OpenListTeam/OpenList-Worker#125 ·
I maintainer di solito rispondono entro 2 giorni
-
Android (vision-camera-location): HybridLocationManager never quits its HandlerThread on disposeAperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 74/100
margelo/react-native-vision-camera#4217 ·
I maintainer di solito rispondono entro 4 giorni