如何排查Telegraf无法将Openweathermap数据写入InfluxDB故障
TIG栈OpenWeatherMap数据写入失败排查
问题现象
按如下链路搭建TIG栈时,启动出现listen udp :8125: bind: address already in use报错,且inputs.openweathermap采集的数据无法写入InfluxDB:
Openweathermap -> Telegraf -> InfluxDB -> Grafana
已确认基础环境状态:
- InfluxDB对应存储桶已创建
- Telegraf容器内可正常ping通InfluxDB服务,网络连通性正常
复现操作
进入Telegraf容器手动触发单次采集的命令:
docker exec -it telegraf /bin/sh telegraf --config /etc/telegraf/telegraf.conf --once
执行后输出日志:
2022-06-22T13:09:27Z W! DeprecationWarning: Option "parse_data_dog_tags" of plugin "inputs.statsd" deprecated since version 1.10.0 and will be removed in 2.0.0: use 'datadog_extensions' instead 2022-06-22T13:09:27Z I! Starting Telegraf 1.23.0 2022-06-22T13:09:27Z I! Loaded inputs: cpu disk diskio kernel mem openweathermap processes statsd swap system 2022-06-22T13:09:27Z I! Loaded aggregators: 2022-06-22T13:09:27Z I! Loaded processors: 2022-06-22T13:09:27Z I! Loaded outputs: influxdb_v2 (2x) 2022-06-22T13:09:27Z I! Tags enabled: host=telegraf 2022-06-22T13:09:27Z W! Deprecated inputs: 0 and 1 options 2022-06-22T13:09:27Z E! [agent] Starting input inputs.statsd: listen udp :8125: bind: address already in use 2022-06-22T13:09:29Z I! [inputs.statsd] Stopping the statsd service panic: runtime error: invalid memory address or nil pointer dereference [signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x2d3f999]
当前配置
telegraf.conf
[global_tags] [agent] interval = "10s" round_interval = true metric_batch_size = 1000 metric_buffer_limit = 10000 collection_jitter = "0s" flush_interval = "10s" flush_jitter = "0s" precision = "" hostname = "" omit_hostname = false [[outputs.influxdb_v2]] urls = ["http://influxdb:8086"] token = "$INFLUXDB_INIT_ADMIN_TOKEN" organization = "$INFLUXDB_INIT_ORG" bucket = "$INFLUXDB_INIT_BUCKET" namedrop = ["weather*"] [[outputs.influxdb_v2]] urls = ["http://influxdb:8086"] token = "$INFLUXDB_OPENWEATHER_TOKEN" organization = "$INFLUXDB_INIT_ORG" bucket = "$INFLUXDB_OPENWEATHER_BUCKET" namepass = ["weather*"] [[inputs.cpu]] percpu = true totalcpu = true collect_cpu_time = false report_active = false [[inputs.disk]] ignore_fs = ["tmpfs", "devtmpfs", "devfs", "iso9660", "overlay", "aufs", "squashfs"] [[inputs.diskio]] [[inputs.kernel]] [[inputs.mem]] [[inputs.processes]] [[inputs.swap]] [[inputs.system]] [[inputs.openweathermap]] app_id = "09b8953b9f8f891e15af01a369aeXXX" lang = "es" fetch = ["weather","forecast"] units = "metric" interval = "10m" [[inputs.statsd]] protocol = "udp" max_tcp_connections = 250 tcp_keep_alive = false service_address = ":8125" delete_gauges = true delete_counters = true delete_sets = true delete_timings = true percentiles = [50.0, 90.0, 99.0, 99.9, 99.95, 100.0] metric_separator = "_" parse_data_dog_tags = true datadog_extensions = false datadog_distributions = false allowed_pending_messages = 10000 percentile_limit = 1000
docker-compose.yml
version: "3.9" volumes: influxdb_data: {} postgres_data: {} grafana_data: {} networks: influx: name: influx-frontend postgres: external: false services: influxdb: container_name: influxdb image: influxdb:${INFLUXDB_VERSION} networks: - influx ports: - 8086:8086 healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8086/ping"] interval: 10s timeout: 10s retries: 5 start_period: 40s restart: always environment: - TZ=America/Argentina/Buenos_Aires env_file: - ./influxdb/influxdb.env volumes: - influxdb_data:/var/lib/influxdb2 - ./influxdb/config.yml:/etc/influxdb2/config.yml telegraf: container_name: telegraf image: telegraf:${TELEGRAF_VERSION} hostname: telegraf profiles: ["telegraf"] environment: - TZ=America/Argentina/Buenos_Aires networks: - influx ports: - 8125:8125/udp restart: always depends_on: - influxdb env_file: - ./telegraf/telegraf.env volumes: - ./telegraf/telegraf.conf:/etc/telegraf/telegraf.conf:ro postgres: container_name: postgres image: bitnami/postgresql:${POSTGRES_VERSION} profiles: ["grafana"] networks: - postgres ports: - 5432:5432 restart: always env_file: - ./postgres/postgres.env volumes: - postgres_data:/bitnami/postgresql grafana: build: context: ./grafana dockerfile: Dockerfile args: - GRAFANA_VERSION=${GRAFANA_VERSION:-latest} container_name: grafana image: grafana/grafana-enterprise:${GRAFANA_VERSION} profiles: ["grafana"] networks: - postgres - influx ports: - 3000:3000 healthcheck: test: ["CMD", "curl", "-f", "http://localhost:3000/api/health"] interval: 10s timeout: 10s retries: 5 start_period: 40s restart: always depends_on: - postgres - influxdb env_file: - ./grafana/grafana.env volumes: - grafana_data:/var/lib/grafana - ./grafana/provisioning:/etc/grafana/provisioning - ./grafana/dashboards:/etc/dashboards
根因定位
两个独立问题共同导致数据写入失败:
- 端口冲突触发进程崩溃:手动执行单次采集命令时,容器内已经存在entrypoint启动的常驻Telegraf进程,该进程已将UDP 8125端口绑定给statsd输入插件使用。手动启动的第二个Telegraf进程无法绑定同一端口,触发statsd插件启动失败,而Telegraf 1.23版本存在已知bug,statsd启动失败后会触发空指针panic,整个进程直接退出,完全不会执行后续的采集、写入流程。
- 采集周期不匹配单次执行逻辑:openweathermap插件单独配置了
interval = "10m"的采集间隔,--once模式默认仅等待全局flush_interval(即10s)就会退出,不会等待长周期插件完成采集,即便进程不崩溃,单次执行也无法获取到openweathermap的采集数据。
修复步骤
- 修复statsd配置废弃项:删除
parse_data_dog_tags = true配置,改为datadog_extensions = true,消除版本兼容警告。如果不需要使用statsd采集,直接注释掉整个[[inputs.statsd]]配置段,从根源避免端口占用问题。 - 手动测试采集时,先终止容器内常驻Telegraf进程,避免端口冲突:
# 进入容器后先杀掉常驻进程 pkill telegraf # 过滤仅加载openweathermap输入和influxdb输出,加debug日志查看采集详情,等待15s给接口留足响应时间 telegraf --config /etc/telegraf/telegraf.conf --once --debug --input-filter openweathermap --output-filter influxdb_v2 --wait 15s
- 测试阶段可临时将openweathermap的采集间隔改为和全局一致的10s,确认数据正常写入后再改回10m。
- 检查
./telegraf/telegraf.env文件中INFLUXDB_OPENWEATHER_TOKEN的配置值,确认该token对目标存储桶有写入权限。 - 修复完成后重启Telegraf容器,等待10分钟后即可在InfluxDB中查询到weather开头的气象指标数据。
内容的提问来源于stack exchange,提问作者Adrián Freisinger
相关产品推荐
相关产品推荐

