[sdk/local-evaluation] getEnvironmentFlags() evaluations are not tracked for analytics
Ninguém assumiu esta issue ainda.
Avaliação
- Dificuldade
- 2/5
- Tempo estimado
- Menos de uma hora
- Facilidade para iniciantes
- 85/100
- Tipo de issue
- Bug
- Clareza
- Claramente especificada
- Status de atividade
- Ativa
- Stack de tecnologia
- nodejs, typescript
- Domínio
- analytics
Direção de pesquisa
A issue aponta para getEnvironmentFlagsFromDocument em sdk/index.ts, por volta da linha 640, onde Flags.fromEvaluationResult é chamado sem o processador de analytics. Compare com getIdentityFlagsFromDocument, perto da linha 669, que já passa this.analyticsProcessor. Execute o script de reprodução da issue: está concluído quando a execução local reportar {"my_feature":5}, como a execução remota.
Escrita pelo modelo de indexação a partir do texto da issue.
Descrição
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.
- Linguagem predominante
- TypeScript
- Estrelas
- 30
- Forks
- 29
- Merge médio
- 9d 9h
- PRs com merge (30d)
- 2
Preparar o ambiente
- Sem Dockerfile nem arquivo Docker Compose
- Tem um modelo de pull request
- Ler o guia de contribuição
Primeiros passos
- Leia a issue inteira e depois o guia de contribuição do projeto.
- Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
- Faça um fork do repositório e trabalhe em uma branch.
- Abra um pull request que referencie o número da issue.
Mais de Flagsmith/flagsmith-nodejs-client
-
Dificuldade 4/5 3-5 dias Facilidade para iniciantes 65/100
-
Dificuldade 4/5 3-5 dias Facilidade para iniciantes 48/100
-
Dependency DashboardAberta
Dificuldade 4/5 3-5 dias Facilidade para iniciantes 25/100
-
Dificuldade 4/5 3-5 dias Facilidade para iniciantes 55/100
Flagsmith/flagsmith-nodejs-client#273 · 1 comentário ·
-
[sdk/local-evaluation] Duplicate identity override entries silently drop feature overridesTalvez já em andamento @xolott-ark assumiu há 162 dias. Aberta
Dificuldade 3/5 1-2 dias Facilidade para iniciantes 68/100
Flagsmith/flagsmith-nodejs-client#267 · 5 comentários ·
Todas as issues de Flagsmith/flagsmith-nodejs-client
Issues semelhantes
-
`cf complete zsh >> .zshrc` fails on vanilla zshTalvez livre de novo Um pull request para esta issue foi fechado sem ser mesclado. Aberta
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 75/100
cloudflare/cf#340 ·
Mantenedores costumam responder em até 1 dia
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 72/100
-
Rename Madson cameraAberta
Dificuldade 2/5 Menos de uma hora Facilidade para iniciantes 75/100
StoDevX/AAO-React-Native#8785 ·
Mantenedores costumam responder em até 1 dia
-
Broken links in the docsAberta
Dificuldade 1/5 Menos de uma hora Facilidade para iniciantes 75/100
-
bnv-manager-v2: accept_invite creates the Mailcow domain admin before the commitTalvez já em andamento @myOmikron assumiu hoje. Abertabug ready-for-agent
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 82/100