Use this file to discover all available pages before exploring further.
ClickStack uses the OpenTelemetry (OTel) collector to collect logs, metrics, and Kubernetes events from Kubernetes clusters and forward them to ClickStack. We support the native OTel log format and require no additional vendor-specific configuration.This guide integrates the following:
Logs
Infra Metrics
To send over application-level metrics or APM/traces, you’ll need to add the corresponding language integration to your application as well.
To collect logs and metrics from both each node and the cluster itself, we’ll need to deploy two separate OpenTelemetry collectors. One will be deployed as a DaemonSet to collect logs and metrics from each node, and the other will be deployed as a deployment to collect logs and metrics from the cluster itself.
Create a new Kubernetes secret with the ingestion API Key from HyperDX. This will be used by the components installed below to securely ingest into your ClickStack OTel collector:
The DaemonSet will collect logs and metrics from each node in the cluster but won’t collect Kubernetes events or cluster-wide metrics.Download the DaemonSet manifest:
# daemonset.yamlmode: daemonset# Required to use the kubeletstats cpu/memory utilization metricsclusterRole: create: true rules: - apiGroups: - '' resources: - nodes/proxy verbs: - getpresets: logsCollection: enabled: true hostMetrics: enabled: true # Configures the Kubernetes Processor to add Kubernetes metadata. # Adds the k8sattributes processor to all the pipelines and adds the necessary rules to ClusterRole. # More info: https://opentelemetry.io/docs/kubernetes/collector/components/#kubernetes-attributes-processor kubernetesAttributes: enabled: true # When enabled the processor will extra all labels for an associated pod and add them as resource attributes. # The label's exact name will be the key. extractAllPodLabels: true # When enabled the processor will extra all annotations for an associated pod and add them as resource attributes. # The annotation's exact name will be the key. extractAllPodAnnotations: true # Configures the collector to collect node, pod, and container metrics from the API server on a kubelet.. # Adds the kubeletstats receiver to the metrics pipeline and adds the necessary rules to ClusterRole. # More Info: https://opentelemetry.io/docs/kubernetes/collector/components/#kubeletstats-receiver kubeletMetrics: enabled: trueextraEnvs: - name: YOUR_OTEL_COLLECTOR_ENDPOINT valueFrom: configMapKeyRef: name: otel-config-vars key: YOUR_OTEL_COLLECTOR_ENDPOINTconfig: receivers: # Configures additional kubelet metrics kubeletstats: collection_interval: 20s auth_type: 'serviceAccount' endpoint: '${env:K8S_NODE_NAME}:10250' insecure_skip_verify: true metrics: k8s.pod.cpu_limit_utilization: enabled: true k8s.pod.cpu_request_utilization: enabled: true k8s.pod.memory_limit_utilization: enabled: true k8s.pod.memory_request_utilization: enabled: true k8s.pod.uptime: enabled: true k8s.node.uptime: enabled: true k8s.container.cpu_limit_utilization: enabled: true k8s.container.cpu_request_utilization: enabled: true k8s.container.memory_limit_utilization: enabled: true k8s.container.memory_request_utilization: enabled: true container.uptime: enabled: true exporters: otlphttp: endpoint: "${env:YOUR_OTEL_COLLECTOR_ENDPOINT}" compression: gzip service: pipelines: logs: exporters: - otlphttp metrics: exporters: - otlphttp
k8s_daemonset.yaml
# daemonset.yamlmode: daemonset# Required to use the kubeletstats cpu/memory utilization metricsclusterRole: create: true rules: - apiGroups: - '' resources: - nodes/proxy verbs: - getpresets: logsCollection: enabled: true hostMetrics: enabled: true # Configures the Kubernetes Processor to add Kubernetes metadata. # Adds the k8sattributes processor to all the pipelines and adds the necessary rules to ClusterRole. # More info: https://opentelemetry.io/docs/kubernetes/collector/components/#kubernetes-attributes-processor kubernetesAttributes: enabled: true # When enabled the processor will extra all labels for an associated pod and add them as resource attributes. # The label's exact name will be the key. extractAllPodLabels: true # When enabled the processor will extra all annotations for an associated pod and add them as resource attributes. # The annotation's exact name will be the key. extractAllPodAnnotations: true # Configures the collector to collect node, pod, and container metrics from the API server on a kubelet.. # Adds the kubeletstats receiver to the metrics pipeline and adds the necessary rules to ClusterRole. # More Info: https://opentelemetry.io/docs/kubernetes/collector/components/#kubeletstats-receiver kubeletMetrics: enabled: trueextraEnvs: - name: HYPERDX_API_KEY valueFrom: secretKeyRef: name: hyperdx-secret key: HYPERDX_API_KEY optional: true - name: YOUR_OTEL_COLLECTOR_ENDPOINT valueFrom: configMapKeyRef: name: otel-config-vars key: YOUR_OTEL_COLLECTOR_ENDPOINTconfig: receivers: # Configures additional kubelet metrics kubeletstats: collection_interval: 20s auth_type: 'serviceAccount' endpoint: '${env:K8S_NODE_NAME}:10250' insecure_skip_verify: true metrics: k8s.pod.cpu_limit_utilization: enabled: true k8s.pod.cpu_request_utilization: enabled: true k8s.pod.memory_limit_utilization: enabled: true k8s.pod.memory_request_utilization: enabled: true k8s.pod.uptime: enabled: true k8s.node.uptime: enabled: true k8s.container.cpu_limit_utilization: enabled: true k8s.container.cpu_request_utilization: enabled: true k8s.container.memory_limit_utilization: enabled: true k8s.container.memory_request_utilization: enabled: true container.uptime: enabled: true exporters: otlphttp: endpoint: "${env:YOUR_OTEL_COLLECTOR_ENDPOINT}" headers: authorization: "${env:HYPERDX_API_KEY}" compression: gzip service: pipelines: logs: exporters: - otlphttp metrics: exporters: - otlphttp
To collect Kubernetes events and cluster-wide metrics, we’ll need to deploy a separate OpenTelemetry collector as a deployment.Download the deployment manifest:
# deployment.yamlmode: deploymentimage: repository: otel/opentelemetry-collector-contrib tag: 0.123.0# We only want one of these collectors - any more and we'd produce duplicate datareplicaCount: 1presets: kubernetesAttributes: enabled: true # When enabled the processor will extra all labels for an associated pod and add them as resource attributes. # The label's exact name will be the key. extractAllPodLabels: true # When enabled the processor will extra all annotations for an associated pod and add them as resource attributes. # The annotation's exact name will be the key. extractAllPodAnnotations: true # Configures the collector to collect kubernetes events. # Adds the k8sobject receiver to the logs pipeline and collects kubernetes events by default. # More Info: https://opentelemetry.io/docs/kubernetes/collector/components/#kubernetes-objects-receiver kubernetesEvents: enabled: true # Configures the Kubernetes Cluster Receiver to collect cluster-level metrics. # Adds the k8s_cluster receiver to the metrics pipeline and adds the necessary rules to ClusteRole. # More Info: https://opentelemetry.io/docs/kubernetes/collector/components/#kubernetes-cluster-receiver clusterMetrics: enabled: trueextraEnvs: - name: YOUR_OTEL_COLLECTOR_ENDPOINT valueFrom: configMapKeyRef: name: otel-config-vars key: YOUR_OTEL_COLLECTOR_ENDPOINTconfig: exporters: otlphttp: endpoint: "${env:YOUR_OTEL_COLLECTOR_ENDPOINT}" compression: gzip service: pipelines: logs: exporters: - otlphttp metrics: exporters: - otlphttp
k8s_deployment.yaml
# deployment.yamlmode: deploymentimage: repository: otel/opentelemetry-collector-contrib tag: 0.123.0# We only want one of these collectors - any more and we'd produce duplicate datareplicaCount: 1presets: kubernetesAttributes: enabled: true # When enabled the processor will extra all labels for an associated pod and add them as resource attributes. # The label's exact name will be the key. extractAllPodLabels: true # When enabled the processor will extra all annotations for an associated pod and add them as resource attributes. # The annotation's exact name will be the key. extractAllPodAnnotations: true # Configures the collector to collect kubernetes events. # Adds the k8sobject receiver to the logs pipeline and collects kubernetes events by default. # More Info: https://opentelemetry.io/docs/kubernetes/collector/components/#kubernetes-objects-receiver kubernetesEvents: enabled: true # Configures the Kubernetes Cluster Receiver to collect cluster-level metrics. # Adds the k8s_cluster receiver to the metrics pipeline and adds the necessary rules to ClusteRole. # More Info: https://opentelemetry.io/docs/kubernetes/collector/components/#kubernetes-cluster-receiver clusterMetrics: enabled: trueextraEnvs: - name: HYPERDX_API_KEY valueFrom: secretKeyRef: name: hyperdx-secret key: HYPERDX_API_KEY optional: true - name: YOUR_OTEL_COLLECTOR_ENDPOINT valueFrom: configMapKeyRef: name: otel-config-vars key: YOUR_OTEL_COLLECTOR_ENDPOINTconfig: exporters: otlphttp: endpoint: "${env:YOUR_OTEL_COLLECTOR_ENDPOINT}" compression: gzip headers: authorization: "${env:HYPERDX_API_KEY}" service: pipelines: logs: exporters: - otlphttp metrics: exporters: - otlphttp
To correlate application-level logs, metrics, and traces with Kubernetes metadata
(ex. pod name, namespace, etc.), you’ll want to forward the Kubernetes metadata
to your application using the OTEL_RESOURCE_ATTRIBUTES environment variable.Here’s an example deployment that forwards the Kubernetes metadata to the
application using environment variables:
# my_app_deployment.yamlapiVersion: apps/v1kind: Deploymentmetadata: name: app-deploymentspec: replicas: 1 selector: matchLabels: app: app template: metadata: labels: app: app # Combined with the Kubernetes Attribute Processor, this will ensure # the pod's logs and metrics will be associated with a service name. service.name: <MY_APP_NAME> spec: containers: - name: app-container image: my-image env: # ... other environment variables # Collect K8s metadata from the downward API to forward to the app - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: POD_UID valueFrom: fieldRef: fieldPath: metadata.uid - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace - name: NODE_NAME valueFrom: fieldRef: fieldPath: spec.nodeName - name: DEPLOYMENT_NAME valueFrom: fieldRef: fieldPath: metadata.labels['deployment'] # Forward the K8s metadata to the app via OTEL_RESOURCE_ATTRIBUTES - name: OTEL_RESOURCE_ATTRIBUTES value: k8s.pod.name=$(POD_NAME),k8s.pod.uid=$(POD_UID),k8s.namespace.name=$(POD_NAMESPACE),k8s.node.name=$(NODE_NAME),k8s.deployment.name=$(DEPLOYMENT_NAME)