# Сбор метрик 1. при сборе о внешнем ip адресе, sh скрипт обрщается к внешнему сервису - `ifconfig.co` таким способом: ```curl --connect-timeout 3 --interface $1 ifconfig.co``` в итоге, все наши шлюзы обращаются к ненашему сервису, это может быть проблемой с защищенностью? при этом `net.*.ip_global` метрика не встречается в текущих метриках. кажется не собирается это поле, но оно есть в описании протобафа, значит должно быть и в собираемых данных. это надо проверить. 2. sh собирает метрики в виде списка проперти, для некоторых свойств типа информации о файловой системе и сетевых интерфейсах, можно использовать индекс в теге (сейчас точка монтирования, или имя интерфейса) сейчас: ``` fs./.avail=6230016 fs./.used=40271872 fs./.size=46501888 fs./tmp.avail=262832128 fs./tmp.used=90112 fs./tmp.size=262922240 fs./configs.avail=17416192 fs./configs.used=81920 fs./configs.size=17498112 fs./var/log.avail=50794496 fs./var/log.used=39325696 fs./var/log.size=95006720 ``` нужно, (так не будет проблем если path сама имеет точку) ``` fs.0.mount="/"" fs.0.avail=6230016 fs.0.used=40271872 fs.0.size=46501888 fs.1.mount="/tmp" fs.1.avail=262832128 fs.1.used=90112 fs.1.size=262922240 fs.2.mount="/configs" fs.2.avail=17416192 fs.2.used=81920 fs.2.size=17498112 fs.3.mount="/var/log" fs.3.avail=50794496 fs.3.used=39325696 fs.3.size=95006720 ``` также на индекс в именах метрик перейти и при сборе сетевых метрик, т.е. вместо ``` net.ppp.ping_max=151.650000 net.ppp.ready=false net.ppp.ip_local=10.15.47.27 net.tun.exists=true net.tun.carrier=true net.tun.rx_errors=0 net.tun.rx_dropped=0 ``` собирать метрики так: ``` net.0.iface=ppp net.0.ping_max=151.650000 net.0.ready=false net.0.ip_local=10.15.47.27 net.1.iface=tun net.1.exists=true net.1.carrier=true net.1.rx_errors=0 net.1.rx_dropped=0 ``` 3. сейчас скрипт который собирает метрики, захламляет вывод с ошибками, и не понятно это ошибка при сборе метрик, или это правильный метод работы скрипта. такие строки сейчас просто игнорируются при разборе метрик. ``` net.ppp.ready=false cat: can't open '/sys/class/net/ppp0/carrier': No such file or directory net.ppp.carrier=false ``` ``` net.ppp.ready=false cat: can't open '/sys/class/net/wwan0/carrier': No such file or directory net.ppp.carrier=false ``` 4. если сохранить метрик в протобафа и в виде строк и сжать их gzip, то разница всего в 2 раза. 500 байт в виде протобафа и 1000 байт в виде сжатых строк. за месяц это `31*24*60` сбора метрик - 22 мегабайта в протобафе, 44 мегабайта в сжатых строк. в итоге добавление протобафа это экономия 22 мегабайта в месяц на шлюзе и сильно усложняется процесс обновления кода. 5. сейчас скрипт собирает метрики в виде строк, а lorawan агент посылает метрики в мониторинговый агент как json. непонятно зачем есть 2 варианта парсинга строк, из json и из property строк. надо придти к одному варианту. будет меньше кода при парсинге. 6. сейчас лораван агент посылает метрики в мониторинговый через unix сокет пушит метрики. было бы хорошо если бы все возможные метрики собирал скрипт. допустим, скрипт бы обращался бы к лораван агенту и вытягивал метрики. к примеру, ловаран агент предоставлял свои метрики по http или unix сокету, скрипт обращается раз в минут и забирает метрики, к примеру `curl` умеет читать данные по unix сокету. и в итоге мониторинговый агент почти исчезает, (в агенте остается только хранение метрик, пересылка) все метрики собирает скрипт. 7. сейчас монитринговый агент не собирает версии агентов, было бы хорошо если бы в метриках были бы версии агентов, тогда можно было отслеживать когда просходили обновления агентов. sh может спрашивать версии у самих агентов, а может просто читать текстовой файл, который распостраняется при обновлении вместе с агентами. (может быть собирать и другие данные) 8. нужно вести учет sh скриптов и их либ. типа ranmon_stat.sh, /lib/functions/wwan.sh 9. попробовать разделить скрипт на несколько частей и запускать скрипты сбора метрик параллельно. 10. можно упростить парсинг. сейчас парсинг идет в 2 стадии, сначала строки конвертируются в `map[string]interface{}`, а значения стразу парсится в float64, int, bool, string. фактически map of maps. а потом эти map of maps конвертируется в протобаф, и значения опять пытаются конвертироваться в нужные типы протобафа. получается двойное преобразование типов. и нагрузка на gc, из-за конвертации значений в interface{}. можно этого избежать и хранить просто строки и конвертировать сразу их в протобаф (на этом этапе ты знаешь типы значений) минуя стадию maps of maps. пример как можно сделать парсинг в протобаф ``` // example metrics: // sys.version="fw.cloudcell@2020.1-canary" // sys.uptime=671224.58 // // path:=["sys","version"], v:="fw.cloudcell@2020.1-canary" // path:=["sys","uptime"], v:="671224.58" // func FillSystem(path []string, v string, system *monitoring.System) error { switch path[1] { case "version": system.Version = v case "uptime": value, err := strconv.ParseFloat(v, 32) if err != nil { return err } system.Uptime = uint64(value) case "lrr": value, err := strconv.ParseUint(v, 10, 32) if err != nil { return err } reason := monitoring.System_LastResetReason(value) system.LastResetReason = reason } return nil } ``` 11. в протобафе несколько разных типов - string, bool, int32, uint32, uint64, float64. это усложняет парсинг, а к примеру victoria metrics умеет только float64 и это покрывает все возможные наши размеры значений. 12. метрики по сети собираются с name="Ehernet", и в итоговом протобафе отсутствуют какое либо поле с названиями "ppp", "eth", "tun". а ran в названиях использует именно "ppp","eth","tun". и поэтому неправильн обрабатывались сетевые метрики в ran. теперь приходится делать маппинг таких названий "Ehernet" -> "eth", "VPN"->"tun" в сервисе на стороне ran. 13. у нас отдельный демон написннаый на си для сбора метрик по power. он раз в 2 сек читает данные данные файла из /sys/* и если напряжение стало падать, пишет метрики в мониториговый агент через unix socket в виде json, но это может делать и сам мониторинговый агент, т.е. можно удалить отдельный сишный проект. (и sh скрипт тоже может читать эти данные) 14. можно сейчас удалить lora метрики, упростится мониторинговый агент, а через время, можно эту функциональность добавить. 15. в протобафе вместо списка сетевых интерфейсов описать 3 переменные. у нас в коде заложено что должно быть 3 метрики с особыми именами и параметрами. это сделает более явным описание метрик именно так как у нас и используется. для этого в протобафе https://gitlab.everynet.io/platform/ran/agent.protobuf/-/blob/master/monitoring.proto вместо ``` message MonitoringData { ... repeated Interface interface = 11; ... } ``` описать так: ``` message MonitoringData { ... Interface eth = 15; Interface ppp = 16; Interface tun = 17; ... } ``` 16. прилетела метрика с ошибочными сетевыми данными. ``` { "id": 2, "exists": true, "carrier": true, "rxBytes": "759035", "txBytes": "2194792" } ``` пропущены обязательные поля name, ifname. без этих полей не получается перевести метрики в старый формат и разпознать сетевые метрики в gw_updater. **вопрос на обсуждение**: что должен делать в таких ситуациях сервер, если он не подтвердит такие метрики, то они будут присылаться постоянно и трафик сожрется. если подвердит, но не запишет в базу, то метрики потеряются. надо определиться с политикой ack метрик. на текущий момент сервер игнорирует ошибочные метрики, пишет в лог ошибки 17. нужно добавить в сбор метрик статистику по лоре агенту: last_rx_timestamp, last_tx_timestamp. которая будет показывать как лора агент общается с ran-lorawan сервисом. 18. редно бывает ошибка валидации метрик (значение lrr строкой прилетает) - https://sentry.k8s.dev.everynet.io/sentry/ran/issues/227455/ надо проверить, может быть валидация неправильная - https://gitlab.everynet.io/platform/ran/agent.protobuf/-/blob/v1/monitoring.proto - https://gitlab.everynet.io/platform/ran/ran/-/blob/master/utils/validator.py 19. порой прилетает ошибка с метрикой csq, https://sentry.k8s.dev.everynet.io/sentry/ran/issues/227455/?query=is%3Aunresolved invalid literal for int() with base 10: '2AT+QCCID' csq: '2AT+QCCID' 20. надо ли добавить в метрики разницу между gps_time от железки и utc time от линукса, чтобы понимать что utc на шлюзе убежал от реального ## Идеал текуший процесс добавления и удаления новых метрик: - добавить сбор новой метрики в sh скрипт - добавить метрику в протобаф описание - обновить исходники с протобафом в агенте и в мониториговом сервисе в ran - добавить парсинг этой метрики в агент (маппинг метрики на протобаф) - добавить тест на сбор этой метрики - обновить агент и sh скрипт на шлюзах - обновить мониторинговый сервис в ran - добавить поле в кликхауз и обновить метрикс-keeper, что бы новое поля сохранялось в clickhouse - обновить/добавить графики в графане а в идеале изменение метрик должно происходить горазбо быстрее и проще: - добавить сбор новой метрики в sh скрипт - добавить тест на сбор метрики - обновить sh скрипт на шлюзах - обновить/добавить графики в графане этого можно добиться если: - пересылка метрик будет не статическая (протобаф), а просто текстом или json, сжатым gzip(для экономии трафика на шлюзе) (ну еще сильнее сжатым с zstd со нашим словарем). - метрики будут сохранять не в статический кликхауз, а допустим в victoria metrics. из-за статической схемы в кликхауз надо делать миграции и обновлять сервис сохранения метрик в кликхауз