Monitoring i observability - dlaczego dowiadujesz się o awarii od klienta, a nie od systemu
Poniedziałek, 9:47. Telefon. Klient: "Od rana nie mogę się zalogować do systemu." Sprawdzasz. Serwer działa, ale baza danych zapchała się w nocy - tabela logów urosła do 50 GB i dysk się skończył. Od 4:23 rano żaden użytkownik nie może pracować. 5 godzin i 24 minuty przestoju, o których dowiedziałeś się od klienta.
W tym samym czasie Twój konkurent ma dashboard, na którym o 4:24 pojawił się alert: "Dysk na serwerze bazodanowym: 95% wykorzystania. Prognoza: pełny za 2 godziny." O 4:30 automatyczny cron wyczyścił stare logi. Przestoju nie było. Nikt nie zadzwonił, bo nie było powodu.
Różnica nie leży w sprzęcie, nie w oprogramowaniu, nie w budżecie IT. Leży w monitoringu - mechanizmie, który sprawia, że system mówi Ci o swoich problemach, zanim staną się problemami Twoich klientów.
Monitoring vs observability - czym się różnią
Monitoring: czy system działa?
Monitoring odpowiada na pytanie binarne: działa / nie działa. Sprawdzasz puls. Jeśli puls jest - pacjent żyje. Jeśli nie - alarm.
- Czy serwer odpowiada na ping?
- Czy strona zwraca status 200?
- Czy baza danych przyjmuje połączenia?
- Czy dysk ma wolne miejsce?
To jest niezbędne minimum. Większość firm nie ma nawet tego.
Observability: dlaczego system jest wolny?
Observability odpowiada na pytania złożone: dlaczego coś nie działa, gdzie jest wąskie gardło, co się zmieniło.
- Dlaczego strona ładuje się 8 sekund zamiast 200 milisekund?
- Które zapytanie do bazy zabiera 90% czasu?
- Czy problem dotyczy wszystkich użytkowników, czy tylko tych z regionu X?
- Od kiedy trwa problem - od wdrożenia wczoraj, czy od 3 tygodni?
Monitoring mówi: "pacjent ma gorączkę". Observability mówi: "pacjent ma gorączkę, ponieważ ma infekcję w prawym kolanie, która zaczęła się 3 dni temu po urazie."
Trzy filary observability
Observability opiera się na trzech rodzajach danych:
Metryki - liczby opisujące stan systemu w czasie. Czas odpowiedzi: 50ms. Zużycie RAM: 4.2 GB. Liczba aktywnych połączeń: 347. Metryki mówią "co" i "ile".
Logi - zdarzenia opisujące co system robił. "Użytkownik jan@firma.pl zalogował się o 09:15. Zamówienie #4523 zmieniono status na 'wysłane'. Błąd połączenia z API kuriera: timeout po 5000ms." Logi mówią "co się wydarzyło".
Trace'y - ślad jednego żądania przez cały system. Użytkownik kliknął "Złóż zamówienie" → Phoenix odebrał request (2ms) → walidacja (5ms) → zapis do bazy (15ms) → Oban: zadanie email (1ms) → Oban: zadanie kurier (1ms) → odpowiedź (24ms). Trace'y mówią "jak" i "gdzie jest wolno".
Co monitorować - konkretna lista
Infrastruktura: podłoga pod systemem
Bez sprawnej infrastruktury nic nie działa. Monitoring bazowy:
CPU - ile procent procesora jest wykorzystywane. Przy 80%+ system zaczyna zwalniać. Przy 100% - stoi.
RAM - ile pamięci jest zajęte. Gdy zabraknie, system operacyjny zaczyna ubijać procesy (OOM Killer). Twoja aplikacja może być jednym z nich.
Dysk - ile miejsca pozostało. Logi, backupy, dane tymczasowe rosną codziennie. Gdy dysk się skończy - baza danych przestaje zapisywać. To jest ten scenariusz z poniedziałkowego ranka.
Sieć - czy serwer jest dostępny z zewnątrz. Czy latencja jest normalna. Czy nie ma packet loss.
Alert: Dysk /var/lib/postgresql: 92% (46 GB / 50 GB)
Tempo wzrostu: 2 GB/tydzień
Prognoza: pełny za 2 tygodnie
Akcja: rozważ czyszczenie logów lub zwiększenie dyskuTen alert daje Ci 2 tygodnie na reakcję zamiast budzenia się z telefonem od klienta.
Aplikacja: czy system robi to, co powinien
Metryki aplikacyjne są cenniejsze niż metryki infrastruktury, bo mówią o doświadczeniu użytkownika:
Czas odpowiedzi (response time) - ile czeka użytkownik na odpowiedź. Mierzony jako percentyle:
- p50 = 50ms (połowa żądań jest szybsza)
- p95 = 200ms (95% żądań jest szybszych)
- p99 = 1200ms (1% żądań trwa ponad sekundę)
Średnia jest bezwartościowa. Średnia z [10ms, 10ms, 10ms, 10ms, 5000ms] to 1008ms - ale 4 z 5 użytkowników czekało 10ms. p95 mówi prawdę: "prawie wszyscy mają szybko, ale 5% ma problem".
Współczynnik błędów (error rate) - procent żądań kończących się błędem. 0.1% to normalne. 1% to ostrzeżenie. 5% to pożar.
Przepustowość (throughput) - ile żądań na sekundę system obsługuje. Nagły spadek (zwykle o 9:00, gdy ludzie zaczynają pracę) oznacza, że system nie daje rady.
Aktywne połączenia WebSocket - w LiveView każdy użytkownik to połączenie WebSocket. Gwałtowny spadek oznacza, że użytkownicy tracą połączenie (problem sieciowy lub crash serwera).
# Telemetry w Phoenix - automatyczne zbieranie metryk
# config.exs
config :my_app, MyAppWeb.Telemetry,
metrics: [
summary("phoenix.endpoint.stop.duration",
unit: {:native, :millisecond},
tags: [:route]
),
counter("phoenix.router.dispatch.stop.count",
tags: [:route, :status]
),
last_value("vm.memory.total",
unit: :byte
),
last_value("vm.total_run_queue_lengths.total")
]BEAM: wgląd, którego nie daje żaden inny runtime
BEAM (maszyna wirtualna Elixira) oferuje poziom observability nieosiągalny w Javie, Pythonie czy Node.js:
Liczba procesów BEAM - typowa aplikacja Phoenix ma 5 000-50 000 procesów. Gwałtowny wzrost (np. z 10 000 do 500 000) oznacza wyciek procesów - ktoś tworzy procesy i ich nie zamyka. To odpowiednik wycieku pamięci, ale łatwiejszy do zdiagnozowania.
Długość kolejek (mailbox) - każdy proces BEAM ma skrzynkę pocztową. Jeśli proces nie nadąża z przetwarzaniem wiadomości, kolejka rośnie. Proces z kolejką 100 000 wiadomości to bottleneck - albo robi za dużo, albo jest zablokowany.
Scheduler utilization - BEAM ma tyle schedulerów, ile rdzeni CPU. Jeśli scheduler jest w 90% zajęty - ten rdzeń jest na granicy. Jeśli wszystkie schedulery są w 90% - potrzebujesz więcej mocy albo optymalizacji.
Garbage collection per process - w BEAM każdy proces ma własny GC. Możesz zobaczyć, który konkretnie proces zabiera czas na GC. W Javie masz "GC pause 200ms" i nie wiesz, który kawałek kodu to spowodował. W BEAM wiesz dokładnie.
ETS tables - współdzielone tablice w pamięci. Rosnąca tabela ETS to potencjalny wyciek pamięci. Monitoring pokazuje rozmiar każdej tabeli.
# LiveDashboard - wbudowany monitoring BEAM
# W routerze Phoenix
live_dashboard "/dashboard",
metrics: MyAppWeb.Telemetry,
ecto_repos: [MyApp.Repo],
ecto_psql_extras_options: [long_running_queries: [threshold: "500 milliseconds"]]Phoenix LiveDashboard jest wbudowany w Phoenix. Nie trzeba nic instalować, konfigurować, płacić. Otwierasz /dashboard i widzisz:
- Procesy BEAM z największym zużyciem pamięci
- Długość kolejek ETS
- Porty (połączenia sieciowe)
- Metryki systemu operacyjnego
- Wolne zapytania do bazy danych
PostgreSQL: baza danych mówi, co ją boli
PostgreSQL ma wbudowaną diagnostykę, z której większość firm nie korzysta:
pg_stat_statements - ranking najwolniejszych zapytań:
SELECT
query,
calls,
mean_exec_time::numeric(10,2) AS sredni_czas_ms,
total_exec_time::numeric(10,2) AS laczny_czas_ms,
rows
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 10;To jest rentgen bazy danych. Wynik mówi: "zapytanie SELECT * FROM zamowienia WHERE... wykonano 45 000 razy w ciągu tygodnia, średnio 340ms. Łączny czas: 4.2 godziny." Jedno zapytanie zabiera 4 godziny czasu procesora tygodniowo. Dodanie indeksu skraca je do 2ms. Zysk: 4 godziny CPU tygodniowo z jednej linijki SQL.
pg_stat_user_tables - statystyki tabel:
SELECT
relname AS tabela,
n_live_tup AS wiersze,
n_dead_tup AS martwe_wiersze,
last_vacuum,
last_autovacuum,
seq_scan AS skan_sekwencyjny,
idx_scan AS skan_indeksowy
FROM pg_stat_user_tables
ORDER BY n_dead_tup DESC;Tabela z 500 000 martwych wierszy? VACUUM nie działał. Tabela z 10 000 skanów sekwencyjnych i 0 skanów indeksowych? Brakuje indeksu. Baza mówi Ci dokładnie, co jest nie tak.
Połączenia - ile połączeń jest aktywnych, ile czeka, ile jest idle. Wyczerpanie puli połączeń to jedna z najczęstszych przyczyn awarii. Monitoring pokazuje trend zanim limit zostanie osiągnięty.
Replikacja - opóźnienie repliki. Jeśli replika jest 30 sekund za primary - dane na dashboardzie są spóźnione o 30 sekund. Jeśli opóźnienie rośnie - replika nie nadąża i trzeba reagować.
Oban: kolejka zadań pod lupą
Oban (kolejka zadań w Elixirze) generuje metryki, które mówią o zdrowiu procesów tła:
Kolejka zadań - ile zadań czeka na wykonanie. Rosnąca kolejka oznacza, że workery nie nadążają. Alert: "Kolejka :email ma 5 000 oczekujących zadań (zwykle: 10-50)."
Czas wykonania - ile trwa przetworzenie zadania. Generowanie PDF trwa zwykle 200ms, dziś trwa 5 sekund? Coś jest nie tak z biblioteką, dyskiem albo CPU.
Współczynnik błędów - ile zadań kończy się niepowodzeniem. 0.1% to normalne (timeout API zewnętrznego). 10% to problem.
Zadania utknięte (stalled) - zadanie w statusie "executing" od 2 godzin? Worker prawdopodobnie umarł bez zgłoszenia wyniku. Oban potrafi to wykrywać i ponawiać automatycznie.
Alerty - sztuka powiadamiania bez spamowania
Monitoring bez alertów jest jak alarm antywłamaniowy podłączony do głośnika w piwnicy - nikt nie usłyszy.
Poziomy alertów
Krytyczny (natychmiastowy) - system nie działa. Użytkownicy nie mogą pracować. SMS + telefon + Slack.
- Serwer nie odpowiada na health check
- Baza danych niedostępna
- Error rate > 10%
- Dysk zapełniony w 99%
Ostrzeżenie (pilny) - system działa, ale coś jest nie tak. Email + Slack.
- Czas odpowiedzi p95 > 2 sekundy (zwykle 200ms)
- RAM > 85%
- Dysk > 85%
- Kolejka Oban > 1000 zadań
- Replikacja opóźniona > 60 sekund
Informacyjny (do sprawdzenia) - anomalia, która nie wpływa na użytkowników teraz, ale może w przyszłości. Slack.
- CPU utylizacja > 70% przez 30 minut
- Nowa wolna kwerenda w pg_stat_statements
- Wzrost liczby procesów BEAM > 20% w ciągu godziny
- Certyfikat SSL wygasa za 14 dni
Alert fatigue - wróg monitoringu
Najgorsze co możesz zrobić: ustawić 200 alertów, z których 190 to fałszywe alarmy. Po tygodniu zespół zaczyna ignorować wszystkie alerty. Gdy przyjdzie prawdziwy alarm - nikt nie zareaguje.
Zasady:
Alertuj na symptomy, nie na przyczyny. "Czas odpowiedzi > 2s" jest lepszym alertem niż "CPU > 80%". CPU na 80% może być normalne przy piku ruchu. Ale czas odpowiedzi 2s zawsze oznacza, że użytkownik czeka za długo.
Każdy alert wymaga akcji. Jeśli alert nie wymaga niczego od Ciebie - nie jest alertem, jest logiem. Wyłącz go albo zmień na log.
Deduplikacja. Serwer nie odpowiada → nie wysyłaj 100 alertów na minutę. Wyślij jeden. Potem co 15 minut: "Problem nadal trwa."
Eskalacja. Alert krytyczny → Slack → jeśli brak reakcji po 15 minutach → SMS → jeśli brak reakcji po 30 minutach → telefon.
Dashboardy - widzieć system jednym rzutem oka
Dashboard operacyjny (dla zespołu IT)
Ekran w biurze IT (albo zakładka w przeglądarce) pokazujący stan systemu w czasie rzeczywistym:
┌─────────────────────────────────────────────┐
│ SYSTEM STATUS: ✓ HEALTHY │
├──────────────┬──────────────┬───────────────┤
│ Response │ Error Rate │ Active Users │
│ p95: 180ms │ 0.02% │ 347 │
│ ▁▂▂▃▂▂▁▂▃▂ │ ▁▁▁▁▁▁▁▁▁▁ │ ▁▃▅▇▇▇▅▃▂▁ │
├──────────────┼──────────────┼───────────────┤
│ CPU │ RAM │ Disk │
│ 34% │ 62% │ 47% │
│ ▂▃▃▂▂▃▃▂▂▃ │ ▅▅▅▅▅▆▅▅▅▅ │ ▄▄▄▄▄▄▄▄▄▄ │
├──────────────┼──────────────┼───────────────┤
│ DB Queries │ Oban Queue │ BEAM Procs │
│ avg: 12ms │ pending: 7 │ 12,847 │
│ ▂▂▃▂▂▂▃▂▂▂ │ ▁▁▁▁▂▁▁▁▁▁ │ ▅▅▅▅▅▅▅▅▅▅ │
└──────────────┴──────────────┴───────────────┘Jedno spojrzenie - wiesz, czy system jest zdrowy. Zielony = spokój. Żółty = obserwuj. Czerwony = reaguj.
Dashboard biznesowy (dla zarządu)
Nie CPU i RAM, ale KPI:
┌────────────────────────────────────────────┐
│ Sprzedaż dziś: 127 450 PLN (+12% vs wt) │
│ Zamówienia: 89 | Średni koszyk: 1 432 │
│ Oczekujące wysyłki: 23 │
│ Zaległe płatności: 45 200 PLN (4 faktury) │
└────────────────────────────────────────────┘Zarząd nie potrzebuje metryk CPU. Potrzebuje odpowiedzi na pytanie: "Jak idzie biznes?" Dashboard biznesowy w LiveView aktualizuje się sam - bez generowania raportów, bez czekania, bez Excela.
Ile kosztuje brak monitoringu
Scenariusz 1: Dysk się skończył
- Czas od awarii do odkrycia: 5 godzin (klient dzwoni)
- Czas naprawy: 1-2 godziny (czyszczenie + restart)
- Przestój: 6-7 godzin
- Koszt: 50-200 pracowników × 6 godzin bez systemu
Z monitoringiem: alert o 4:24, automatyczne czyszczenie o 4:25, przestój: 0 minut.
Scenariusz 2: Wolne zapytanie blokuje bazę
Raport kwartalny (generowany ręcznie) blokuje bazę na 20 minut. Wszyscy użytkownicy czekają. Nikt nie wie dlaczego. Tomek restartuje bazę "żeby odblokować".
Z monitoringiem: pg_stat_activity pokazuje zapytanie blokujące. Alert: "Zapytanie trwa 5 minut, blokuje 23 inne sesje." Akcja: kill zapytania, optymalizacja na wieczór.
Scenariusz 3: Wyciek pamięci
Aplikacja zjada coraz więcej RAM. 4 GB, 6 GB, 8 GB... W poniedziałek OOM Killer zabija proces. System nie działa. Restart. Przez tydzień wszystko OK. W następny poniedziałek - to samo.
Z monitoringiem: trend wzrostu pamięci widoczny na wykresie. Alert: "RAM wzrasta liniowo: +500 MB/dzień. Obecne: 6.2 GB / 8 GB. Prognoza: OOM za 3 dni." Czas na diagnozę i naprawę bez presji.
Scenariusz 4: API partnera padło
API kuriera nie odpowiada od 2 godzin. 150 paczek nie zostało nadanych. Handlowcy obiecują klientom wysyłkę "dziś". Paczki nie wyjadą.
Z monitoringiem: alert po 5 minutach nieodpowiadającego API. Oban automatycznie ponawia. Dashboard: "API InPost: DOWN od 10:15. 23 przesyłki w kolejce retry. Następna próba: za 5 minut." Decyzja: czekaj albo nadaj ręcznie przez panel InPost.
Policzmy
Firma bez monitoringu ma średnio 2-4 nieplanowane przestoje miesięcznie. Każdy trwa 1-6 godzin. Przy 200 pracownikach i koszcie przestoju 100 PLN/h/osobę:
- 3 przestoje × 3 godziny × 200 osób × 100 PLN = 180 000 PLN/miesiąc
- To jest 2.16 mln PLN rocznie utracone na przestoje
Oczywiście nie każdy przestój dotyka 200 osób na 3 godziny. Ale nawet przy konserwatywnych założeniach (1 przestój × 1 godzina × 50 osób) to 60 000 PLN rocznie.
Koszt monitoringu? 5 000-20 000 PLN za wdrożenie + 500-2 000 PLN/miesiąc za narzędzia. Ułamek kosztu jednego incydentu.
Jak budujemy monitoring - nasz stack
Warstwa 1: Health checks
Najprostszy mechanizm - endpoint /health sprawdzany co 10 sekund:
defmodule MyAppWeb.HealthController do
use MyAppWeb, :controller
def check(conn, _params) do
checks = %{
database: check_db(),
oban: check_oban(),
disk: check_disk(),
memory: check_memory()
}
status = if Enum.all?(checks, fn {_, v} -> v == :ok end), do: 200, else: 503
json(conn |> put_status(status), checks)
end
defp check_db do
case Ecto.Adapters.SQL.query(Repo, "SELECT 1") do
{:ok, _} -> :ok
_ -> :error
end
end
defp check_disk do
{output, 0} = System.cmd("df", ["-h", "/"])
if parse_usage(output) < 90, do: :ok, else: :warning
end
endZewnętrzna usługa (UptimeRobot, Healthchecks.io, własny monitor) odpytuje /health. Jeśli zwraca 503 - alert.
Warstwa 2: Metryki aplikacyjne (Telemetry)
Elixir ma wbudowany framework Telemetry - standardowy sposób zbierania metryk:
# Metryki Phoenix
:telemetry.attach("request-handler",
[:phoenix, :endpoint, :stop],
fn _event, measurements, metadata, _config ->
duration_ms = System.convert_time_unit(
measurements.duration, :native, :millisecond
)
route = metadata.route
status = metadata.conn.status
StatsD.histogram("http.request.duration", duration_ms,
tags: ["route:#{route}", "status:#{status}"])
end,
nil
)Metryki eksportowane do Prometheus/Grafana, Datadog, lub własnego dashboardu w LiveView.
Warstwa 3: Logi strukturalne
Nie IO.puts("coś się stało"), ale strukturalne logi z kontekstem:
Logger.info("Zamówienie utworzone",
order_id: order.id,
customer_id: order.customer_id,
total: order.total,
items_count: length(order.items),
source: "web"
)
# Wynik w JSON (do Elasticsearch/Loki/CloudWatch):
# {"level":"info","msg":"Zamówienie utworzone",
# "order_id":4523,"customer_id":789,
# "total":"1450.00","items_count":3,"source":"web",
# "timestamp":"2026-02-22T09:15:23Z"}Strukturalne logi można filtrować, agregować, wizualizować. "Pokaż wszystkie błędy z modułu zamówień w ostatniej godzinie" - jedno zapytanie. Z IO.puts - grep po gigabajtowych plikach tekstowych.
Warstwa 4: Phoenix LiveDashboard
Wbudowany w Phoenix dashboard dostępny pod /dashboard:
- Metryki OS - CPU, RAM, dysk, sieć w czasie rzeczywistym
- Procesy BEAM - sortowane po pamięci, długości kolejki, redukcjach
- ETS - tablice w pamięci z rozmiarem
- Porty - połączenia sieciowe
- Ecto - wolne zapytania, statystyki tabel, indeksy
- Oban - kolejki, zadania, błędy
Zero instalacji, zero konfiguracji, zero kosztów. Jest w każdym projekcie Phoenix.
Warstwa 5: Alerty
# Moduł alertów
defmodule MyApp.Alerts do
use GenServer
# Sprawdzaj co minutę
def handle_info(:check, state) do
check_response_time(state)
check_error_rate(state)
check_queue_depth(state)
check_disk_space(state)
Process.send_after(self(), :check, :timer.minutes(1))
{:noreply, state}
end
defp check_response_time(state) do
p95 = Metrics.response_time_p95(last_minutes: 5)
cond do
p95 > 5_000 ->
notify(:critical, "Response time p95: #{p95}ms (> 5s)")
p95 > 2_000 ->
notify(:warning, "Response time p95: #{p95}ms (> 2s)")
true ->
:ok
end
end
defp notify(:critical, message) do
Slack.send("#alerts-critical", message)
SMS.send(on_call_number(), message)
end
defp notify(:warning, message) do
Slack.send("#alerts-warning", message)
end
endMonitoring a RODO i compliance
Monitoring to nie tylko wydajność. To też compliance:
Audit log - kto kiedy uzyskał dostęp do danych osobowych. RODO wymaga rejestru czynności przetwarzania. Monitoring go zapewnia automatycznie.
Wykrywanie anomalii - pracownik eksportuje 10 000 rekordów klientów o 22:00? To normalne czy próba kradzieży danych? Monitoring widzi anomalię i alarmuje.
Raportowanie incydentów - RODO wymaga zgłoszenia naruszenia w 72 godziny. Bez monitoringu nie wiesz, że naruszenie nastąpiło. Z monitoringiem masz dokładny timestamp, zakres i wpływ.
Od zera do monitoringu - plan wdrożenia
Tydzień 1: Health check + uptime monitoring
Dodaj endpoint /health. Podłącz UptimeRobot (darmowy plan: 50 monitorów, sprawdzanie co 5 minut). Skonfiguruj alert na email i Slack. Czas: 2 godziny.
Od teraz wiesz, że system nie działa, w ciągu 5 minut zamiast 5 godzin.
Tydzień 2: Metryki bazowe
Dodaj monitoring CPU, RAM, dysk (node_exporter + Prometheus + Grafana, albo prosty skrypt z alertem). Ustaw progi alertów: dysk > 85%, RAM > 85%. Czas: 4 godziny.
Od teraz wiesz o zapchanych dyskach i wyciekach pamięci zanim spowodują awarię.
Tydzień 3: Metryki aplikacyjne
Dodaj Telemetry do Phoenix (jest domyślnie). Skonfiguruj LiveDashboard (jest domyślnie). Dodaj dashboard w Grafana z czasem odpowiedzi, error rate, throughput. Czas: 1 dzień.
Od teraz wiesz, czy system jest wolny i dla kogo.
Tydzień 4: Logi i PostgreSQL
Skonfiguruj strukturalne logi (JSON). Włącz pg_stat_statements. Dodaj dashboard z wolnymi zapytaniami i statystykami tabel. Czas: 1 dzień.
Od teraz wiesz, które zapytanie zabija wydajność bazy.
Ciągle: Tuning alertów
Alerty to żywy organizm. Przez pierwsze tygodnie będą fałszywe alarmy. Dostrajaj progi. Wyciszaj szum. Po miesiącu alerty powinny być rzadkie i zawsze trafne.
Podsumowanie
| Aspekt | Bez monitoringu | Z monitoringiem |
|---|---|---|
| Odkrycie awarii | Telefon od klienta (godziny) | Alert automatyczny (sekundy) |
| Diagnoza problemu | "Coś nie działa, nie wiem co" | "Zapytanie X blokuje bazę od 10:15" |
| Prognozy | Brak ("dysk się skończył o 4 rano") | "Dysk pełny za 2 tygodnie" |
| Wydajność bazy | "System muli" | "Top 3 wolne zapytania do optymalizacji" |
| Wyciek pamięci | OOM crash w poniedziałek | Trend widoczny na wykresie, naprawa w spokoju |
| Compliance (RODO) | "Nie wiemy kto miał dostęp" | Pełny audit log |
| Koszt roczny przestojów | 60 000-2 000 000 PLN | 6 000-24 000 PLN (narzędzia) |
Chcesz wiedzieć o problemach w swoim systemie zanim dowiedzą się Twoi klienci? Porozmawiajmy - wdrożymy monitoring, który zamieni nocne telefony w spokojne poranki.