Skip to content

Boolean evaluations are stored with an empty evaluation_value in ClickHouse analytics #6587

Description

@markphelps

Problem

When ClickHouse analytics is on, every boolean flag evaluation is stored with an empty evaluation_value (""). You can't tell enabled results from disabled ones, and nothing reports an error.

Cause

  • Boolean evaluations record the result as a bool span attribute: tracing.AttributeVariant.Bool(resp.Enabled). This happens in three places:
  • The analytics sink reads that attribute with v.Value.AsString() and doesn't check its type (sink.go:80-81). For a BOOL value, OTel's AsString() returns "".
  • The AttributeMatch case just above it does check attribute.BOOL.
  • "" is then inserted into evaluation_value Nullable(String) (clickhouse/mutation.go:31).

No Flipt API reads evaluation_value back, so the problem only shows up when you query ClickHouse directly or use dashboards built on it.

Reproduce

This test fails with expected: "true", actual: "":

internal/server/analytics/sink_bool_test.go
package analytics

import (
	"testing"
	"time"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	"go.flipt.io/flipt/internal/server/tracing"
	"go.opentelemetry.io/otel/attribute"
	sdktrace "go.opentelemetry.io/otel/sdk/trace"
)

// Mirrors the attributes emitted for boolean evaluations.
func TestTransformSpanEvent_BooleanEvaluationValue(t *testing.T) {
	ev := sdktrace.Event{
		Name: tracing.Event,
		Time: time.Now(),
		Attributes: []attribute.KeyValue{
			tracing.AttributeFlag.String("bool-flag"),
			tracing.AttributeVariant.Bool(true),
			tracing.AttributeFlagTypeBoolean,
		},
	}
	got, err := transformSpanEventToEvaluationResponses(ev)
	require.NoError(t, err)
	require.Len(t, got, 1)
	require.NotNil(t, got[0].EvaluationValue)
	assert.Equal(t, "true", *got[0].EvaluationValue, "boolean evaluation value lost")
}

Suggested fix

In the sink, switch on v.Value.Type() for AttributeVariant and format BOOL values as "true"/"false" (or use v.Value.Emit()). Also add a boolean case to TestSinkSpanExporter.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    buggosize:SThis PR changes 10-29 lines, ignoring generated files.v2Flipt v2

    Type

    No type

    Projects

    • Status
      No status
    • Status
      No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions