Snippets · Sources
Collect Kubernetes events as logs
Kubernetes events explain most "why is this pod not running" questions, and the API server deletes them after an hour. The k8s_events receiver watches them and turns each into a log record, so they stay searchable next to the pod's own logs.
- Signals
- Logs
- Category
- CollectionKubernetes
- Source
- Kubernetes API (events)
- Components
- batchmemory_limiterotlphttp
- Destination
- OTLP/HTTP endpoint
OpenTelemetry Collector
receivers:
k8s_events:
auth_type: serviceAccount
# Empty means every namespace.
namespaces: []
processors:
memory_limiter:
check_interval: 1s
limit_percentage: 80
spike_limit_percentage: 25
batch:
timeout: 5s
exporters:
otlphttp:
endpoint: https://your-backend:4318
service:
pipelines:
logs:
receivers: [k8s_events]
processors: [memory_limiter, batch]
exporters: [otlphttp]
The collector needs this to run in a cluster: a ServiceAccount, the RBAC it uses and the workload. Create the config first with kubectl -n observability create configmap k8s-events --from-file=config.yaml.
apiVersion: v1
kind: ServiceAccount
metadata:
name: k8s-events
namespace: observability
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: k8s-events
rules:
- apiGroups: [""]
resources: [events, namespaces]
verbs: [get, list, watch]
- apiGroups: [events.k8s.io]
resources: [events]
verbs: [get, list, watch]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: k8s-events
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: k8s-events
subjects:
- kind: ServiceAccount
name: k8s-events
namespace: observability
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: k8s-events
namespace: observability
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: k8s-events
template:
metadata:
labels:
app: k8s-events
spec:
serviceAccountName: k8s-events
containers:
- name: otelcol
image: otel/opentelemetry-collector-contrib:0.161.0
args: ["--config=/conf/config.yaml"]
env:
- name: K8S_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
volumeMounts:
- name: config
mountPath: /conf
volumes:
- name: config
configMap:
name: k8s-events
LinkMesh
Library › Sources › Kubernetes Events
- Auth Type
- serviceAccount
- Field Selector
- type=Warning
What LinkMesh then pushes to the collector, under receivers:
k8sobjects/input_src_00000501:
auth_type: serviceAccount
objects:
- field_selector: type=Warning
mode: watch
name: events
The same, as an API call (see automation recipes):
curl -X POST "$LINKMESH/sources" \
-H "Authorization: Bearer $LMSAT" \
-H "Content-Type: application/json" \
-d '{
"defaultConfig": {
"auth_type": "serviceAccount",
"field_selector": "type=Warning"
},
"name": "Kubernetes Events",
"receiverType": "k8s_events"
}'The rest of the collector config above (k8s_events, memory_limiter, batch, otlphttp) is not part of this template: in LinkMesh those are separate sources, processors and destinations on the route.
Generated from LinkMesh's template catalogue by linkmesh-server snippet-render 1.464.3, not written by hand.
Download config.yamlValidated with otelcol-contrib v0.161.0 on 2026-10-26
Complete config files, each checked with the collector's own validate command (otelcol-contrib v0.161.0). Replace https://your-backend:4318 with your own OTLP endpoint before you run it.
The gotcha
Two replicas ship every event twice. In our test a probe pod produced four events; with one collector replica they arrived once, with two replicas each replica shipped all four - eight records for four events. Keep replicas: 1, and the Recreate strategy, as the manifest does.
Manage this across a fleet
LinkMesh manages collector configuration across a fleet from one self-hosted control plane, so a change like this is made once rather than host by host. The first 25 Collectors are free after a no-card registration in the OpenSight Customer Portal (5 without one).
Doing this in LinkMesh: Install LinkMesh on Kubernetes
Related snippets
- Scrape cAdvisor container metrics from the kubeletThe container_* metrics Kubernetes dashboards expect, scraped from each node's kubelet with the pod's service account token.
- Collect Kubernetes cluster metrics (one replica)Deployment replicas, pod phases, node conditions, restarts and resource quotas from the Kubernetes API - one collector for the whole cluster.
- Kubernetes pod logs to Loki, enriched with deployment and clusterEvery pod's logs into Loki over OTLP, labelled with namespace, pod, container, deployment, node and cluster.
- Scrape pods by prometheus.io annotationsScrape every pod that asks for it with prometheus.io/scrape annotations, each node's collector only its own pods.