Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion charts/superlog-otel/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ apiVersion: v2
name: superlog-otel
description: Collect Kubernetes telemetry and export it to Superlog.
type: application
version: 0.1.0
version: 0.1.1
appVersion: "0.156.0"
home: https://superlog.sh
sources:
Expand Down
36 changes: 29 additions & 7 deletions charts/superlog-otel/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ In Porter, open **Add-ons → Create add-on → Helm Chart** and enter:
| Add-on name | `superlog-otel` |
| Helm Repository URL | `https://superloglabs.github.io/helm-charts` |
| Chart Name | `superlog-otel` |
| Chart Version | `0.1.0` |
| Chart Version | `0.1.1` |

Paste this into **Values YAML**, replacing the placeholder with the project
ingest key shown in Superlog:
Expand All @@ -31,11 +31,12 @@ Kubernetes cluster UID as its stable identity.

The chart installs two coordinated collector roles in one Helm release:

- A node agent (`DaemonSet`) collects stdout/stderr from every pod, host CPU,
memory, disk and network metrics, and kubelet pod/container metrics.
- A node agent (`DaemonSet`) collects stdout/stderr from every pod on Porter's
Application nodes, host CPU, memory, disk and network metrics, and kubelet
pod/container metrics.
- One cluster collector (`Deployment`) collects Kubernetes events and workload
state metrics and accepts application OTLP traces, logs, and metrics on ports
`4317` and `4318`.
state metrics across the cluster and accepts application OTLP traces, logs,
and metrics on ports `4317` and `4318`.
- Both roles attach Kubernetes workload metadata and export directly to the
selected Superlog project.

Expand All @@ -48,11 +49,32 @@ objects may contain sensitive environment values and create unnecessary
telemetry volume. Kubernetes events, resource identity, and operational metrics
are collected instead.

## Porter node groups

By default, the node agent targets Porter's **Application** node group. This
keeps a one-click install schedulable on a fresh Porter cluster, where the fixed
System nodes may already be at their pod limit. Kubernetes events and workload
state metrics remain cluster-wide because the cluster collector is not a
DaemonSet.

To collect container logs and node metrics from every Linux node, replace the
default in Porter's **Values YAML** with the following. Use this only when every
node has capacity for one additional pod; otherwise Porter can remain in the
**Deploying** state while an agent waits to schedule.

```yaml
collectors:
agent:
porterNodeGroups: []
```

## Existing monitoring

[Porter's built-in application metrics](https://docs.porter.run/applications/observability/monitoring)
use Prometheus, so a standard Porter cluster does not have a competing
OpenTelemetry Collector. Install the default chart as shown above.
use a separate monitoring pipeline. It may collect some of the same Kubernetes
and kubelet metrics for Porter's dashboards, but it does not send application
container logs, metrics, or traces to Superlog. The default chart can therefore
be installed alongside Porter's built-in monitoring.

If the cluster's **Add-ons** page shows an OpenTelemetry, Datadog, New Relic,
Fluent, Promtail, or Vector add-on that already exports the same data to
Expand Down
11 changes: 11 additions & 0 deletions charts/superlog-otel/templates/daemonset.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,17 @@ spec:
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.collectors.agent.porterNodeGroups }}
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: porter.run/workload-kind
operator: In
values:
{{- toYaml . | nindent 22 }}
{{- end }}
containers:
- name: collector
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
Expand Down
11 changes: 11 additions & 0 deletions charts/superlog-otel/tests/render-contract.sh
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ render() {
helm lint "$chart_dir" \
--set global.superlog.apiKey=sl_public_test >/dev/null

grep -Fxq 'version: 0.1.1' "$chart_dir/Chart.yaml" || \
fail "expected chart version 0.1.1"

# Default install owns node collection and one cluster-wide OTLP gateway.
render
assert_line "kind: DaemonSet"
Expand All @@ -61,6 +64,9 @@ assert_line_count 1 "kind: DaemonSet"
assert_line_count 1 "kind: Deployment"
assert_line_count 1 "kind: Service"
assert_line_count 2 " kubernetes.io/os: linux"
assert_contains "key: porter.run/workload-kind"
assert_contains "operator: In"
assert_contains "- application"
assert_contains "name: otlp"
assert_contains "port: 4317"
assert_contains "name: otlp-http"
Expand All @@ -85,6 +91,11 @@ assert_contains "Authorization: Bearer \${env:SUPERLOG_API_KEY}"
assert_not_contains "x-api-key:"
assert_contains 'value: "porter-monitoring"'

# Clusters with capacity on every node can opt into full-node collection.
render --set-json 'collectors.agent.porterNodeGroups=[]'
assert_not_contains "key: porter.run/workload-kind"
assert_line_count 2 " kubernetes.io/os: linux"

# Component suffixes remain distinct even at Kubernetes' 63-character limit.
long_fullname="$(printf 'a%.0s' {1..63})"
expected_agent_name="${long_fullname:0:57}-agent"
Expand Down
6 changes: 6 additions & 0 deletions charts/superlog-otel/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ collectors:
# host metrics, and kubelet metrics.
agent:
enabled: true
# Porter keeps system, monitoring, and application workloads in separate
# node groups. Application-only is the safe zero-config default because a
# fresh Porter's fixed system nodes may already be at their pod limit.
# Set this to [] only after ensuring every Linux node has a free pod slot.
porterNodeGroups:
- application
nodeSelector:
kubernetes.io/os: linux
kubelet:
Expand Down
Loading