# `Otel.Logs.LogRecordLimits`
[🔗](https://github.com/yangbancode/otel/blob/main/lib/otel/logs/log_record_limits.ex#L1)

Configurable limits for `Otel.Logs.LogRecord` attribute
collections (`logs/sdk.md` §LogRecord Limits L321-348).

Holds the two limit values and exposes a single `apply/2`
entry point that returns the limited `LogRecord` together
with the dropped-attributes count for the orchestrator to
forward into `Otel.Logs.LogRecord.dropped_attributes_count`.
Composition ordering and the spec-required discard message
(`logs/sdk.md` L345-348) remain the orchestrator's
responsibility — see `Otel.Logs.Logger.emit/2`.

## Configurable parameters

| Field | Default | Spec |
|---|---|---|
| `attribute_count_limit` | `128` | `common/README.md` L305 — *"Maximum allowed attribute count per record"* |
| `attribute_value_length_limit` | `:infinity` | `common/README.md` L306 — *"Maximum allowed attribute value length (applies to string values and byte arrays)"* |

Both fields accept any `t:non_neg_integer/0` (per the
spec value-range definition in `sdk-environment-variables.md`
L197-L204 *"Valid values are non-negative"*) — `0` is a
valid setting that drops every attribute or truncates every
value to empty.

## Configuration sources

Spec env vars `OTEL_LOGRECORD_ATTRIBUTE_COUNT_LIMIT` and
`OTEL_LOGRECORD_ATTRIBUTE_VALUE_LENGTH_LIMIT` are not read.
Minikube hardcodes the spec defaults; `Otel.Logs.Logger`
carries the limits as a compile-time literal
(`@log_record_limits`) and there is no runtime override.

## Truncation rules

`LogRecord.attributes` values are the full
`t:primitive_any/0` per spec
(`opentelemetry-proto/opentelemetry/proto/logs/v1/logs.proto`
L178 — `repeated KeyValue` where `KeyValue.value = AnyValue`).
Truncation applies recursively per `common/README.md`
L260-L274:

| Value shape | Truncation |
|---|---|
| `String.t()` | character (grapheme) count via `String.slice/3` (spec L262-263 *"counting any character in it as 1"*) |
| `{:bytes, binary()}` | byte count via `binary_part/3` (spec L265-267 *"counting each byte as 1"*) |
| `[primitive_any()]` | element-wise recursion — covers both homogeneous primitive arrays (spec L268-269) and heterogeneous AnyValue arrays (spec L270-271) |
| `%{String.t() => primitive_any()}` | recursion over map values (spec L272-273) |
| `boolean()`, `integer()`, `float()`, `nil` | passes through unchanged (spec L274 *"otherwise a value MUST NOT be truncated"*) |

## References

- OTel Logs SDK §LogRecord Limits: `opentelemetry-specification/specification/logs/sdk.md` L321-348
- OTel Common §Attribute Limits: `opentelemetry-specification/specification/common/README.md` L249-299
- OTel Common §Configurable Parameters: `opentelemetry-specification/specification/common/README.md` L303-306
- Mapping to non-OTLP §Dropped Attributes Count: `opentelemetry-specification/specification/common/mapping-to-non-otlp.md` L73-79
- Env vars: `opentelemetry-specification/specification/configuration/sdk-environment-variables.md` L197-L204

# `primitive`

```elixir
@type primitive() ::
  String.t() | {:bytes, binary()} | boolean() | integer() | float() | nil
```

# `primitive_any`

```elixir
@type primitive_any() ::
  primitive() | [primitive_any()] | %{required(String.t()) =&gt; primitive_any()}
```

# `t`

```elixir
@type t() :: %Otel.Logs.LogRecordLimits{
  attribute_count_limit: non_neg_integer(),
  attribute_value_length_limit: non_neg_integer() | :infinity
}
```

# `apply`

```elixir
@spec apply(log_record :: Otel.Logs.LogRecord.t(), limits :: t()) ::
  {Otel.Logs.LogRecord.t(), non_neg_integer()}
```

Applies all attribute limits to a `LogRecord`.

Returns `{limited_record, dropped_attributes_count}`. The
count is the size delta from the count-limit drop step
(truncation precedes drop and preserves map size, so the
delta is exclusively the dropped-attribute count that
belongs in `Otel.Logs.LogRecord.dropped_attributes_count`
and the OTLP proto field of the same name).

# `new`

```elixir
@spec new(opts :: map()) :: t()
```

**SDK** — Construct log-record limits. Defaults match
`logs/sdk.md` §LogRecord Limits.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
