dependency-wrapperOTEL_API_KEY must be supplied by the referenced otel-api-key Kubernetes Secret for telemetry export.extraEnvs for the target cluster.github.com/LerianStudio/helm; license is Apache-2.0.This Helm chart installs the OpenTelemetry Collector configured for Lerian’s observability stack. It collects traces, logs, and metrics from Kubernetes workloads and exports them to Lerian’s central telemetry backend.
This chart is intentionally a dependency-wrapper: it configures the upstream opentelemetry-collector chart and does not carry local Kubernetes templates. Application-chart requirements such as templates/_helpers.tpl and values-template.yaml do not apply unless local templates are added later. A values.schema.json is committed to keep the subchart configuration block validated, and Chart.lock is committed so dependency resolution is reproducible.
To install the OpenTelemetry Collector using Helm, run the following command:
$ helm install otel-collector-lerian oci://registry-1.docker.io/lerianstudio/otel-collector-lerian --version <version> -n midaz --create-namespace
This will create a new namespace called midaz if it doesn’t already exist and deploy the OpenTelemetry Collector Helm chart.
After installation, you can verify that the release was successful by listing the Helm releases in the midaz namespace:
$ helm list -n midaz
Before installing this chart, you need to create a Kubernetes secret containing the API key for authenticating with the central collector:
$ kubectl create secret generic otel-api-key --from-literal=api-key=<your-api-key> -n midaz
This chart provides a pre-configured OpenTelemetry Collector with the following capabilities:
k8sobjects.objects[0].namespaces (default: midaz and midaz-plugins)check_interval: 1s, limit_percentage: 80)pod_association strategy: primary resolves identity from the k8s.pod.ip resource attribute (set by lib-observability-based apps via OTEL_RESOURCE_ATTRIBUTES); fallback uses the connection source IP (requires hostNetwork: true on the collector pod).client.id for multi-tenancy supportapp.request.payload)http.method, http.status_code) and OTel stable (http.request.method, http.response.status_code). Keeps both forms populated on every span during the lib-observability migration window (only trace_statements; logs are not normalized because the access log fields use underscore form http_method/http_status_code and are parsed by Loki directly). Skips when the new method attr is _OTHER (cardinality protection sentinel).midaz and midaz-plugins namespaces only. Telemetry from any other namespace is dropped at the collector before being exported.https://telemetry.lerian.io)| Parameter | Description | Default |
|---|---|---|
opentelemetry-collector.mode |
Deployment mode (daemonset required for kubeletstats) | daemonset |
opentelemetry-collector.image.repository |
Container image repository | otel/opentelemetry-collector-contrib |
opentelemetry-collector.image.tag |
Container image tag | 0.142.0 |
| Parameter | Description | Default |
|---|---|---|
opentelemetry-collector.resources.limits.cpu |
CPU limit | 650m |
opentelemetry-collector.resources.limits.memory |
Memory limit | 512Mi |
opentelemetry-collector.resources.requests.cpu |
CPU request | 250m |
opentelemetry-collector.resources.requests.memory |
Memory request | 256Mi |
| Parameter | Description | Default |
|---|---|---|
opentelemetry-collector.extraEnvs[0].name |
API key environment variable name | OTEL_API_KEY |
opentelemetry-collector.extraEnvs[0].valueFrom.secretKeyRef.name |
Secret name for API key | otel-api-key |
opentelemetry-collector.extraEnvs[0].valueFrom.secretKeyRef.key |
Secret key for API key | api-key |
GOMEMLIMIT |
Go memory limit | 200MiB |
GOGC |
Go garbage collection percentage | 80 |
GOMAXPROCS |
Maximum number of Go processes | 2 |
| Parameter | Description | Default |
|---|---|---|
config.receivers.otlp.protocols.grpc.endpoint |
OTLP gRPC endpoint | 0.0.0.0:4317 |
config.receivers.otlp.protocols.http.endpoint |
OTLP HTTP endpoint | 0.0.0.0:4318 |
config.receivers.k8s_cluster.collection_interval |
Cluster metrics collection interval | 60s |
config.receivers.kubeletstats.collection_interval |
Kubelet stats collection interval | 10s |
| Parameter | Description | Default |
|---|---|---|
config.processors.memory_limiter.limit_percentage |
Memory limit percentage | 80 |
config.processors.memory_limiter.spike_limit_percentage |
Spike limit percentage | 20 |
config.processors.batch.timeout |
Batch timeout | 200ms |
config.processors.batch.send_batch_size |
Batch size | 512 |
config.processors.batch.send_batch_max_size |
Maximum batch size | 1024 |
| Parameter | Description | Default |
|---|---|---|
config.exporters.otlphttp/server.endpoint |
Central telemetry endpoint | https://telemetry.lerian.io:443 |
| Parameter | Description | Default |
|---|---|---|
config.processors.resource/add_client_id.attributes[0].value |
Client ID for multi-tenancy | Firmino |
The chart configures the following pipelines. All pipelines follow the same processor ordering: memory_limiter first, k8sattributes before batch (batch drops the connection context that pod_association relies on), and batch last so all enrichment runs on individual records.
memory_limiter (admission control)k8sattributes (pod identity via k8s.pod.ip resource attribute or connection IP fallback)resource/add_client_id (multi-tenancy)filter/include_midaz_namespaces (BYOC privacy — drop spans from non-midaz namespaces)transform/remove_sensitive_attributes (strip app.request.payload)transform/normalize_http_semconv (mirror legacy ↔ OTel-stable HTTP attrs)batchspanmetrics connectorAccepts OTLP-pushed metrics from applications. Required so apps using lib-observability (which emits http.server.request.duration and other OTel-native metrics directly via the OTel SDK) deliver those to the central backend.
memory_limiter → k8sattributes → resource/add_client_id → filter/include_midaz_namespaces → batchCarries the RED metrics derived from spans by the spanmetrics connector.
spanmetrics connectormemory_limiter → k8sattributes → resource/add_client_id → batch(No filter/include_midaz_namespaces here because spans were already filtered upstream in the traces pipeline.)
k8s_cluster and kubeletstats receivers (OTLP is not in this pipeline — application OTLP metrics flow through the Metrics pipeline above to avoid double export)memory_limiter → k8sattributes → resource/add_client_id → filter/include_midaz_namespaces → filter/drop_node_metrics → batchk8sobjectsmemory_limiter → k8sattributes → resource/add_client_id → filter/include_midaz_namespaces (drops logs from non-midaz namespaces before masking) → 10 transform/mask_body_sensitive_data_replace_* (PII masking) → batchThe chart deploys the collector as a DaemonSet with hostNetwork: true and dnsPolicy: ClusterFirstWithHostNet. hostPort mappings are set to 0 (since hostNetwork binds the container directly to the node’s network stack, hostPort would be redundant and could fight for ports during rolling updates).
This is required so the k8sattributes processor can resolve pod identity from the connection source IP — without hostNetwork, hostPort hairpin NAT would rewrite the source IP to the node IP and k8sattributes couldn’t match telemetry to its originating pod.
Two-tier pod_association:
from: resource_attribute, name: k8s.pod.ip — works for any pod, no hostNetwork required. Apps need to emit OTEL_RESOURCE_ATTRIBUTES=k8s.pod.ip=$(POD_IP) (the midaz chart’s ledger/crm templates set this automatically when otel-collector-lerian.enabled=true).from: connection — kicks in for apps that don’t emit k8s.pod.ip (e.g. apps still on lib-commons v2). Requires the collector’s hostNetwork: true to be honored by the cluster’s Pod Security policy.If your cluster’s Pod Security Standards forbid hostNetwork: true you can still run the chart in a restricted mode by setting hostNetwork: false and ensuring every application emits the k8s.pod.ip resource attribute — the primary path is enough on its own.
The chart includes comprehensive PII masking for logs, including:
The chart automatically creates the necessary ClusterRole with permissions to:
| Dependency | Version | Repository |
|---|---|---|
| opentelemetry-collector | 0.142.0 | https://open-telemetry.github.io/opentelemetry-helm-charts |
To customize the client ID for multi-tenancy, update the values.yaml:
opentelemetry-collector:
config:
processors:
resource/add_client_id:
attributes:
- key: client.id
value: "your-client-id"
action: upsert
$ kubectl logs -l app.kubernetes.io/name=otel-collector-lerian -n midaz
The collector exposes internal metrics on port 8887:
$ kubectl port-forward svc/otel-collector-lerian 8887:8887 -n midaz
$ curl http://localhost:8887/metrics
$ kubectl auth can-i list pods --as=system:serviceaccount:midaz:otel-collector-lerian -n midaz