getsentry / getsentry/sentry-python

Logs: array attribute values are silently dropped (and diverge from sentry-javascript)

Abierto
#6,441 5 comentarios 0 reacciones 0 asignados Ver en GitHub
Bug Logs Python
Lenguaje dominante
Python
Estrellas
2.2k
Forks
669
Merge medio
1 d 1 h
PR fusionados (30 d)
213

Descripción

### Environment

`sentry-sdk` 2.61.0, Python 3.14, logs enabled via `enable_logs=True`.

### What happened

Passing a list-valued attribute to `sentry_sdk.logger.*` results in the attribute **silently disappearing** from the Logs UI — no value, no warning, no debug log.

```python
sentry_sdk.logger.info(
"workflow_engine processed event",
attributes={
"workflow_ids": [101, 202, 303], # list[int] -> dropped (blank in UI)
"rule_names": ["high_cpu", "oom"], # list[str] -> dropped (blank in UI)
"organization_id": 42, # int -> stored OK
"mixed_list": [1, "two", 3.0], # mixed -> stored as the string "[1, 'two', 3.0]"
"nested_dict": {"a": [1, 2]}, # dict -> stored as the string "{'a': [1, 2]}"
},
)
```

Querying the log back (EAP `logs` dataset), the homogeneous scalar lists come back `null`, while the scalars and the *stringified* mixed/dict values are present.

### Root cause

`format_attribute` (sentry_sdk/utils.py:2125) preserves a **homogeneous** scalar `list`/`tuple` as a real array, but falls back to `safe_repr` (a string) for mixed lists and objects:

```python
elif isinstance(val, list):
ty = type(val[0])
if ty in (str, int, float, bool) and all(type(v) is ty for v in val):
return copy.deepcopy(val) # sent as a real array
...
return safe_repr(val) # everything else -> string
```

Sentry's log storage (EAP) only retains scalar attribute types (string / number / boolean), so the real arrays are dropped on ingestion. The net effect is counterintuitive: **homogeneous lists vanish, but mixed lists/objects survive (as strings).**

### Divergence from sentry-javascript

`@sentry/core` (v10.50) does the opposite for logs — `serializeAttributes(logAttributes, true)` runs with `fallback=true`, so **every** non-primitive (arrays and objects) is `JSON.stringify`'d into a string attribute and shows up. Its `attributes.js` even has an explicit comment that it intentionally does *not* send real arrays yet to avoid a future breaking change. So the same logging API gives different results across SDKs.

### Suggested fix

Make Python consistent with JS for now: stringify non-primitive attribute values (instead of sending homogeneous arrays that get dropped), or at minimum emit a debug log / drop-record when an attribute value can't be represented, so the loss isn't silent.

A docs note has been added in getsentry/sentry-docs#17921.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Guía de contribución

Abrir la guía de contribución

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.