Галоўная / Артыкулы

Стварэнне API для Node.js з можлівасцю аблявання: логаванне, метрыкі і трэйсінг

Дазвольце дазнацца, як структураваныя логіі, трэйсінг запытоў, метрыкі і адлагоджаная сістэма паведамленняў спяваюць разам, чынячы адлагоджванне API-ў на Node.js у працоўным режыме значна менш стрэсавым.

Выдавец: REACTAPP.TOP17 хв чытання4023 слоў

Крыніцы: When Your Node.js API Breaks: What I Learned About Logging and Observability

Калі вы пачаткі разы працуеце над API на Node.js, большая частка вашай увагі прыкладзваецца да пераканання, што код дэйсна працуе.

Канчатковая тэпа вяртае тую адпаведнасць, якой вы чакалі.

Запыт да базы дадзеных выконваецца правільна.

Процес аутэнтыкаціі працуе так, як і планавалася.

Фронтэнд і бэкэнд размовляюць адзін з другім без проблем.

У такі момент вы можаце припусціць, што API готава.

Але згодзейшыся выклікаецца іншы вопыт:

Што будзе, калі ў чымсь з’явятся проблэмы, а вы ў той момент не стаяце пры кодзе?

Запыт можа зазнаць няудачы, калі сервіс вже запусцены.

Запыт да базы дадзеных пачынае займаць занадта много часу.

Зовнішній сервіс перестае рэагаваць.

Пользователь паведамляе вас пра проблэму.

Канчатковая тэпа неспадзявана пачынае выдаваць кешэнія 500.

Сам сервіс можа ўсё ўсё працаваць.

Праўя задача — з’ясаваць чаму ён працюе некоректна.

Самэлькі момент, калі логаванне і можлівасць аналізу перестаюць быть дадатковым элементам і стаюць ключовай часткай практыкі стварэння API.

Створэнне API, якое правільна працюе, — це адна з задач.

Створэнне API, якое можна реальна діагноставаць, калі ён перестае працюваць, — цэла іншая задача.

Логаванне было першым элементам, які мне паўтарна трэба было перадумаць

Як і большасць людзей, якія вучаюцца програмаванню, пачатковыя прычыны логавання зазвычай абумованыя на console.log().

Што-та на кшталт:

console.log("Login request received");
console.log(user);
console.log("Database query completed");

Такі падход добра працуе для локальнага розвітку.

Ён шырок.

Ён просты.

А калі вы дебагуеце на сваёй машыне, у вас вже є достатнькі даны, каб зрозумець выходны результат.

Калі складнасць прыкладнення зростае, ўсё пачынае ламацца.

Вам можа давацца справа з сотнямі або тысячамі одночасных запитоў.

Багато разных выкарыстоўвальнікаў.

Калькі екземпляраваў вашагу API, якія працуюць адразу.

Фонавыя заданні, якіе выкананы паралельна.

Постаўкі да базы дадзенаў, якія вядуцься постаўна.

Запыты да сторонніх служб.

Прабавы аутантыкаціі, якія не ўспыхваюць.

Праўда, у такім масштабе накуп неструктураваных стрэнгаў, выведзеных у тэрмінал, втрачае большую частку свайго значэння.

Гэта спрыяла змінам у падходзе да логаў.

Запіс у логу не должен проста паведамляць:

"Осё-такі ўсёлякое адбылася."

У замен, хорашы запіс у логу должен дазволіць вам з’ясаваць, што на самай праўдзе адбылася, у які момент, якая частка системы была задзейнана, а таксама всі дапаможныя деталі, якія патрэбны для правильнага аналізу.

Прыгодны логі маюць контэкст

Паглядзіце на разлік межа гэтымі двумя падходамі.

Не дужа прыгодна

Something went wrong

Порівнянне з:

{
  "level": "error",
  "message": "Database query failed",
  "method": "GET",
  "route": "/api/projects",
  "requestId": "abc123",
  "durationMs": 842
}

Вялікі варыянт адразу ж дае вам набліжнае больш прыгодная інфармацыя.

Вы можете адразу ж з’ясаваць:

  • Што саме стало прычыной абярэння
  • Якае заданне яго спрыгнула
  • Какі метод HTTP быў выкарыстоўваны
  • Які маршрут быў парадуцаны
  • Какі конкрэтны запит можна праследаваць
  • Сколькі часу падышла рэалізацыя задання

Конкрэтныя польні будуць разлічная залежна ад вашай прыкладнай програмы.

Важнае — гэта наявнасць контэксту.

Структураваныя логі зменілі мае падходжэнне да логаў

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

У працоўнай форме замест таго, каб запісваць падзею як звычны, вольнай формы тэкст, напрыму:

User login failed for some reason

Можна представіць яго як структурованыя даны:

{
  "level": "warn",
  "event": "login_failed",
  "requestId": "abc123",
  "ip": "example",
  "timestamp": "..."
}

Калі логі стануць структурованымі, ўзнікненне і фільтрацыя іх стане значна простэйшым.

Можна ставіць запиты на:

level = error

альбо:

event = login_failed

альбо:

route = /api/auth/login

Этае мае вялікі эфект, калі вашы логі агрэгуюцца на централізаванай платформе для логавання.

У замест на безканцова прасуванне праз неструктурованный текст, вы можете ставіць точныя, спрямованыя запиты.

Не логавайце все

Этае ўсё тая ж пастка, у якую легка пацягнуцца.

Пад час дэбагавання здаецца прыродным хацець больш даных, а не менш.

Так вы в канцыку логаваеце все, пра што толькі можетэ задумацца.

Тэла запиту.

Тэла адпаведзі.

Полны об’ект пользователя.

Рэзультаты базы дадаў.

Загаловкі запиту.

Токены аутэнтыкаціі.

Дакладныя вядомасі пра серавэр.

Внутрэніяя памылкі об’ектаў.

Чэрз некалькі часоў у вас з’яўляецца вельмі большы запісаны калектар дадзеных.

І гэта створае два аднальныя проблемы.

Першая — гэта ускладнюе пошук сапраўдна важлівых мэтадаў.

Другая, болей серьёзная, — гэта рызык випадковага захавання чутлівых дадзеных.

Гэты другі праблема заслуговыць на аднальны раздзіл.

Ніколі не вважайце лог-файлы безпечным месца для секрэтнаў

Гэта стала аднай з найважлівейшых урокаў безпекі, якія трэба запам’ятаваць.

Лог-файлы не ўтвараюць падходягаючага месца для захавання чутлівых пароляў толькі таму, што гэта зручна пад час дыбаггіну.

Категорыі дадзеных, якія зазвычай вымагаюць дадатковай абераглівасці:

  • Паролі выкарыстоўвачаў
  • Токены OAuth або bearer, якія выкарыстоўваюцца для доступу
  • Токены, якія выкарыстоўваюцца для аднавлення сесіі
  • Клучы, якія выкарыстоўваюцца для автанацыі ў API
  • Секрэты, зв’язаныя з калектваўнам адарожэннем
  • Даныя аброцення, якія выкарыстоўваюцца для з’язку з базай дадзенаў
  • Kookies, якія выкарыстоўваюцца для атрыбутавання сесіі
  • Будзь-якія персональныя або прыватныя даны корыстувача
  • Як прыклад, гэта сапраўды пасляднюя ідея:

    console.log(req.headers.authorization);
    

    Гэта можа заўсёды заадно зашчытіць калькі хвілі пад час вышуквання бага.

    Але гэтыя даны могу застацца ў вашых лаг-файлах дужа дзеўна пасля таго, як сесія адлучэння бага завершыцца.

    Сама інфраструктура логавання таксама патрэбуе захавы.

    Якшо хтось здобудзе неупраўнены доступ да вашай системы логавання, ён можа запрацаваць з данымі, якія вы ніколі не хацелі адкрыць.

    ID-ы запытак сталі чыразнацо корыстнымі

    Уявіце сабе кліента, які надае запыт на кшталт:

    POST /api/orders
    

    Гэты запыт праходзіць через калькі слоёў:

    Client
       ↓
    Load Balancer
       ↓
    Node.js API
       ↓
    Database
       ↓
    Payment service
    

    У якім-небудзь моменты ён не выйшаў.

    Тепер уявіце, што кожны рэкорд лога, які асоцыюецца з тым запитам, несе той самы ідэнтыфікатор:

    requestId = 7f91...
    

    Вы можете выкарыстоўваць гэты ідэнтыфікатор для пошуку і восстанавленаць цэлыя лінію падзей.

    Напрыклад:

    request started
          ↓
    authentication successful
          ↓
    database query started
          ↓
    database query completed
          ↓
    payment request started
          ↓
    payment service timeout
          ↓
    request failed
    

    Без спяльнага ідэнтыфікатора запита ціх адзінарых записаў лога можа быць важкая асоціяваць между сабой.

    Калі ёсць такі ідэнтыфікатор, яны ствараюць аднае цэласнае выказанне, а не розрозненыя, нез’ўязаныя падзеі.

    Логаванне і адлагоджэнне — гэта два разныя процесы

    З часам разлік между гэтымі двума стаў значна яснейшым.

    Калі працуеце локальна, можа з’явіцца патрэба дадаць што-небудзь адзіночнае, толькі каб пераканацца ў значэнні:

    console.log(result);
    

    Гэта корыстна ў той момент, для вас, проста тут.

    Але логаванне, якое викорыстоўваецца у працэсе вырабніцтва, патрэбуе іншага типу дизайна.

    Логі вырабніцтва должны быць:

    • Аднаковыя
  • Магчымна для пошуку
  • Структуравана
  • Корыстная
  • Безпечная
  • Зразумна па вolumе
  • Швыдкае выведанне для адклекчэння бягаў і рэальная стратэгія стварэння можлівасцей абзору — гэта не адна і тая ж рошчынь.

    Кожны рэжым лога служыць сваёй мете

    Звычны патэрн — гадаваць такія рэжымы, як:

    debug
    info
    warn
    error
    

    Точныя назвы разлічаюцца ў залежнасці ад інструментоў і каманд.

    Але асновная ідея застаецца незменнай.

    Адклекчэння бягаў

    Дзейнае деталізаванне, якое ў большасці случаў є актуальным, калі вы актываўна расследуеце чы ўсуняеце проблемы падчас разработкі.

    Інфармацыя

    Звычныя запісы, якія выходзяць пад час нормальнай роботы.

    Напрыклад:

    Server started
    Request completed
    Background job completed
    

    Апавешчэнне

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

    Напрыклад:

    External service response was slow
    

    Памылка

    О чымсь з’явілася проблема, і яе трэба негайна адзначыць.

    Напрыклад:

    Database connection failed
    

    Запам’ятовваць гэтыя катагорыі на самай справе не ўсё так важна.

    Важлаўнае — сталявасці ў ўжыцці іх.

    Коды стану HTTP таксама маюць значэнне для аналізу

    Спачатку коды стану здаваліся чымось, што служыць толькі кліенту.

    Аднак выявілася, што яны таксама є корыстным інструментам для розумення фактычнай працы вашага API.

    Напрыклад:

    200 → successful request
    201 → resource created
    400 → invalid request
    401 → authentication required/failed
    403 → forbidden
    404 → resource not found
    429 → rate limited
    500 → internal server error
    

    Уявіце, што вашы панелі керування раптам пакажуць рост:

    500 responses
    

    Гэта ўзнака апазору, якую варта расследаваць.

    Альбо уявіце сабе стрымкі адхіл:

    429 responses
    

    Такі рост можа вказваць на незвычныя патэрны трафіку, занадта агрэсыўных кліентаў чы на неправильна налаштаваны ліміт частоты запытаў.

    Коды стану стаюць значамімымі сигналамі, калі вы сталявасці ў ўжыцці іх у вашам API.

    Паведамленні пра адказы должны дапамагаць вашай командзе, а не зловмешчыкам

    Іншы баланс, які варта вывучыць, — это межа між деталям внутрэшняй памялкі і тым, што вы паказваеце кліенту.

    Спадзяймося, запіс у базе данных не выйшоў.

    У внутрэшнім режыме первосортная памялка пра аберанне можа выглядаць так:

    unique constraint violation on users_email_key
    

    Гэта справды дапамагае пад час адлучвання бягункоў.

    Але передача гэтай первасортнай памялкі пра аберанне безпосередна канецовам корыстніку зазвычай не є належным.

    У замен адпаведзь API можа выглядаць так:

    {
      "success": false,
      "message": "The email address is already registered."
    }
    

    Тым часам усі тэхнічныя деталі застаюцца ў логах сервера, дзе ім і месца.

    Такі падход даўа вашай командзе неабходную інфармацыю, не прасачываючы внутрэшняях деталяў реалізацыі тым, хто вызывае API.

    Стэк-трэйсы трэба адмаўляць астаточна

    Стэк-трэйс, калі ў чымось выходзіць наперад, можа быць надзвычайна корыстным для выявлення таго, дзе сталася аберанне.

    Але ён таксама можа адкрываць внутранія деталі ўсупрацоўкі вашай системы.

    Самэ гэтая прычына стварая значны разлік у спосабе адносу да гэтага:

    Разработка

    У гэтым случае повны, деталізаваны вывод пра адмошчанні часто ёсць практычна корыстным.

    Эксплуатацыя

    Кліенты зазвычай должны атрымваць контролюемую, універсальную адпаведзь на адмошчанні, тады калі всі діагностычныя деталі залишаюцца ў захіщаных логах.

    API, які працуе ў режыме эксплуатацыі, не павінен вяртаць усю свою внутраню інфармацыю пра стэк-трейс толькі таму, што запит неўдалы.

    Пасля гэтага з’яўляюцца метрыкі

    Логі адпавядаюць на такыя запитанні:

    Што ўжо сталася?

    Метрыкі адпавядаюць на іншы тип запитанняў:

    Як часта гэта трапляецца?

    Прыклады включаюць:

    Requests per second
    Error rate
    Response latency
    Database connection count
    CPU usage
    Memory usage
    

    Уявіце API, яке зазвычай адаптаваеся так:

    150 ms
    

    а пасля сярэжны час адпаведзьбы вырастае да:

    1200 ms
    

    Нават якщо кожны запит все ўсё вяртаецца з кодам 200, явна адбылася змена.

    Этая змена мае значэнне.

    API не павінна быць зламанай.

    Але ёна таксама не працуе як зазвычай.

    Метрыкі дапамагаюць зафіксаваць такія змены.

    Толькі сярэжныя значэння можуць вводзіць у глухое

    Гэта выявілася ўсё жа адной з важлівых наўук.

    Сказаўмо, ваш API обрабоцвае 10 000 запытоў.

    Большая частка з іх завершаецца за:

    100–200 ms
    

    Але калькі з іх трэбуе:

    5–10 seconds
    

    Сярэжны показнік для ўсіх іх можа лёгка сховаць гэтыя атыпавыя прыклады.

    Самэльга таму час адпаведзьбы часта вимерваюць за дапамогою перцэнтайлів.

    Напрыклад:

    p50
    p95
    p99
    

    У загальных рысах:

    p50 — так выглядае тыповы запит.

    p95 — так выглядае медленнейшая частка запитоў.

    p99 — так выглядае найгorsы варіант роботы сеткі.

    Вам не завжды патрэбна будзе стежыць за кожным з іх.

    Але апошнёвацца выключна на сярэдзіне можа замаскаваць рэальныя проблэмы.

    Логі описваюць запускі; метрыкі адкрываюць тэндэнцыі

    Гэта разлік па працэўнасці апынуўся справдзільна корыстным у практыцы.

    Уявіце сабе:

    Metric:
    API latency increased
    

    Гэта значыць, чыгосці змяніліся.

    Потым вы пераглядзаете логі і знаходзите:

    Database query took 4.8 seconds
    

    Тепер у вас є правдападобная прычына.

    Гэтыя два джералі даных дапамагаюць адна другой.

    Вы можете уявіць сабе гэты зв’язак так:

    Metrics
       ↓
    Something looks wrong
       ↓
    Logs
       ↓
    What happened?
       ↓
    Tracing
       ↓
    Where did it happen?
    

    Гэта естэційна прыводзіць да наступнага аспекту стабільнасці.

    Выпанаванне запиту з самага пачатку да канцоў з атрыбутамі трэйсінгу

    Атрыбут трэйсінгу дазволяе спрацаваць з адным запитам як з історыяй, стежачы за ўсімі его пераходамі праз разныя часткі вашай системы.

    Напрыклад:

    HTTP Request
         │
         ├── Authentication
         │
         ├── Controller
         │
         ├── Service
         │
         ├── Database query
         │
         └── External API
    

    Кожны крок у процесе можа мячыць своі даны пра час выканання.

    Можа выявіцца, што сам слой API патрэбуе толькі:

    200 ms
    

    тады калі вызов якога-небудзь зовнішняго сервісу займае:

    4 seconds
    

    Без трэйсінгу зазвычай можна пабачыць толькі нечыткае жалоба на кшталт:

    API is slow
    

    Колі ўвёстаўся трэйсінг, можна задаць набліжэнейшы пытанне:

    Калькі частка гэтага запиту насправды спрычыняе замедленне?

    Это набліжэнейшы пытанне для адлучэння прычыны.

    Логі, метрыкі і трэйсы адпаведаюць на разныя пытанні

    Дапамагае так апісваць гэтыя тры типы даных:

    SignalCore: questionLogs – Чыя жа здарылася? Metrics – Колькі часта, або колькі? Traces – Дзе на самай працэ пайшло час пад час запытку?

    Існуе якісь перакрыцця межы ўсіх трох, але ніхто з іх не можа цалком заменіць іншаго.

    Добра створаная система зазвычай выкарыстоўвае ўсі трох разам.

    Пакупка інструментаў – гэта не тое ж сама, што досягненне можлівасці спостэрэння

    Гэта можа быть найважлівейшы вывод з усьго гэтага процесу.

    Лёгка прыйміць за даналог:

    "Калі я установлю якісь інструмент для спостэрэння, мой прыклад стане доступным для спостэрэння."

    Але рэчы працуюць не так.

    Інструменты добра справляюцца з сборам дадзэнняў.

    Але хтось усё рава должен адпавядаць на такія запытанні:

    • Што на самай працэ трэба мерыць?
    • Што варта фіксавацыя?
    • Калі здарэнняяе маюць значэнне?
    • Шта лягае ў основу паказання адказкі?
  • Які умовы параджуець паведамленне пра абяранне?
  • Які поля ўважаюцца чулымі?
  • Як давго трэба зберагчы гэтыя данні?
  • Як спаўязваць адносныя запыты?
  • Установка інструментаў рэдка калі ёсць складным элементам.

    Складнасць крыўціцца ў тым, каб выявіць, яя інфармацыя справаўна мае значэнне.

    Ролі OpenTelemetry

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

    Яго цэннасць заключаецца ў тым, што ён стандартызуе спосаб працы развівачаў з даннымі тэлеметрыі, абгружаючы такія аспекты, як:

    • Трагі
    • Метрыкі
    • Логі

    У працоўнай практыцы OpenTelemetry адкрывае можлівасць стварання та збору данных тэлеметрыі без прыкреплення да аднаго конкрэтнага прадавця абзірнае разгляду системы.

    Маленькі проекты на Node.js, верагчыма, не патрабуюць адразу ж цэлага комплекту засобаў для абзірнасці.

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

    Для телеметрыяй таксама неабходна адпаведная абераганне прыватнасці, як і для логаў

    Є ў гэтым аспекте безпекі, які варта падкрэсліць.

    Правіло, яке дапэўнюе логаванне, таксама паслужыць і для телеметрыяй:

    Сбор большых колькасцей дадзеных сам па сабе не ўлучшэнне.

    Павінны быть рашучыя ў выборе таго, што будзе збірванацца:

    • Логі
    • Трэйсы
    • Метрыкі
    • Інструменты для адлічэння памылак
    • Панелі монітарынгу

    Збір усьго тэла HTTP-запыту ў трэйсе можа здавацца карыстным пад час дэбаггінгу.

    Але падумайце, што будзе, як гэты пакет дадзеных будзе мітыць:

    password
    token
    personal information
    payment information
    

    Разам ваша система аналізу стана ператворылася ў ўсё новая адзінка для зберагчэння чутлівых дадзеных.

    Проблемы з безпекай не заканчываюцца на логах — яны распрастраняюцца на весь процес аналізу стана.

    Рывень деталізавання логаў павінен разліцвацца ў розных средах

    Пад час розработкі локальна вы, як правило, хочаце якомога больш мярку інфармацыі негайна.

    Гэта часта значыць неабходнасць увімкнення болей деталізаваных логаў.

    У прымэтнай среде прыорітэты зменяюцца на:

    • Падтрымкі высокага спявазання сигналу і шуму
    • Додатковых накладных витрачэнняў на выконанне
    • Рызыка для безпекі
    • Ступеня можлівасці пошуку дадзеных
    • Палітік зберагчэння дадзеных
    • Функцыяў паведамленняя пра проблемы

    Настройка логавання, якая добра працуе пад час розработкі, не павінна быць адповідной у прымэтнай среде.

    Гэта ў частцы прычыны, чаму важна настраіваць логаванне па кожнай средзе.

    Працэўнасць базы дадзенаў трэба адзінакава фіксаваць

    У большасці системы з адзюльтайн-бэкендам база дадзенаў зазвычай ёсць аднам з першых месцаў, якія трэба пераглядзець, калі API сповольняецца.

    Уявіце, што гэты эндпаўт раптам пачынае вяртаць адпаведзь за колькісць секундаў:

    GET /api/projects
    

    Слою прыемкі можа здавацца, што ўсё цалка працюе нормальна.

    Аднак асновны запыт можа мець такія проблемы:

    • Відсутнае неабходнае індэкс
    • Зяўленне занадта великай колькасці рэядкоў
    • Выкарыстоўванне непатрэбных з’еднанняў
    • Выконанне больш разоў, чым планавалася
    • Блакаванне у чаканні іншай операцыі
    • Выкарыстоўванне паслабленага плану выконання

    Гэта безпасульна адносіцца да паказаных раней пунктав пра правильную разработку схем PostgreSQL.

    Якісная разработка базы дадзенаў і якісная можлівасць адстэйкавання ўзаўмна падтрымліваюць адна другую.

    Ні адна з іх сама по сабе недастатняя.

    Візуабельнасць дапамагае выявіць проблемы типу N+1

    Возьмімо такій сцэнарый:

    Get 100 projects
           ↓
    Get owner for project 1
    Get owner for project 2
    Get owner for project 3
    ...
    Get owner for project 100
    

    З функцыйональнага точка зору API можа працаваць нормальна.

    Але загальная колькасць запытанняў, якія падаюць у базу данных, може значна перасіць тое, чаго можна было б спакавацца.

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

    Спроможнасць стазіроўкі сама па сабе не рашыць проблему шаблона N+1.

    Але яна дазволяе заўважыць, што такі шаблон вообща існуе.

    Апавешчэнняя павінны спрыяць рэальным дзеянням

    Системы апавешчэнняя — ўсё тая ж сфера, якую варта перэпрацаваць.

    Калі кожна дробная рэч выклікае апавешчэнне, люди па-прыродны чынам начынаюць іх ігнараваць.

    Корыстнае апавешчэнне павінна дазволіць вам адпавесць на пытанне:

    Чакаецца мая увага зараз?

    Што-та на кшталт:

    Error rate has increased significantly
    

    Мабыць, варта адзначыць гэта.

    Але:

    One request took 1.2 seconds
    

    Паўна ўпэўненасць, што не варта з-за гэтага перываць каго-небудзь.

    Точныя прагі будуць разніцявацца залежна ад системы.

    Основная ідея застаецца незменнай:

    Апавешчэнне должна падступіць да дзеяння, а не проста стварыць шум.

    Павтаральны процес значна зменшае напругу пад час адлагоджэння

    Калі ўсё ламаецца, адборчая перапрацоўка рэдка калі дапамагае быстрасці. Кращэ працаваць па аднаковай секвенцы.

    1. Пераканацца, што проблема рэальная

    Спачатку паверыце, што ўсё ж такі сталася проблема.

    Errors increased?
    Latency increased?
    Specific endpoint affected?
    

    2. З'ясаваць, насколькі шырока ёй распрастраненасць

    Выявіце, чы рэшаецца проблема толькі:

    one user?
    one endpoint?
    all users?
    one API instance?
    database?
    external service?
    

    3. Паглядзіце, што няўжо зменілася

    Пераканацеся, чы была:

    deployment?
    configuration change?
    database migration?
    dependency update?
    

    4. Дакледжванне логаў

    Шукаць:

    errors
    timeouts
    failed dependencies
    database failures
    unexpected status codes
    

    5. Анаіз паказнікаў

    Паглядзець на:

    latency
    error rate
    traffic
    CPU
    memory
    database metrics
    

    6. Атрымоўваць трэйс запыту, калі можна

    Точна выявіце, дзе было паспало час або дзе выйшла злома.

    7. Раскінуць асалодную прычыну

    Супротставіце жаданню проста пакрыць симптам.

    Такі структураваны падход здаецца набагато надзейнейшы, чым пачатак сэрвера і надзея, што проблема сама знікне.

    Пачатак сэрвера можа замаскаваць асалодную проблему

    Цікавае ўсно выказаць гэта, таму што спакуса рэальная.

    Уявіце прыклад аплікацыі, якая спаваліла. Вы пачынаеце ёю занова, і раптам усё знову вяртаецца нормальным. Здаецца, што проблема рашылася.

    Але асалодная прычына могла быць такой:

    memory leak
    

    Або выкараная:

    database connections
    

    Або такая, якая сасвойвае многа рэсурсоў:

    background job
    

    Паўторны запуск пазбавіў толькі візуальных сімптамаў — ён не павярбаваў таго, што на самай працэ падазроўна было не так.

    Рэальная можлівасць абзору дапамагае з’ясавіць, чым на самай працэ спраба паўторнага запуску была эфектыва.

    Частыя падступкі ў логаванні і абзоре

    Ёсць памылкі, яых варта актываўна утрымацца.

    1. Заноска даколькі-небудзь стрэлок у логі

    Гэта проста стварае шум, а не ўжо якісь корыстныя данні.

    2. Запіс чутлівых дадзенняў у логі

    Паролі, токены, секрэты і персональныя данні трэба адносіцца да іх аўтарытатна, а не проста так.

    3. Ігнораванне корэляцыі запытак

    Без ідэнтаў запытак стае значна сложней відстэпліваць адзін запыт па розным кроках.

    4. Адзірванне толькі за часам працы

    API можа тэхнічна быць „у роботе“, але ўсё рав чакліва медлены або часта нефункцыйнальны.

    5. Апоўнай залежнасць ад сярэжнага часу адпаведзення

    Аналіз на аднойчынных пярасэтах можа выявіць проблемы, якія ховае простая сярэжнасць.

    6. Ігнораванне выконвальных характарыстыкаў базы дадзеных

    Можа быць ситуацыя, калі швайнае прыемнікавае слой работае над медленной базай дадзеных.

    7. Налагоджэнне занадта большай колькасці апавешчэнняў

    Постаўленыя постоянна апавешчэнняя ведуць да справжняга вымучэння і таго, што люди перестаюць на яе зважаць.

    8. Дадаванне механізмаў абэрвазабіліті пасля

    Чаканне да часу пасля інцыдэту, каб дадаць монітарынг, толькі ускладняе адлагоджэнне ў будучыні.

    9. Працэсаванне дакладных дазнаўчых дадзеных кліентам

    Дакладная дыагностычная інфармацыя патрабуеяцца ў системах, якімі вы керуеце на станцыі сервера, а не ў адпаведзеннях, надаўаемых кліентам.

    10. Дадаванне інструментаў без чыстай мэты

    Панель керування, заполненая показнікамі, не прымусова робіць іх корыстнымі.

    Спіс пераканальных пунктаў для ацэнкі абэрвазабіліті

    Перш чым сказаць, што API ў разумныя моменты є спостерагаемым, падумайце пра тое, каб задаць ся гэтымі пытаннямі.

    Логаванне

    • Чы рэўізуюцца важлівыя запусковыя здарэння?
    • Чы логаванне ў структураваны формат?
    • Чы настаўлены роўні логавання адносова?
    • Чы існуе достатня інфармацыя, каб выявіць нештатны стан?
    • Чы є ідэнтыфікаторы запросаў?
    • Чы чувствяглівыя даны адсорбаваны чы выключаны цэлкам?

    Пакрыткі

    • Чы фіксуюцца нечаканыя пакрыткі?
    • Чы кліенты бачаць толькі безпечныя, універсальныя паведамлення пра пакрыткі?
    • Чы ўнутршняя частка системы все ўсё мае дакладную діагностику?
    • Чы пакрыткі можна прыязначыць да конкрэтных запросаў?

    Метрыкі

    • Чы вам вядома колькасць вашых запросаў?
    • Чы вам вядомы пакрыткі?
    • Чы вам вядома час адпаведзення?
    • Чы можна выявіць абнормальныя трафікавыя патэрны?
  • Чы можаце вы старанна следзіць за важлівымі залежнасцямі?
  • База дадзеных

    • Чы можаце вы выявіць медленныя запиты?
    • Чы можаце вы бачыць проблемы, related да з’яўленняў з’язку?
    • Чы можаце вы расследаваць тэрміналы, якія інтэнсывна запрашваюць базу дадзеных?
    • Чы праблемы базы дадзеных ўсё-такі видны вам?

    Аналіз

    • Чы можаце вы следзіць за важлівымі запросамі ў парадку ўсередзіне системы?
    • Чы можаце вы выявіць медленныя операцыі?
    • Чы можаце вы бачыць вызовы зовнішніх служб?
    • Чы можаце вы сувязваць дзейнасці між разнымі службамі?

    Апавешчэння

    • Чы важлівыя праблемы дэйсна спрычыняюць апавешчэння?
    • Чы праграмы ўсё-такі маюць значэнне?
    • Чы апавешчэння ўсё-такі можна выконваць?
    • Чы шум апавешчэння контролюецца?

    Галоўны урок з усьго гэтага

    Самая значныя зміна ў падходзе была у усвядомленні гэтага: прыкладнасць, якая працуе правільна, не значыць автаматычна, што ёю можна кераваць з абяцаннем.

    Калі вы розвіваеце прыкладнасць локальна, вы можаце проста ачыняць тэрмінал і стачыць, што відбываецца у рэальны час. У прыметнай средовыце все не так.

    Вы мусіце справляцца з калькамаючыміся корыстнікамі, калькамаючысяя серверамі, калькамаючысяяя службамі, фонавымі заданнямі, базамі дадзеных, зовнішнімі API і абяканнямі, якія ніколі не праказуюцца на вашай сопрацоўнай машыне.

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

    Самэ гэтая прычына, чаму логаванне і можлівасць абсалютнага разгляду системы так важныя. Яны — не проста дадатковыя засобы для манітарынгу; яны ўскладневаюць спроможнасць системы самой сабе адказваць.

    Куды гэта ведае далей

    Чым больш часу вы практыкуеце з системамі бэкенду, тым ясней стае, што гатовнасць да эксплуатацыі на практыцы ёсць ланцюгам супакоўзлых адказаў. Аутентыкацыя заходзіць таго, хто можа зайсці. Автарызацыя керуе тым, што ён можа робіць. Обмежэнне частоты запытоў дапамагае контролаваць трафік. Дызайн базы дадзеных заходзіць цэласць вашых дадзеных. Логаванне і можлівасць абсалютнага разгляду системы дапамагаюць зрозумець, што самэ ў тым моментзе робіць система.

    Наступным логічным крокам ёсць глыбэйшае дакладжанне да аспекта развяртывання той самай ланцоўкі — контейнеры, налаштавання сяродовы, пайплайны CI/CD, перагляд стану, павольнае завершэння роботы, стратэгіі развяртывання і ўсё тое, што на самай працэ развяртывання прыкладнення на Node.js з локальнага комп’ютера ў прымэтную среду зменяецца. Гэты аспект найлепей выучыць праз практычную рэалізацыю, а не толькі праз тэорыю.

    Заключная думка

    Лёгка ўявіць, што дэбагаванне — гэта пераважна пошук той самай проблематычнай лініі коду. У практыцы ж часта йдзе пра наявнасць достатніх даных, каб зрозумець систему, якая або якія цяпер адносуюцца да той лініі.

    Напісанне хорашага коду заўсёды мае значэнне. Але калі ў канцэ наступаюць проблемы — а яны неўхібна наступаюць — можласць бачыць, што на самай працэ адбылася, таксама мае вельмі важлівое значэнне.

    Створыце систему. Захавайце яе. Абяроце ўсё, што з нею відбываецца. Потым сфокусавайцеся на тым, каб яе было лёгкая аператаваць.