Skip to content

Product telemetry#

Lens Agents emits product telemetry as OpenTelemetry log records. Telemetry helps Lens improve the platform and helps operators understand usage patterns. No conversation content, prompts, responses, tool-call arguments, or file contents are ever included.

The full catalogue is 57 events, listed below. All of them are emitted by the platform server itself.


Emission semantics#

Who emits what#

Every event comes from the platform server, through one OpenTelemetry LoggerProvider carrying these resource attributes:

Resource attribute Value
service.name lens-agents-backend
service.namespace lens-agents
service.version The platform version
deployment.environment.name config.deploymentEnvironment

Transport#

Events are sent as batched OTLP/HTTP log records to {OTEL_EXPORTER_OTLP_ENDPOINT}/v1/logs. A BatchLogRecordProcessor handles queuing and retry. When OTEL_EXPORTER_OTLP_ENDPOINT is unset or empty, the telemetry subsystem is a full no-op — no buffering, no network calls.

User attribution#

An actor is resolved to a user.id only when a person did the thing:

Auth context type Resolved user.id Rationale
oidc OIDC subject ID Human user actions are attributed
api-token undefined (omitted) The event fires but is unattributed — the count is accurate, the actor is the token itself
sandbox undefined (omitted) Agent-initiated actions are not attributed to a person
cluster-jwt undefined (omitted) Cluster-initiated actions are not user-attributed

When user.id is undefined the attribute is omitted entirely from the log record — downstream systems can filter on its presence to separate human-initiated from machine-initiated events.

What is NOT instrumented#

Ordinary read operations do not emit telemetry events. The instrumented set is state-mutating actions — create, update, delete, rotate, revoke, issue — plus MCP session start and end, aggregate tool-usage counts, and periodic snapshots of running sandboxes and connectors.


Configuration#

Two environment variables control telemetry for both the agent runtime and the control plane:

Variable Required Description
OTEL_EXPORTER_OTLP_ENDPOINT No Base URL of the OTLP/HTTP collector. Released images bake in a Lens-operated endpoint, so leaving this unset does not mean nothing is sent.
OTEL_EXPORTER_OTLP_API_KEY No Passed as the x-api-key header to the collector. Use when your collector requires authentication.

Helm values#

Value Default Purpose
telemetry.enabled true Master switch. Always rendered into the ConfigMap. Set false to send nothing at all.
telemetry.endpoint (empty) OTLP/HTTP collector base URL. Empty falls through to the endpoint baked into the image, not to "off".
telemetry.apiKey (empty) Sent as x-api-key when your collector requires authentication.
telemetry.existingSecret (empty) Read the API key from an existing Secret instead.
telemetry.existingSecretKey OTEL_EXPORTER_OTLP_API_KEY Key within that Secret.

A default install does send telemetry

Released images carry a Lens-operated OTLP endpoint. The chart omits OTEL_EXPORTER_OTLP_ENDPOINT when telemetry.endpoint is empty, which lets that baked-in endpoint apply. Setting telemetry.endpoint redirects the events to a collector you run; only telemetry.enabled=false stops them.

Both choices are one Helm value. See Point at your own collector and Turning it off.


Base attributes#

Every event (runtime and control-plane) carries these attributes automatically:

Attribute Description
event.id Auto-generated UUIDv7 per event
event.name Event name (see the catalogue below)
user.id OIDC subject of the actor. Omitted whenever the actor is not a signed-in person
deployment.id A persistent identifier for this install, generated once and stored in your database
service.instance.id IP address of the emitting instance
deployment.environment.name Whatever you set config.deploymentEnvironment to
cloud.*, host.* Provider, region, and host identifiers, when the standard OpenTelemetry detectors find them on AWS, GCP, or Azure. Absent on-premises

deployment.id is what makes events from one install correlatable across time. If that, or the cloud metadata, is more than you want to share, point telemetry at your own collector or turn it off.


Event catalogue#

Fifty-seven events, all emitted by the platform server. Every one carries the base attributes above in addition to the keys listed here.

Organizations#

Event Attribute keys
org created org.id, org.name
org updated org.id
org deleted org.id
org member role updated org.id, member.user.id, member.role
org member removed org.id, member.user.id

Projects#

Event Attribute keys
project created org.id, project.id, project.name
project updated org.id, project.id
project deleted org.id, project.id
project keys rotated org.id, project.id

Teams and invitations#

Event Attribute keys
team created org.id, team.id, team.name
team updated org.id, team.id
team deleted org.id, team.id
team member added org.id, team.id, member.user.id or member.agent_token.id
team member removed org.id, team.id, member.id
team project access granted org.id, team.id, project.id, access.role
team project access revoked org.id, team.id, project.id
org invitation sent org.id, invitation.id
org invitation accepted org.id, invitation.id
org invitation declined org.id, invitation.id
org invitation revoked org.id, invitation.id

Policies and policy bindings#

Event Attribute keys
policy created org.id, policy.id, policy.scope, project.id (when project-scoped)
policy updated org.id, policy.id, policy.scope
policy deleted org.id, policy.id, policy.scope
policy binding created org.id, binding.id, binding.scope, project.id (when project-scoped)
policy binding updated org.id, binding.id
policy binding deleted org.id, binding.id

Policy contents are never sent — only the identifier and scope. What a policy allows stays in your database.

Sandboxes#

Event Attribute keys
sandbox created org.id, project.id, sandbox.id, sandbox.name, sandbox.type, container.image
sandbox started org.id, project.id, sandbox.id, sandbox.type
sandbox stopped org.id, project.id, sandbox.id, sandbox.type
sandbox deleted org.id, project.id, sandbox.id, sandbox.name, sandbox.type
sandbox connected project.id, sandbox.id, sandbox.name, sandbox.type, container.image, org.id when known
sandbox disconnected project.id, sandbox.id, sandbox.name, sandbox.type, container.image, disconnect.code, org.id when known
sandbox token issued org.id, project.id, token.id, token.ttl_ms

container.image is the image reference you supplied. If your image names are themselves sensitive, that is a reason to route telemetry to your own collector.

Clusters#

Event Attribute keys
cluster created org.id, project.id, cluster.id
cluster updated org.id, project.id, cluster.id
cluster deleted org.id, project.id, cluster.id
cluster tunnel token rotated org.id, project.id, cluster.id

AWS connections and credentials#

Event Attribute keys
aws connection created org.id, project.id, connection.id
aws connection updated org.id, project.id, connection.id
aws connection deleted org.id, project.id, connection.id
credential created org.id, project.id, credential.id
credential updated org.id, project.id, credential.id
credential deleted org.id, project.id, credential.id

Credential values, header names, and target domains are not sent. Only the row identifier.

Connectors and MCP servers#

Event Attribute keys
mcp server created org.id, project.id, mcp_server.id
mcp server updated org.id, project.id, mcp_server.id
mcp server deleted org.id, project.id, mcp_server.id
mcp server oauth completed org.id, project.id, mcp_server.id, credential.id
connector created (http) org.id, project.id, connector.id, connector.kind, connector.entryCount
connectors snapshot org.id, project.id, connector.id, connector.kind, connector.status, connector.enabled, connector.has_credential

Upstream URLs are not sent, and the discovered tool list is not sent. connector.entryCount is a count, not a list. Names of tools an agent actually calls do appear, in the aggregate tool usage counts below.

MCP sessions and tool usage#

Event Attribute keys
mcp session started org.id, project.id, sandbox.id, sandbox.type (each when known)
mcp session ended session.end.reason, plus org.id, project.id, sandbox.id, sandbox.type when known
tool usage org.id, project.id, tool.name, tool.kind, tool.outcome, tool.calls, plus sandbox.id, sandbox.type, connector.id when known
runtime snapshot org.id, project.id, sandbox.id, sandbox.type. With no sandboxes running, a single event carrying sandboxes.connected: 0

tool usage records which tool ran, how it ended, and how many times, aggregated per flush. That includes the names of connector tools an agent called. Tool arguments and results are never included.

API tokens#

Event Attribute keys
api token created org.id, token.id, token.expires_at (when set)
api token revoked org.id, token.id

Spending limits#

Event Attribute keys
spending limit set org.id, limit.cents, actor.type, actor.id (when scoped to one actor)
spending limit removed org.id, limit.id

What is NOT sent#

Product telemetry is strictly limited to lifecycle and metadata events. The following are never included:

  • Conversation content — prompts, responses, and message history
  • Tool-call arguments or results — MCP tool inputs, Kubernetes API responses, shell output
  • File and workspace contents — files read, written, or transferred by agents
  • Credentials — API keys, tokens, or secrets, and the domains and headers they are injected into
  • Policy contents — what a policy allows; only its identifier and scope are sent
  • Connector targets — upstream URLs, and the discovered tool list. Names of tools an agent calls do appear in aggregate tool usage counts

All attribute values are identifiers (IDs, names, numeric thresholds). No free-text or user-generated content is captured.


Point at your own collector#

Send telemetry to any OTLP/HTTP-compatible collector you operate:

helm upgrade lens-agents oci://ghcr.io/lensapp/lens-agents --reuse-values \
  --set telemetry.endpoint="https://otel.internal.example.com" \
  --set telemetry.existingSecret=lens-agents-otel

This works with any OpenTelemetry-compatible backend — Grafana Alloy, Datadog, Honeycomb, a self-hosted OpenTelemetry Collector, or anything else that accepts OTLP/HTTP log records. The events described on this page then land in your own observability stack and go nowhere else.


Turning it off#

helm upgrade lens-agents oci://ghcr.io/lensapp/lens-agents --reuse-values \
  --set telemetry.enabled=false

telemetry.enabled is the master switch and is always rendered into the ConfigMap, so false disables the pipeline whatever the image was built with. Leaving telemetry.endpoint empty is not enough — an empty endpoint falls through to the endpoint baked into released images.