Skip to content

Commit 93dbf26

Browse files
committed
Update Troubleshooting section
Signed-off-by: Rokibul Hasan <mdrokibulhasan@appscode.com>
1 parent 092ccd7 commit 93dbf26

1 file changed

Lines changed: 114 additions & 25 deletions

File tree

docs/platform/guides/cluster-management/telemetry-data-check.md

Lines changed: 114 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -96,15 +96,9 @@ kubectl exec -n monitoring <thanos-receive-ingester-pod> -- wget -qO- http://loc
9696
```
9797

9898
If this timestamp is stale (not advancing over successive checks), metrics are not being
99-
ingested. Check that Prometheus (or your agent) has `remoteWrite` configured to point at
100-
the Thanos receive router:
101-
102-
```bash
103-
kubectl get prometheus -n monitoring <prometheus-name> -o jsonpath='{.spec.remoteWrite}'
104-
```
105-
106-
An empty result means nothing is shipping samples to Thanos, regardless of whether
107-
Prometheus itself is scraping normally.
99+
ingested. Metrics are shipped from each connected cluster by the OpenTelemetry stack
100+
(`appscode-otel-stack`). See the [Troubleshooting](#troubleshooting-metrics-stale-but-logs-healthy)
101+
section below for how to trace that pipeline.
108102

109103
---
110104

@@ -191,28 +185,123 @@ matching your retention/compaction schedule.
191185

192186
## Troubleshooting: metrics stale but logs healthy
193187

194-
Logs and metrics are independent paths through the same `TelemetryStack` — one being
195-
healthy says nothing about the other, so always run both checks above rather than
196-
assuming one implies the other.
188+
There is no Prometheus doing remote-write in this setup. Telemetry is shipped from each
189+
connected cluster by the **`appscode-otel-stack`** chart (built on `opentelemetry-kube-stack`),
190+
which runs two OpenTelemetry collectors in the `monitoring` namespace of the *connected*
191+
cluster:
197192

198-
If the metrics checks show a stale `maxTime`/head timestamp that isn't advancing, the
199-
most common cause is that nothing is configured to remote-write samples into Thanos.
200-
Check the `Prometheus` CR's remote-write config:
193+
- **Daemonset (agent) collector**: runs on every node. Its `prometheus` receiver scrapes
194+
targets assigned by the **Target Allocator** (which discovers `ServiceMonitor`/`PodMonitor`
195+
CRs), and its `filelog` receiver collects container logs. Everything is forwarded over
196+
OTLP to the gateway collector.
197+
- **Gateway collector** (deployment): receives OTLP and exports to the monitoring cluster
198+
through `prom-label-proxy`:
199+
- **Metrics**`prometheusremotewrite` exporter → `https://<ingest-endpoint>:10001/api/v1/receive`
200+
→ Thanos receive. The `THANOS-TENANT` header is injected per batch by the
201+
`headers_setter` extension.
202+
- **Logs**`clickhouse` exporter → the same `prom-label-proxy` endpoint → ClickHouse
203+
(`otel_logs` table).
204+
205+
The `<ingest-endpoint>` depends on how the platform is deployed:
206+
207+
- **DNS mode**: the exporters point at the monitoring cluster's domain name.
208+
- **IP mode**: the exporters use the fixed hostname `prom-label-proxy.monitoring.svc.cluster.local`,
209+
which is mapped to the monitoring cluster's IP via a `hostAliases` entry on the gateway
210+
collector pod (required for TLS certificate verification against a bare IP).
211+
212+
Confirm the endpoint actually in use from the gateway collector's config:
201213

202214
```bash
203-
kubectl get prometheus -n monitoring <prometheus-name> -o jsonpath='{.spec.remoteWrite}'
215+
kubectl get opentelemetrycollectors -n monitoring -o yaml | grep -B2 -A2 'endpoint:'
204216
```
205217

206-
An empty result means Prometheus may be scraping fine locally, but nothing is shipping
207-
samples to the Thanos receive router. Also check for a `PrometheusAgent` resource that
208-
might be expected to do remote-write instead:
218+
Logs and metrics share the daemon → gateway OTLP hop and the mTLS client cert
219+
(`otel-client-cert`), but split into different exporters at the gateway. So if logs are
220+
healthy and metrics are stale, connectivity and certs are fine; the problem is specific
221+
to the metrics path: either **scraping** (daemon collector / Target Allocator) or the
222+
**remote-write export** (gateway → Thanos). Run these checks **on the connected cluster**:
223+
224+
### a. Collector pods are running
209225

210226
```bash
211-
kubectl get prometheusagents -A
227+
kubectl get pods -n monitoring -l otel-collector-type=daemonset
228+
kubectl get pods -n monitoring -l otel-collector-type=deployment
212229
```
213230

214-
**Fix:** add `spec.remoteWrite` to the `Prometheus` CR, pointing at the Thanos receive
215-
router's remote-write endpoint (`http://thanos-receive-router-<stack>.monitoring.svc:19291/api/v1/receive`)
216-
with the tenant header the router's hashring expects (e.g. `THANOS-TENANT: <tenant>`).
217-
After applying, re-run the `prometheus_tsdb_head_max_time` check above over a couple of
218-
minutes to confirm the timestamp starts advancing.
231+
The daemonset collector must have one Running pod per node; a node without an agent pod
232+
silently drops that node's scrape targets (allocation is per-node).
233+
234+
### b. Gateway is exporting metrics without errors
235+
236+
Check the gateway collector's own telemetry for sent vs. failed metric points. The
237+
collector image is minimal (no shell or `wget` inside), so `kubectl exec` will not work;
238+
port-forward its internal telemetry port (8888) and query it from your machine instead:
239+
240+
```bash
241+
kubectl port-forward -n monitoring <gateway-collector-pod> 8888:8888 &
242+
sleep 2 # give the port-forward a moment to establish
243+
curl -s http://localhost:8888/metrics \
244+
| grep -E 'otelcol_exporter_(sent|send_failed|enqueue_failed).*metric_points'
245+
```
246+
247+
These counters are cumulative since the pod started, so a single reading proves nothing:
248+
a large `send_failed` value may just be leftover from a past incident (for example a
249+
monitoring-cluster restart) while everything is healthy now. Run the `curl` again after
250+
30 seconds or so and compare the two readings; only the counters that are still
251+
*advancing* matter. There are three possible outcomes:
252+
253+
1. **`sent_metric_points{exporter="prometheusremotewrite"}` is increasing and
254+
`send_failed`/`enqueue_failed` stay flat.** The gateway is exporting successfully, so
255+
this cluster's pipeline is healthy. The problem is downstream (prom-label-proxy or
256+
Thanos receive on the monitoring cluster) or a tenant mismatch; continue with step (d).
257+
2. **`send_failed_metric_points` is climbing.** Exports are failing. Read the gateway logs
258+
for the actual `prometheusremotewrite` error (HTTP status codes, TLS failures) against
259+
the `prom-label-proxy` endpoint:
260+
261+
```bash
262+
kubectl logs -n monitoring <gateway-collector-pod> --tail=100 | grep -iE "error|prometheusremotewrite"
263+
```
264+
265+
TLS or certificate errors point at the `otel-client-cert` secret (check it exists and
266+
is not expired). Connection refused or timeout points at a wrong or unreachable ingest
267+
endpoint. HTTP 4xx/5xx responses point at the prom-label-proxy / Thanos receive side
268+
on the monitoring cluster.
269+
3. **All counters are flat or zero.** The gateway has nothing to export, which means the
270+
daemon collectors are not scraping anything. Continue with step (c).
271+
272+
A growing `enqueue_failed_metric_points` means the exporter's sending queue is
273+
overflowing because sends are too slow or failing, and those points are dropped; treat
274+
it the same as outcome 2.
275+
276+
Note the exporter retries for a bounded time (`max_elapsed_time: 120s`) and then drops the
277+
batch, so persistent export errors mean permanent data loss, not delayed delivery.
278+
279+
When finished, stop the background port-forward with `kill %1`.
280+
281+
### c. Scrape targets exist and are being allocated
282+
283+
If the gateway shows nothing to export (`sent` flat, no errors), the daemon collectors
284+
aren't scraping anything. Check that the Target Allocator is running and that
285+
`ServiceMonitor`/`PodMonitor` resources exist for your workloads:
286+
287+
```bash
288+
kubectl get pods -n monitoring -l app.kubernetes.io/component=opentelemetry-targetallocator
289+
kubectl get servicemonitors,podmonitors -A
290+
```
291+
292+
The Target Allocator watches these CRs and distributes their scrape targets across the
293+
daemonset collectors. No matching monitors (or an unhealthy allocator) means the
294+
`prometheus` receiver has nothing to scrape: no data flows and no errors are logged
295+
anywhere, which is exactly the "silently stale" symptom.
296+
297+
### d. Data flowing under the wrong tenant
298+
299+
Metrics may be arriving in Thanos but under a different tenant than the one you're
300+
querying. The gateway derives the tenant from resource attributes: it defaults to
301+
`default`, and is set to the source namespace name only for namespaces labeled
302+
`ace.appscode.com/client-org: "true"`; batches with no tenant attribute fall back to
303+
`anonymous`. Re-run the store/query checks from section 2 with `THANOS-TENANT: default`
304+
(and `anonymous`) before concluding data is missing.
305+
306+
After fixing whichever stage was broken, re-run the `prometheus_tsdb_head_max_time` check
307+
from section 2 over a couple of minutes to confirm the timestamp starts advancing.

0 commit comments

Comments
 (0)