Перейти к основному содержимому

3 записи с тегом "debugging"

Посмотреть все теги

Восстановление повреждённых series в InfluxDB

· 2 мин. чтения
dmn
maintainer

Как "починить" сломанные series в InfluxDB

Неожиданно при отладке датчиков influxdb перестал запускаться с такой ошибкой.

Ошибка запуска

root@napi-playfulokapi:~# /usr/lib/influxdb/scripts/influxd-systemd-start.sh
Command "print-config" is deprecated, use the influx-cli command server-config to display the configuration values from the running server
2025-09-16T08:54:29.621708Z info Welcome to InfluxDB {"log_id": "0z0RZky0000", "version": "v2.7.1", "commit": "407fa622e9", "build_date": "2023-04-28T13:24:42Z", "log_level": "info"}
2025-09-16T08:54:29.677535Z info Resources opened {"log_id": "0z0RZky0000", "service": "bolt", "path": "/root/.influxdbv2/influxd.bolt"}
2025-09-16T08:54:29.680849Z info Resources opened {"log_id": "0z0RZky0000", "service": "sqlite", "path": "/root/.influxdbv2/influxd.sqlite"}
2025-09-16T08:54:29.754889Z info Checking InfluxDB metadata for prior version. {"log_id": "0z0RZky0000", "bolt_path": "/root/.influxdbv2/influxd.bolt"}
2025-09-16T08:54:29.756722Z info Using data dir {"log_id": "0z0RZky0000", "service": "storage-engine", "service": "store", "path": "/root/.influxdbv2/engine/data"}
2025-09-16T08:54:29.773043Z info Compaction settings {"log_id": "0z0RZky0000", "service": "storage-engine", "service": "store", "max_concurrent_compactions": 2, "throughput_bytes_per_second": 50331648, "throughput_bytes_per_second_burst": 50331648}
2025-09-16T08:54:29.774155Z info Open store (start) {"log_id": "0z0RZky0000", "service": "storage-engine", "service": "store", "op_name": "tsdb_open", "op_event": "start"}
2025-09-16T08:54:29.780689Z error Unable to open series file {"log_id": "0z0RZky0000", "service": "storage-engine", "path": "/root/.influxdbv2/engine/data/50d1dfc5f00c762d/_series", "partition": 0, "error": "invalid series segment"}
2025-09-16T08:54:29.781180Z info Open store (end) {"log_id": "0z0RZky0000", "service": "storage-engine", "service": "store", "op_name": "tsdb_open", "op_event": "end", "op_elapsed": "7.046ms"}
2025-09-16T08:54:29.781345Z error Failed to open engine {"log_id": "0z0RZky0000", "error": "invalid series segment"}
Error: invalid series segment

Как видно в логе - у нас сломался series. Очистка базы мне не помогла, поэтому чистил вручную.

Проверить series

root@napi-playfulokapi:~# influxd inspect   verify-seriesfile
2025-09-16T09:00:55.486187Z error Error opening segment {"log_id": "0z0RwJBW000", "path": "/root/.influxdbv2/engine/data/50d1dfc5f00c762d/_series", "partition": "01", "segment": "0000", "error": "invalid series segment"}
2025-09-16T09:00:55.497022Z error Error opening segment {"log_id": "0z0RwJBW000", "path": "/root/.influxdbv2/engine/data/50d1dfc5f00c762d/_series", "partition": "00", "segment": "0000", "error": "invalid series segment"}
2025-09-16T09:00:55.507980Z error Error opening segment {"log_id": "0z0RwJBW000", "path": "/root/.influxdbv2/engine/data/50d1dfc5f00c762d/_series", "partition": "02", "segment": "0000", "error": "invalid series segment"}

Видим поломанный series. Удалим его и перестроим

Удаление повреждённых series

mv /root/.influxdbv2/engine/data/50d1dfc5f00c762d/_series/ /root/.influxdbv2/engine/data/50d1dfc5f00c762d/_series.bad/

Перестроим series

influxd inspect build-tsi

Результат

После этого "шаманства" у меня influx запустился корректно.

PS. Возможно это не самый удачный способ, но в записную книжку как срочный рецепт исправления я решил это записать.

#influxdb

Python-сниффер для анализа Modbus RTU трафика

· 3 мин. чтения
dmn
maintainer

Написал "на коленке" полезный сниффер modbus

modbus_sniffer_raw_pretty.py

#!/usr/bin/env python3
"""
Raw Modbus RTU Sniffer — listens to a serial port and prints decoded Modbus RTU frames.
Now includes decoding of address/count/value for popular function codes.
"""

import serial
import argparse
import time
import logging
import struct

logging.basicConfig()
log = logging.getLogger()
log.setLevel(logging.INFO)

def calculate_crc(data: bytes):
crc = 0xFFFF
for pos in data:
crc ^= pos
for _ in range(8):
lsb = crc & 0x0001
crc >>= 1
if lsb:
crc ^= 0xA001
return crc.to_bytes(2, 'little')

def validate_crc(frame: bytes):
if len(frame) < 4:
return False
data, received_crc = frame[:-2], frame[-2:]
return calculate_crc(data) == received_crc

def decode_payload(fc, payload):
if fc in [1, 2, 3, 4]: # Read coils, discrete inputs, HR, IR
if len(payload) >= 4:
address, count = struct.unpack(">HH", payload[:4])
return f"Read | Addr={address} | Count={count}"
elif fc in [5, 6]: # Write single coil/register
if len(payload) >= 4:
address, value = struct.unpack(">HH", payload[:4])
return f"Write Single | Addr={address} | Value={value}"
elif fc in [15, 16]: # Write multiple coils/registers
if len(payload) >= 5:
address, count, byte_count = struct.unpack(">HHB", payload[:5])
return f"Write Multiple | Addr={address} | Count={count} | Bytes={byte_count}"
return f"Payload: {payload.hex()}"

def print_frame_info(frame: bytes):
if not validate_crc(frame):
log.warning(f"❌ Invalid CRC: {frame.hex()}")
return
unit_id = frame[0]
function_code = frame[1]
payload = frame[2:-2]
desc = decode_payload(function_code, payload)
log.info(f"📥 Unit={unit_id} | FC={function_code}{desc}")

def read_frames(ser):
buffer = bytearray()
last_byte_time = time.time()
inter_char_timeout = 0.01
frame_timeout = 0.1

while True:
if ser.in_waiting:
byte = ser.read(1)
now = time.time()
if now - last_byte_time > frame_timeout and buffer:
print_frame_info(bytes(buffer))
buffer.clear()
buffer.append(byte[0])
last_byte_time = now
elif buffer and time.time() - last_byte_time > frame_timeout:
print_frame_info(bytes(buffer))
buffer.clear()
else:
time.sleep(0.005)

def main():
parser = argparse.ArgumentParser(description="Raw Modbus RTU Sniffer with decoding")
parser.add_argument('--port', required=True, help='Serial port (e.g. /dev/ttyUSB0)')
parser.add_argument('--baudrate', type=int, default=9600)
parser.add_argument('--parity', choices=['N', 'E', 'O'], default='N')
parser.add_argument('--stopbits', type=int, choices=[1, 2], default=1)
args = parser.parse_args()

try:
ser = serial.Serial(
port=args.port,
baudrate=args.baudrate,
parity={'N': serial.PARITY_NONE, 'E': serial.PARITY_EVEN, 'O': serial.PARITY_ODD}[args.parity],
stopbits=args.stopbits,
bytesize=8,
timeout=0
)
log.info(f"🔍 Listening on {args.port} at {args.baudrate} bps...")
read_frames(ser)
except Exception as e:
log.error(f"Failed to open serial port: {e}")

if __name__ == "__main__":
main()

использует библиотеку pyserial

pip install pyserial

Пример:

(venv) orangepi@cm4-right:~$ python3 modbus_sniffer_raw_pretty.py  --baudrate 9600 --port /dev/ttyS9
INFO:root:🔍 Listening on /dev/ttyS9 at 9600 bps...
INFO:root:📥 Unit=1 | FC=3 — Read | Addr=0 | Count=1
INFO:root:📥 Unit=1 | FC=3 — Read | Addr=10 | Count=2

Скрипт читает и распознает пакеты modbus, запросы modbus транслирует на экран.

#modbus #modbussniffer

Работа со службами в NapiLinux/Armbian

· 6 мин. чтения
dmn
maintainer

Для остановки, запуска, перезапуска и проверки состояния служб необходимо знать как работать с сервисом systemd.

Службы под управлением сервиса systemd управляются через утилиту systemctl.

Общие параметры запуска


systemctl start|stop|restart|enable|disable|status <service>

Уметь работать с сервисами полезно при отладке и настройке датчиков, шлюзов, конфигураций.

  • systemctl stop telegraf остановит сервис telegraf
  • systemctl start telegraf запустит сервис telegraf
  • systemctl restart telegraf перезапустит сервис telegraf (следует выполнять, когда вы исправили конфиг)
  • systemctl start telegraf выведет статус сервиса telegraf

Даже остановив или запустив сервис - при перезагрузке системы, он не "вспомнит" последнее свое состояние.

Чтобы сервис запускался при загрузке следует его "включить" командой (на примере сервиса telegraf) systemctl enable telegraf, а чтобы сервис не запускался при загрузке, его следует "выключить" командой systemctl disable telegraf.

Рассмотрим несколько примеров.

Служба mbusd

Служба моста Modbus RTU - Modbus TCP mbusd перехватывает доступ к порту, на котором находятся датчики и невозможно прочитать датчик вручную. Допустим mbusd не работает как полагается и нам надо проверить отвечает датчик или нет.

Остановим mbusd

systemctl stop mbusd

Прочитаем датчики вручную

root@napi-rk3308b-s:~# modpoll -m rtu -b 115200 -a 2 -r 1 -c 1 /dev/ttyS3
modpoll 3.10 - FieldTalk(tm) Modbus(R) Master Simulator
Copyright (c) 2002-2021 proconX Pty Ltd
Visit https://www.modbusdriver.com for Modbus libraries and tools.

Protocol configuration: Modbus RTU, FC3
Slave configuration...: address = 2, start reference = 1, count = 1
Communication.........: /dev/ttyS3, 115200, 8, 1, even, t/o 1.00 s, poll rate 1000 ms
Data type.............: 16-bit register, output (holding) register table

-- Polling slave... (Ctrl-C to stop)
[1]: 2
-- Polling slave... (Ctrl-C to stop)
[1]: 2
-- Polling slave... (Ctrl-C to stop)
[1]: 2
-- Polling slave... (Ctrl-C to stop)

Видим, что датчик читается и дело в настройках mbusd (внимательно проверяйте параметры порта !)

Включим, чтобы сервис mbusd стартовал при загрузке системы

systemctl enable mbusd

Служба telegraf

Если автоматически telegraf не читает датчик, то необзодимо его протетстировать в ручном режиме. Для этого остановим службу telegraf


systemctl stop telegraf

Прочтем датчик вручную, запустив telegraf с параметром --test

Тестирование Telegraf в ручном режиме


В данном примере мы читаем два конфига: один общий (1), другой конфиг датчика (2)

root@napi-rk3328:~# telegraf --test --config /etc/telegraf/telegraf.conf --config /data/active/Elemy_ATS-1240_smtp.conf
2024-03-19T15:02:22Z I! Loading config: /etc/telegraf/telegraf.conf
2024-03-19T15:02:22Z I! Loading config: /data/active/Elemy_ATS-1240_smtp.conf
2024-03-19T15:02:22Z I! Starting Telegraf 1.29.5 brought to you by InfluxData the makers of InfluxDB
2024-03-19T15:02:22Z I! Available plugins: 241 inputs, 9 aggregators, 30 processors, 24 parsers, 60 outputs, 6 secret-stores
2024-03-19T15:02:22Z I! Loaded inputs: snmp
2024-03-19T15:02:22Z I! Loaded aggregators:
2024-03-19T15:02:22Z I! Loaded processors:
2024-03-19T15:02:22Z I! Loaded secretstores:
2024-03-19T15:02:22Z W! Outputs are not used in testing mode!
2024-03-19T15:02:22Z I! Tags enabled: host=napi-rk3328
2024-03-19T15:02:24Z W! DeprecationWarning: Value "agent_host" for option "agent_host_tag" of plugin "inputs.snmp" deprecated since version 1.29.0 and will be removed in : set to "source" for consistent usage across plugins or safely ignore this message and continue to use the current value
> snmp,agent_host=87.245.206.187,host=napi-rk3328,name=ATS1204 uptime=345564141i 1710860544000000000
> ATS1204,agent_host=87.245.206.187,elmAtsPowerInputIndex=0,host=napi-rk3328,index=0,name=ATS1204 elmAtsPowerInputFault=0i,elmAtsPowerInputFreqence=5002i,elmAtsPowerInputIsActive=1i,elmAtsPowerInputIsNormal=1i,elmAtsPowerInputVoltage=226i 1710860546000000000
> ATS1204,agent_host=87.245.206.187,elmAtsPowerInputIndex=1,host=napi-rk3328,index=1,name=ATS1204 elmAtsPowerInputFault=0i,elmAtsPowerInputFreqence=5002i,elmAtsPowerInputIsActive=0i,elmAtsPowerInputIsNormal=1i,elmAtsPowerInputVoltage=226i 1710860546000000000
> ATS1204,agent_host=87.245.206.187,elmAtsPowerOutputIndex=0,host=napi-rk3328,index=0,name=ATS1204 Amp_output=50i,Cos-ph=782i,Volt-ampere-reactive=114i,Watt=90i,uetAstPowerOutputHasVolt=1i 1710860547000000000
root@napi-rk3328:~#

Проверка статуса службы

Проверить запущена ли служба можно командой systemctl status <service>

Проверим запущен ли и в каком статусе сервис telegraf

root@napi-rk3328:~# systemctl status telegraf
● telegraf.service - Telegraf
Loaded: loaded (/lib/systemd/system/telegraf.service; enabled; preset: disabled)
Active: active (running) since Sat 2024-03-16 09:35:50 +05; 3 days ago
Docs: https://github.com/influxdata/telegraf
Main PID: 415 (telegraf)
Tasks: 13 (limit: 2278)
Memory: 174.9M
CGroup: /system.slice/telegraf.service
├─415 /usr/bin/telegraf -config /etc/telegraf/telegraf.conf -config-directory /data/active
└─488 /usr/bin/dbus-daemon --syslog --fork --print-pid 4 --print-address 6 --session

Проверим в каком статусе сервис mbusd

Ошибка сервиса mbusd

root@napi-rk3328:~# systemctl status mbusd
× mbusd.service - Modbus TCP to Modbus RTU (RS-232/485) gateway.
Loaded: loaded (/lib/systemd/system/mbusd.service; enabled; preset: disabled)
Active: failed (Result: exit-code) since Sat 2024-03-16 09:35:51 +05; 3 days ago
Duration: 19ms
Process: 497 ExecStart=/usr/bin/mbusd -d -c /etc/mbusd/mbusd.conf (code=exited, status=5)
Main PID: 497 (code=exited, status=5)

Notice: journal has been rotated since unit was started, output may be incomplete.
root@napi-rk3328:~#


Видно, что сервис не запущен.

Сервис может быть не запущен, потому что остановлен или потому что не смог прочитать конфиг. Узнать подробнее, что случилось с сервисом можно командой journalctl -u <service>

Например, если сервис mbusd не запущен и записей по нему нет, вывод будет такой

root@napi-rk3328:~# journalctl -u mbusd
-- No entries --
root@napi-rk3328:~#

При неудачной попытке запуска сервиса вывод будет такой

Подробная ошибка mbusd

root@napi-rk3328:~# systemctl start mbusd
root@napi-rk3328:~# journalctl -u mbusd
Mar 19 20:16:23 napi-rk3328 systemd[1]: Started Modbus TCP to Modbus RTU (RS-232/485) gateway..
Mar 19 20:16:23 napi-rk3328 mbusd[25420]: 19 Mar 2024 20:16:23 conn_init(): can't open tty device /dev/ttyS3 (Input/output error)
Mar 19 20:16:23 napi-rk3328 systemd[1]: mbusd.service: Main process exited, code=exited, status=5/NOTINSTALLED
Mar 19 20:16:23 napi-rk3328 systemd[1]: mbusd.service: Failed with result 'exit-code'.
Mar 19 20:16:24 napi-rk3328 systemd[1]: mbusd.service: Scheduled restart job, restart counter is at 1.
Mar 19 20:16:24 napi-rk3328 systemd[1]: Stopped Modbus TCP to Modbus RTU (RS-232/485) gateway..
Mar 19 20:16:24 napi-rk3328 systemd[1]: Started Modbus TCP to Modbus RTU (RS-232/485) gateway..
Mar 19 20:16:24 napi-rk3328 mbusd[25421]: 19 Mar 2024 20:16:24 conn_init(): can't open tty device /dev/ttyS3 (Input/output error)
Mar 19 20:16:24 napi-rk3328 systemd[1]: mbusd.service: Main process exited, code=exited, status=5/NOTINSTALLED
Mar 19 20:16:24 napi-rk3328 systemd[1]: mbusd.service: Failed with result 'exit-code'.

Мониторинг процессов через ps

Есть еще один способ понять запущен процесс или нет. Бывает, Вы можете не знать имя службы до конца, но запущен ли процесс понять можно.

Команда ps из под root выводит список всех процессов, поэтому командой

ps | grep <process>

в некоторых системах нужно запускать

ps ax | grep <process>

Можно узнать а работает ли процесс и какой у него PID.

Узнаем, работает ли у нас telegraf (да, работает pid=415)

root@napi-rk3328:~# ps ax | grep telegraf
415 ? SLsl 139:23 /usr/bin/telegraf -config /etc/telegraf/telegraf.conf -config-directory /data/active
25487 pts/0 S+ 0:00 grep telegraf

Узнаем, работает ли у нас mbusd (нет не работает, его нет в списке процессов)

root@napi-rk3328:~# ps ax | grep mbusd
25516 pts/0 S+ 0:00 grep mbusd
root@napi-rk3328:~#

Если мы не знаем как называется сервис, но знаем хоть начало названия, все равно ps покажет запущен или нет процесс по любому шаблону, например по шаблону "tele".

root@napi-rk3328:~# ps ax | grep tele
415 ? SLsl 139:31 /usr/bin/telegraf -config /etc/telegraf/telegraf.conf -config-directory /data/active
25527 pts/0 S+ 0:00 grep tele
root@napi-rk3328:~#

Но в целом, это уже метод "последней надежды", пользуйтесь systemctl.

P.S. В Ubuntu также есть команда service