惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
Schneier on Security
A
Arctic Wolf
S
Security Affairs
O
OpenAI News
SecWiki News
SecWiki News
TaoSecurity Blog
TaoSecurity Blog
H
Heimdal Security Blog
T
Threat Research - Cisco Blogs
Hacker News: Ask HN
Hacker News: Ask HN
N
News | PayPal Newsroom
Google Online Security Blog
Google Online Security Blog
C
Cisco Blogs
The Hacker News
The Hacker News
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
C
CXSECURITY Database RSS Feed - CXSecurity.com
P
Privacy International News Feed
V
Vulnerabilities – Threatpost
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
酷 壳 – CoolShell
酷 壳 – CoolShell
H
Hacker News: Front Page
T
Tenable Blog
T
The Exploit Database - CXSecurity.com
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Spread Privacy
Spread Privacy
人人都是产品经理
人人都是产品经理
www.infosecurity-magazine.com
www.infosecurity-magazine.com
V2EX - 技术
V2EX - 技术
L
LINUX DO - 最新话题
The GitHub Blog
The GitHub Blog
博客园 - 三生石上(FineUI控件)
T
The Blog of Author Tim Ferriss
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
V
Visual Studio Blog
The Cloudflare Blog
N
News and Events Feed by Topic
量子位
Google DeepMind News
Google DeepMind News
Application and Cybersecurity Blog
Application and Cybersecurity Blog
L
LINUX DO - 热门话题
P
Palo Alto Networks Blog
Stack Overflow Blog
Stack Overflow Blog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Attack and Defense Labs
Attack and Defense Labs
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Hacker News - Newest:
Hacker News - Newest: "LLM"
Apple Machine Learning Research
Apple Machine Learning Research
The Register - Security
The Register - Security
Microsoft Security Blog
Microsoft Security Blog
Know Your Adversary
Know Your Adversary
Webroot Blog
Webroot Blog

Все публикации подряд на Хабре

Ловим музу за клавиатуру: как айтишнику стать автором Что умеет Midjourney в 2026? Мой немного грустный разбор этого шикарного инструмента Никто не любит писать тесты, но ИИ может исправить это IPv8 выглядит как мечта. Поэтому почти наверняка не взлетит Производители вернули в продажу материнки с DDR3. Что происходит? Управление агентом с телефона через Telegram теперь в KodaCode От координации к лидерству: как меняется роль руководителя разработки Я сделала родителям бизнес вместо пенсии: зарабатываем 70 тысяч, мама не даёт продать В три раза быстрее приемка товара и оптимизация трудозатрат на 73%: как «РСТ-Инвент» помог Gulliver Group ИИ-шечный мир победил? О влиянии искусственного интеллекта на игропром Кремль снижает давление на Телеграмм пока Европа строит интернет по паспорту Как CEO, CTO и CIO за 8 часов собрали ИИ-директора, который умеет держать позицию под давлением Как (не) потерять домен за выходные Вместо 8 разных VPS: как я организовал практику студентам на одном сервере Почему твой Open Source проект не замечают? R&D: искусство управления неопределенностью в разработке AI-дефляция: вакансий для разработчиков больше, а рост зарплат — худший за 15 лет Мы отдали управление роботами OpenClaw. Что из этого вышло Галактический ID: система идентификации для всех форм разумной жизни Шесть основ бизнес-анализа: начинаем с вопроса «Кто в игре?» Код-ревью, в котором дело не в коде Данные переехали. Команда — нет Системной подход к сдаче OSWE в 2025 Почему комната управления реактором покрашена в цвет морской пены 4 YAML-файла вместо PySpark: как аналитикам строить пайплайны без разработчиков LLM-агент для поиска свободных доменов: автоматизируем подбор Когда, зачем и как правильно начинать новую сессию в Claude Code? Как я заставил нейросеть писать макросы для FreeCAD Анатомия ИИ‑агента для подбора персонала. От тысячи резюме к топ‑10 за минуты Опыт разработчика как экономика внимания Автономность как точка невозврата: кто будет субъектом в цифровом будущем Обучение ИИ в «диких» условиях: как рутинные действия превращаются в датасеты Как измерить LLM для задач кибербеза: обзор открытых бенчмарков Где хранить код? Сравнение GitHub, GitLab и Bitbucket Математика объясняет, почему нормальное распределение встречается повсюду Почему ваш FinOps не работает: 12 тезисов от практиков Как подписать проектную документацию УКЭП с использованием бесплатных лицензий Pilot Адаптивное администрирование Sigla Vision Я грузил уран в бочки, а потом 20 лет строил ИТ в атомной отрасли Чем позвонить с Эвереста? История и обзор спутниковой связи. Часть 2 Как языковая модель помогает контролировать качество инструктажей по охране труда в металлургии Как не передать на desktop свой IP в РКН Анатомия SAP Privileges: как устроено управление правами в macOS MoneyDev: Сказка про три главных слова Обновлённый токенизатор видео K-VAE 2.0 от Сбера Как сделать диспетчеризацию дома на 1284 квартиры почти бесплатно Как мы разогнали железную дорогу Мы дали агентам рутину. Теперь надо решить — что делать с освободившимся временем Токсичный контент, промпт-хакинг и защита ИИ — всё о Guardrails для LLM Умный город начинается с точного взгляда: как «Фалькон Тех» меняет пространство к лучшему Навайбкодил приложение для анализа графов Почему Дюну так интересно читать? Упрощаем работу с рутиной или как стать Гендальфом Белым Деконструкция Go: CPU, RAM и что там происходит. Go Assembler база. Часть 1.1 Какие профессии исчезнут из-за ИИ, а какие появятся? И что с этим делать Как мы построили IT-отдел, где хочется расти: архитектурные встречи, прозрачные метрики и книжные подарки Rufler: Делаем из Claude Code автономный рой через один YAML-конфиг Sing-box и белый список приложений Как построить надёжный обмен сообщениями в микросервисах: лучшие практики для enterprise OpenAI строит MLM-пирамиду, а McKinsey и Accenture помогают ей в этом Дом, который не построил Фишер (Часть 2) «Сверхзвуковой математик» против «Вдумчивого логиста»: битва алгоритмов 3D-упаковки Мультимодальные модели – грубый и дорогой инструмент Разговоры ничего не стоят. Код тоже Проверки физических лиц: с кого начнет ФНС Топ-10 бесплатных нейросетей для создания видео в 2026 году Первые слои кода: как наши решения сегодня определяют архитектуру ИИ на десятилетия Разработка нового статического анализатора: PVS-Studio JavaScript Поиск уязвимостей ПО: базовый минимум или роскошный максимум Почему оценка персонала не работает как инструмент управления Как мы разработали ИИ-ассистента и сократили рутину продуктовой команды на 50% Как я ушел из найма, нажарил косточек и продал на маркетплейсах на 168 млн в год Когда 1С:ERP уже внедрена, а нормального производственного плана всё ещё нет Как я сделал Claude мультимодальным, подключив к нему Qwen Omni Как приглашение на вакансию мечты превращается в атаку Infrastructure as Code: философия и лучшие практики IaC Тестируем Yandex Code Assistant на задаче, в которой нужно хранить секреты nxs-universal-chart v3.0: новое поколение универсального Helm-чарта Callback Injection: Техника, которая отправила Microsoft Defender в глухой нокаут «Все идеи на стол»: митап как способ вывести проект из тупика Сегодня я узнал нечто новое о GPU благодаря багу в своей игре Как заставить LLM ̶ ̶г̶а̶л̶л̶ю̶ ̶ эволюционировать Карта событий как фундамент аналитики: практический кейс для E-commerce Что выбрать для AI: x86, ARM или RISC-V? Дайджест железа за март Роль соматических мутаций в развитии аутоиммунных заболеваний: путь к избирательной терапии Mythos от Anthropic — тревожный сигнал для всех, а не только для банков Guardrails для LLM на Java: как приручить промпт‑инъекции и токсичные ответы Green-VLA: как мы собрали VLA-модель для реального антропоморфного робота и не потеряли обобщение Финансовая гонка вооружений: почему умные люди добровольно в ней участвуют Эра ИИ-агентов наступила: выбираем лучшего цифрового сотрудника # Практический опыт внедрения WinCC Redundancy на производственном предприятии Сделал MVP за 3 дня, а потом неделю прикручивал оплату. Оно того стоило? Физика против Маска: почему Starship V3 может оказаться ещё одной катастрофой Нефть Венесуэлы: крупнейшие запасы в мире, но не крупнейшая нефтяная держава JPA 4. Переосмысление Hibernate Почему зеркальная фотокамера Nikon D5 десятилетней давности идеально подошла для миссии «Артемида-2» Проект «Уровень-Спутник» или как мы сделали платформу для гидрологов «Замедлиться, чтобы ускориться»: почему ИИ повышает цену ошибок в требованиях и архитектуре Как с нуля поднять трафик IT-компании на 1657% при бюджете 55 тыс. и выжить Pixel-perfect Downsampling — идеальная отрисовка 50 миллионов точек без потерь
Ещё один круг ада: мониторинг ERP без Prometheus, Grafana и выделенного DevOps
mainbotan · 2026-05-09 · via Все публикации подряд на Хабре

7 мин

12K

Привет, Хабр. Меня зовут Серафим Недошивин, уже как год я пишу мультитенантную ERP-подобную систему (Go, pgx | next.js, ts) для малого бизнеса и, чтобы не сойти с ума, рассказываю о проблемах, с которыми сталкиваюсь на этом нелёгком пути. В первой статье речь шла о 10 в первую очередь архитектурных проблемах (или кругах ада), включая изоляцию данных организаций, систему доступов и миграции схем базы данных.

Причина, по которой написана уже эта статья, крайне проста: загнивая от усталости, дописывая последнюю строчку последнего (или не очень) модуля системы, теша себя мыслями о скорой зарплате, каждый уважающий себя философ задаётся вопросом - а как контролировать в бою всё то, что мы написали¿¿

  • Глупец скажет - никак, мы же покрыли тестами.

  • Хитрец скажет - Grafana+Prometheus отдельными сервисами.

  • Психопат на крайней стадии выгорания скажет - поднимем отдельную админку и будем собирать метрики и инциденты без прометеуса, снимая снимки системы каждую минуту асинхронными воркерами под каждый компонент платформы, включая сервер, базу данных, объектное хранилище и кэш. На лету будем высчитывать дельты серверных метрик, а в завершение отрисуем всё это дело без графаны, силами Recharts и Святого Духа, упакуем в отдельную панель для технических администраторов и наконец - сделаем клиентский status-page платформы.

Очевидно, что автор этой статьи относится к последнему типу. По этой причине сегодня речь пойдёт об опыте построения самодельной системы мониторинга и интеграции её в уже существующую административную панель платформы. Приятного чтения.

От автора: всё, описанное в статье, не является эталоном и не утверждает о целесообразности использования такого подхода в других проектах. Многое можно реализовать гораздо чище и интеллигентнее.

Kroncl - разработчикам | GitHub проекта

Мониторинг сервера

Мониторинг сервера

База

Для начала определимся с тем, что и с какой целью будем мерить. Начнём с того, что практически каждое приложение можно разделить на компоненты/сервисы, в числе которых наиболее вероятно будут: api-сервер, база данных, кэш, файловое хранилище. Каждый из этих сервисов, что очевидно, может в любой момент упасть и, что ещё более очевидно, имеет свои лимиты допустимых значений нагрузки.

Таким образом, ваш Go-сервер может выдержать нагрузку, скажем, в 1000 RPS, а инстанс PostgreSQL имеет максимально допустимый лимит схем в 1000, при превышении которого скорость работы сервиса значительно снизится.

В совокупности каждый компонент платформы имеет несколько критичных метрик, по которым можно и нужно определять работоспособность всей платформы. Для краткости статьи сфокусируемся на двух наиболее критичных сервисах Kroncl (название платформы) и не будем упоминать мониторинг бизнес-метрик (это тема для отдельной статьи).

Итак, наша цель — собирать метрики с двух компонентов:

  • Go-сервер: requests_total, requests_5xx_total, requests_4xx_total, avg_response_time_ms, p95_response_time_ms, goroutines_count, heap_alloc_mb, open_fds_countполный набор метрик

  • Postgres: total_database_size_mb, total_schemas_count, total_tables_count, total_active_connections, xact_commit, xact_rollback, tup_fetchedполный набор метрик

Особое внимание в случае Kroncl стоит уделить базе данных, ведь мультитенантность здесь реализована с помощью изоляции по схемам, что, очевидно, влечёт за собой жёсткие требования по отслеживанию превышения лимитов схем на инстанс.

Как собирать?

Индустриальный стандарт для обеспечения observability сервисов - Prometheus + Grafana. Работает эта прекрасная связка по схеме: Prometheus стучится на отдельный эндпоинт вашего сервера, собирая накопившиеся с момента запуска метрики, после чего Grafana отрисовывает собранные данные в красивые диаграммы. При использовании такого подхода вся работа заключается в обеспечении /metrics эндпоинта для сбора метрик и настройки дашбордов в Grafana.

Но не спешите радоваться. Используя такой подход, вы добавляете сразу 2! новых сервиса в инфраструктуру приложения. Это не кажется проблемой только на dev-стадии проекта. Для использования Grafana в проде придётся конфигурировать дашборды, чтобы всё не слетало после банального рестарта сервиса + разводить порт на отдельный админский поддомен, всеми любимый Prometheus тянет за собой отдельную базу, и, кроме того, вы лишаетесь возможности разграничения доступа между тех. админами платформы (кто и какие метрики видит).

Но конкретно в моём случае критично другое: как формализовывать метрики, хранимые в базе Prometheus, в виде страницы статуса платформы, открытой для всех клиентов? Как определять инциденты на основании превышения системных лимитов того или иного компонента?

Кроме того, по скромному мнению автора, мониторинг сервисов не должен превращаться в беготню по тех. поддоменам платформы и вспоминанию паролей от админки. В идеальном мире контроль над платформой обеспечивается одной единой панелью, включающей как мониторинг системных и бизнес-метрик, так и техническую поддержку клиентов. Поднимается такое творение один раз вместе с ядром платформы.

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

P.S. В конфигурации Kroncl, на всякий пожарный, всё равно присутствуют и Prometheus, и Grafana — как fallback-решение от греха подальше.

Архитектура: воркеры и дельты

Для реализации сборщика метрик не будем изобретать новые подходы. Снимки системы за каждый промежуток времени - лучший вариант, к тому же ещё и просто реализуемый на Go с помощью воркеров поверх robfig/cron/v3.

План такой: под каждый компонент (сервер, база данных) реализуется воркер, собирающий метрики с соответствующего компонента (в случае с сервером - чтение глобальных счётчиков из памяти + расчёт дельт; в случае с базой - подключение и сбор метрик через pgx), после чего собранные данные сохраняются в базу.

В идеале система мониторинга не должна влиять на ресурсы боевого сервера и базы, что приводит к необходимости написания отдельного минималистичного сервера под воркеры и развёртывания отдельной базы для хранения метрик.

Зачем? - В случае полного падения основной базы/сервера (господи, сохрани) система мониторинга останется нетронутой.

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

Реализация двух воркеров сбора метрик находится в core/workers Kroncl, инициализация и shutdown упакованы в точке входа - пакет app сервера. Периоды сбора метрик каждого компонента можно изменять с помощью config/workers.go.

Вспомогательный пакет metrics занимается инициализацией глобальных счётчиков серверных метрик.

Акцентирую внимание читателя на необходимости расчёта дельт некоторых метрик сервера. Дельта — это прирост значения счётчика за интервал между снятием двух последовательных снапшотов. Представьте, что с момента запуска сервера пришло 1000 запросов. Через минуту – 1020. Абсолютные значения (1000, 1020) на графике покажут рост, но пиков не видно. Дельта за минуту — 20 запросов. Так мы видим реальную нагрузку на сервер в каждый момент времени. Таким образом, для каждого цикла воркера мы сохраняем текущее абсолютное значение счётчика, а в БД записываем разницу между новым и предыдущим значением.

В конечном итоге таблицы metrics_db/server_history накапливают метрики с момента старта сервера, помечая каждую метку временными метками. Получаем историю изменения метрик компонентов, в нашем случае — сервера и базы данных.

Аналогично можно реализовать воркеры сбора метрик кэша, например Redis, и файлового хранилища, например Minio. Можно считать количество бакетов, элементы в бакетах, ключи в кэше, максимальный срок жизни строки кэша.

Лимиты & Инциденты

Итак, у нас есть история изменения метрик всех компонентов. Уже на этом этапе можно отображать графики счётчиков за целевой промежуток времени для админов платформы. Но много ли это даёт технически неподкованным пользователям? Вряд ли рядовой администратор диагностирует болезнь сервера, глядя на зашкаливающую метрику распределения кучи (heap_alloc).

Отсюда вытекает потребность в определении некоего отклонения от нормы метрик платформы. Для начала выделим 4 статуса системы и её компонентов:

  • operational - полная стабильность, отсутствие инцидентов;

  • degraded - деградация;

  • partial_outage - частичное нарушение;

  • major_outage - крупный сбой;

Для каждой критичной метрики объявим допустимый предел в config/status.go. Таким образом, можно регулировать жёсткость настроек текущей системы, увеличивая или уменьшая лимиты.

В пакете core/status реализуем логику динамического расчёта статуса всей системы и её компонентов за целевой промежуток времени с шагом анализа в 1 день. Определим количество отклонений от нормы каждой метрики на основе сохранённой истории в базе данных и присвоим каждому отклонению идентификатор вида <тип компонента>.<метрика>.<timestamp>. Каждое такое отклонение от нормы и называется инцидентом. На основе количества инцидентов можно определять статус компонента/всей системы (деградация, частичное нарушение, полная стабильность, крупный сбой).

Примеры инцидентов:

  • server-p95-1778260244

  • server-gc-1778259555

  • db-cache-1778260235

А теперь откроем эндпоинт статуса платформы для всех пользователей и отобразим в стиле я красивый:

Статус платформы

Статус платформы

К динамическому расчёту инцидентов можно добавить кэширование или вовсе запускать отдельным воркером раз в день.

Администрирование

Для детализации метрик и просмотра подробностей состояния отдельных компонентов системы в Kroncl реализована административная панель, совмещающая управление тикетами техподдержки, клиентской базой и просмотр метрик.

Админка строится на системе определения доступа, основанной на числовых кодах от 1 до 5 (модель проще, чем в основной платформе — статья, посвящённая системе прав Kroncl) и X-Admin-Keyword (ключевая фраза, подтверждающая критичные для платформы действия).

Реализация административной панели упакована в admin директории.

Таким образом, администраторы платформы с разными уровнями доступа получают доступ к анализу метрик разных компонентов платформы.

Выглядит это так:

Метрики базы данных

Метрики базы данных

Метрики сервера

Метрики сервера

В завершение

Автор не знает, что сказать в завершение. Наверное, ничего. Система мониторинга своими руками на чистом Go без сторонних сервисов. Благодарю за внимание.

Kroncl - разработчикам | GitHub проекта | Server | Client