64 lines
3.3 KiB
Python
64 lines
3.3 KiB
Python
#!/usr/bin/env python3
|
|
"""Send ONE uniquely tagged probe to Kafka, then verify its indexed representation.
|
|
|
|
Does not reset consumer offsets or write directly to OpenSearch. The measurement
|
|
name 'pipeline_probe' is excluded by every supplied metric visualization filter.
|
|
"""
|
|
import json
|
|
from pathlib import Path
|
|
import subprocess
|
|
import sys
|
|
import time
|
|
import urllib.error
|
|
import urllib.request
|
|
import uuid
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
|
|
def probe():
|
|
probe_id = uuid.uuid4().hex
|
|
sample = {'name': 'pipeline_probe', 'timestamp': int(time.time() * 1000),
|
|
'tags': {'host': 'pipeline-probe', 'environment': 'diagnostic',
|
|
'role': 'diagnostic', 'series': 'pipeline-probe / diagnostic', 'probe_id': probe_id},
|
|
'fields': {'value': 1.0}}
|
|
print('Publishing one diagnostic measurement to Kafka:', probe_id, flush=True)
|
|
command = ['docker', 'compose', 'exec', '-T', 'kafka', '/opt/kafka/bin/kafka-console-producer.sh',
|
|
'--bootstrap-server', 'kafka:29092', '--topic', 'host-metrics-v1',
|
|
'--producer-property', 'acks=all', '--producer-property', 'delivery.timeout.ms=15000',
|
|
'--producer-property', 'request.timeout.ms=10000', '--producer-property', 'max.block.ms=15000']
|
|
try:
|
|
sent = subprocess.run(command, cwd=ROOT, input=json.dumps(sample) + '\n', text=True,
|
|
capture_output=True, timeout=40)
|
|
except subprocess.TimeoutExpired:
|
|
print('FAIL: Kafka producer timed out. Check broker/topic/listeners.'); return 2
|
|
if sent.returncode or 'ERROR' in sent.stderr:
|
|
print(sent.stdout, sent.stderr)
|
|
print('FAIL: Kafka did not accept the probe.'); return 2
|
|
print('Producer completed; checking Data Prepper → OpenSearch for up to 60 seconds.', flush=True)
|
|
last_error = ''
|
|
for _ in range(12):
|
|
query = {'size': 1, 'query': {'term': {'tags.probe_id': probe_id}}}
|
|
request = urllib.request.Request('http://127.0.0.1:9200/host-metrics-v1-*/_search',
|
|
data=json.dumps(query).encode(), headers={'Content-Type': 'application/json'})
|
|
try:
|
|
with urllib.request.urlopen(request, timeout=5) as response:
|
|
hits = json.load(response)['hits']['hits']
|
|
if hits:
|
|
doc = hits[0]['_source']
|
|
if not doc.get('@timestamp') or doc.get('fields', {}).get('value') != 1:
|
|
print('FAIL: probe indexed with incorrect transformation:', json.dumps(doc)); return 3
|
|
print('PASS: Kafka → Data Prepper → OpenSearch is working.')
|
|
print('Index:', hits[0]['_index'], 'timestamp:', doc['@timestamp'])
|
|
print('If native host metrics are absent, inspect the Telegraf service/configuration and its Kafka connection.')
|
|
return 0
|
|
except (urllib.error.URLError, KeyError, ValueError) as error:
|
|
last_error = str(error)
|
|
time.sleep(5)
|
|
print('FAIL: probe was not found in OpenSearch within the wait window.', last_error)
|
|
print('Inspect Data Prepper startup errors, consumer lag/backlog, OpenSearch write failures and the DLQ.')
|
|
print('Probe ID (for searching again after a backlog drains):', probe_id)
|
|
return 3
|
|
|
|
if __name__ == '__main__':
|
|
sys.exit(probe())
|