Для чего нужны логи

Kibana-мать или Зачем вам вообще нужны логи?

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

Такой use case обещает наполнить вашу жизнь совершенно новыми красками и заставит испытать полную гамму чувств.

Для чего нужны логи. Смотреть фото Для чего нужны логи. Смотреть картинку Для чего нужны логи. Картинка про Для чего нужны логи. Фото Для чего нужны логи

Пролог:

«Пойми, на Хабрахабре только и разговоров, что о Kibana и Elasticsearch. О том, как это чертовски здорово — наблюдать, как огромный текстовый лог превращается в красивые графики, а еле видимая нагрузка на CPU горит где-то в глубине top-а. А ты. Что ты им скажешь?»

Матчасть

В жизни каждого нормального пацана возникает момент, когда он решил-таки поставить на своем проекте связку ELK.

Схема среднестатистического пайплайна выглядит примерно так:
Для чего нужны логи. Смотреть фото Для чего нужны логи. Смотреть картинку Для чего нужны логи. Картинка про Для чего нужны логи. Фото Для чего нужны логи

Мы шлём в Kibana 2 вида логов:

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

В зависимости от формата, прогоняем его через соответствующий кодек.

В случае с nginx, это будут вот такие “необычные” регулярки-полуфабрикаты, предлагаемые фильтрующим модулем “grok” (слева), и названия полей, в которые попадут заматченые данные (справа). Для пущей красоты у нас есть еще фильтр geoip, который определяет локацию клиента. В Кибане можно будет сделать “географию” клиентов. Базу качаем отсюда dev.maxmind.com/geoip/legacy/geolite.

А в случае с json, как видите, ничего делать вообще не надо, что не может не радовать.

Имя индекса и document_type для ES берем из полей, которые в самом начале пути приклеили к сообщениям в filebeat-е.

Связывание событий в логах фронта и бэка

Завязка:

“У нас было 2 типа логов, 5 сервисов в стэке, полтерабайта данных в ES, а также несчетное множество полей в логах приложений. Не то чтобы это был необходимый набор для риалтайм-анализа состояния сервиса, но когда начинаешь задумываться еще и о связывании событий nginx-а и приложения, становится сложно остановиться.

Единственное, что вызывало у меня опасения — Lua. Нет ничего более беспомощного, безответственного и порочного, чем Lua в конфигах Nginx. Я знал, что рано или поздно мы перейдем и на эту дрянь”.

Для чего нужны логи. Смотреть фото Для чего нужны логи. Смотреть картинку Для чего нужны логи. Картинка про Для чего нужны логи. Фото Для чего нужны логи

Для генерации request-id на Nginx-е будем использовать Lua-библиотеку, которая генерирует uuid-ы. Она, в целом, справляется со своей задачей, но пришлось немного доработать ее напильником — ибо в первозданном виде она (та-дам!) дуплит uuid-ы.

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

Довольно быстро обнаружилось, что наши “вселенски-уникальные” айдишники не такие уж уникальные. Дело в том, что randomseed библиотека берет из таймстампа на момент запуска nginx-воркера. А воркеров у нас столько, сколько ядер у процессора, и запускаются они одновременно… Не беда! Подмешаем туда pid воркера и будет нам счастье:

P.S. В репозитарии Debian-а есть готовый пакет nginx-extras. Там сразу есть Lua и еще куча полезных модулей. Рекомендую, вместо того чтобы вкомпиливать модуль Lua руками (еще бывает openresty, но я не пробовал).

Группировка ошибок по частоте возникновения.

Kibana позволяет группировать (строить рейтинги) событий на основе одинаковых значений полей.

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

Так выглядит топ 20 ошибок:
Для чего нужны логи. Смотреть фото Для чего нужны логи. Смотреть картинку Для чего нужны логи. Картинка про Для чего нужны логи. Фото Для чего нужны логи

И отдельно взятый тип ошибки на графике и списком эпизодов:
Для чего нужны логи. Смотреть фото Для чего нужны логи. Смотреть картинку Для чего нужны логи. Картинка про Для чего нужны логи. Фото Для чего нужны логи

Теперь мы знаем, какой баг в системе можно пофиксить когда-нибудь потом, т.к. он слишком редкий. Согласитесь, такой подход куда научнее, чем “за эту неделю было много подобных тикетов в саппорт”.

А теперь — срыв покровов: оно работает, но плохо

Кульминация:

«Я понимаю. Ты нашёл в NoSQL рай: у тебя быстро шла разработка, ведь ты хранил все в MongoDB, и тебе не нужны были такие друзья, как я. А теперь, ты приходишь и говоришь: мне нужен поиск. Но ты не просишь с уважением, ты даже не называешь меня Лучшим Поисковым Движком. Нет, ты приходишь ко мне в дом в день рождения Lucene и просишь меня индексировать неструктурированные логи бесплатно»

Для чего нужны логи. Смотреть фото Для чего нужны логи. Смотреть картинку Для чего нужны логи. Картинка про Для чего нужны логи. Фото Для чего нужны логи

Неожиданности
Все ли сообщения из лога попадают в Кибану?

Нет. Не все попадают.

Маппинг запоминает название поля и его тип (число, строка, массив, объект и т.д.). Если мы посылаем в ES сообщение, в котором есть поле, уже существующее в маппинге, но тип не совпадает с тем, что было в этом поле раньше (например, в маппинге — массив, а пришел объект), то такое сообщение не попадет в ES, а в его логе будет не слишком очевидное сообщение:

Имена полей в json-логах

Elasticsearch v2.x не принимает сообщения, в которых есть поля, имена которых содержат точки. В v1.x этого ограничения не было, и мы не можем перейти на новую версию, не переделав все логи, т.к. у нас такие поля уже “исторически сложились”.
Источник

Кроме того, в Kibana не поддерживаются поля имена которых начинаются с подчеркивания ‘_’.
Для чего нужны логи. Смотреть фото Для чего нужны логи. Смотреть картинку Для чего нужны логи. Картинка про Для чего нужны логи. Фото Для чего нужны логи

Автоматическое уползание данных в соседние инстансы ES

По-умолчанию в ES включена опция Zen Discovery. Благодаря ей, если вы запустите несколько инстансов ES в одной сети (например, несколько докер-контейнеров на одном хосте), то они друг друга найдут и поделят данные между собой. Очень удобный способ смешать продуктивные и тестовые данные и долго с этим разбираться.

Оно падает и потом долго поднимается. Это еще больнее, когда docker

Реже, но тоже бывает, что падает Elasticsearch. Делает он это “по-английски” (т.е. молча).

Чтобы понять, кто из них двоих упал, делаем http-запрос в ES — если ответил, значит лежит не он. Кроме того, когда у вас относительно много данных (скажем, 500G), то ваш Elasticsearch после запуска будет еще около получаса просасывать эти данные, и в это время они будут недоступны. Данные самой Kibana хранятся там же, поэтому она тоже не работает, пока ее индекс не подхватится. По закону подлости, до нее обычно очередь доходит в самом конце.

Приходится мониторить мониторингом длину очереди в rabbitmq, чтобы оперативно реагировать на инциденты. Раз в неделю они стабильно случаются.

А когда у вас всё в docker-е, и контейнеры слинкованы между собой, то вам нужно перезапустить еще и все контейнеры которые были слинкованы с контейнером ES, кроме него самого.

Большие дампы памяти при OOM

30GB. Сбрасываются они, разумеется, в директорию, где лежат бинарники (а не туда, где данные). Происходит это быстро, мониторинг даже не успевает прислать смс-ку. Отключить это поведение можно в bin/elasticsearch.in.sh.

Производительность

В Elasticsearch существует т.н. “маппинг” индексов. По-сути, это схема таблицы, в которой хранятся данные в формате “поле — тип”. Создается она автоматически на основе поступающих данных. Это значит, что ES запомнит имя и тип данных поля, исходя из того, данные какого типа пришли в этом поле в первый раз.

Например, у нас есть 2 очень разных лога: access-log nginx и production-log nodejs-приложения. В одном стандартный набор полей, он короткий, типы данных никогда не меняются. В другом же, напротив, полей много, они nested, они свои у каждой строчки лога, названия могут пересекаться, данные внутри полей могут быть разных типов, длина строки доходит до 3 и более Mб. В итоге автомаппинг ES делает так:

В общем, оно сильно тормозит как при индексации данных, так и при поиске через Kibana. При этом, чем больше накопилось данных, тем хуже.

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

Поэтому мы придумали более радикальное решение. Весь тяжелый nested-json в production-логе отныне будет логироваться в виде строки в специально-отведенном одном поле сообщения. Т.е. вот прямо JSON.stringify(). За счет этого набор полей в сообщениях становится фиксированным и коротким, мы приходим к “легкому” маппингу как у nginx-лога.

Конечно, это своего рода “ампутация с дальнейшим протезированием”, но вариант рабочий. Будет интересно увидеть в комментариях, как еще можно было сделать.

Промежуточный итог

Стэк ELK — классный инструмент. Для нас он стал просто незаменимым. Менеджеры следят за всплесками ошибок на фронтэнде после очередного релиза и приходят жаловаться к разработчикам уже “не с пустыми руками”. Те, в свою очередь, находят корреляции с ошибками в приложении, сразу видят их стэки и прочие важнейшие данные, необходимые для дебага. Есть возможность моментально строить различные отчеты из серии “хиты по доменам сайтов” и т.п. Словом, непонятно как мы жили раньше. Но с другой стороны…

“Robust, Reliable, Predictable” — все это не про ELK. Cистема очень капризная и богатая на неприятные сюрпризы. Очень уж часто приходится копаться во всем этом шатком, извините, Jav-не. Лично я не могу припомнить технологию, которая бы так плохо следовала принципу “настроил и забыл”.

Поэтому за последние 2 месяца мы полностью переделали логи приложения. Как в плане формата (избавляемся от точек в именах, чтобы перейти на ES v.2), так и в плане подхода к тому, что вообще логировать а что нет. Сам по себе этот процесс, имхо, абсолютно нормальный и логичный для такого проекта, как наш — недавно uKit отпраздновал свой первый день рождения.

«В начале пути вы сваливаете в логи как можно больше инфы, т.к. заранее неизвестно, что понадобится, а потом, начав „взрослеть“, постепенно убираете лишнее». (c. pavel_kudinov)

Источник

Лог: что это, зачем нужен и где его найти?

Зачем нужны лог файлы?

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

1. Логи могут понадобится, если нужно узнать статистику по сайту. Например, логи сайтов отображают следующую информацию:

а) статистику посещаемости

б) точки входа и выхода с сайта

в) поисковые запросы, по которым приходят посетители, и наиболее популярные страницы сайта

г) поисковики, страны и браузеры посетителей

д) уровень конверсии и страницы сайта, которые никто не посещает

е) сайты, которые ссылаются на этот ресурс.

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

3. Для восстановления доступов испольузются логи авторизации, которые собирают данные о попытках входа.

4. В случае ошибок в работе определенного ПО, устройства или ОС, когда необходимо определить источник проблемы.

Логи (server logs) помогают контролировать работу серверной машины и в случае возникновения ошибок быстро их находить и устранять. Логи используются практически везде, где ведется запись и прослеживание истории программного процесса. В первую очередь это необходимо в целях безопасности. Для того, чтобы найти и проанализировать логи, используют специально предназначенное для этого ПО. Некоторые логи могут обладать очень большим размером, поэтому время от времени их нужно очищать. Лог файл показывает события и его непосредственный источник. Причиной события может быть:

Какие есть виды логов?

На практике видов логов может быть несколько. Рассмотрим каждый из них.

Как найти логи?

Место, где находятся логи зависит от используемого ПО, заданных настроек и пути, который заведомо установил администратор сервера.

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

Названия файлов: журнал ошибок – error.log; журнал доступов – log; основной журнал – syslog; журнал загрузки системы – dmesg.

В ОС Windows свой способ структуризации логов, в котором выделяют уровни событий: подробности; сведения; предупреждение; ошибка; критический. Пользователь может сортировать и фильтровать записи, в зависимости от того, что именно ему нужно.

Что делать с логами?

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

Даже беглый анализ логов может помочь выяснить причины чрезмерной нагрузки на сайт, поэтому если вам нужна помощь, чтобы разобраться с логами и исправить возникшие ошибки работы сервера, обращайтесь в техническую поддержку ГиперХост.

Включение и выключение записей логов на сервере происходит в панели управления. В большинстве случаев эта функция доступна в разделе панели Журнал или Логи. Более детально об этом вы можете уточнить непосредственно у вашего хостера.

Источник

Необходимо ли логирование программ?

Мне часто приходилось сталкиваться с полным отсутствием понимания назначения логирования в приложениях, хотя система логирования это далеко не второстепенная фаза в разработке проекта. Но, зачастую, люди это понимают уже на стадии сдачи поекта, когда введение полноценной системы логирования — процесс достаточно затратный и как результат, оставляют все как есть. Что в результате имеем? А имеем мы систему, в которой любая проблема у заказчика превращается в головную боль разработчика, т.к невозможно восстановить причины возникновения проблемы у заказчика, т.е у разработчика есть только описание проблемы от человека, у которого эта проблема воспроизвелась. К сожалению, мы живем не в идеальном мире и как правило описания проблемы носит малоинформативный характер, т.к пользователи системы не являются грамотными тестерами и не могут описать проблему подробно(есть конечно приятные исключения, но их мало). Особенно остро проблема логирования стоит когда нет возможности воспроизведения проблемы на своей стороне.

Реализация:

#include string >
#include
#include
#include
#include
#include

namespace smart_log
<
typedef void (*ErrorHandler)( const std:: string &);
typedef const std:: string (*Obfuscater)( const std:: string &);
//This type provides constant which set the writing log mode.
//If a current mode is bigger then methods mode the writing will be ignored.
//It needs for log flood control
enum LogLevel;

struct LogParameters
<
std:: string m_strLogFileName;
//Pointer to a function which does appropriate manipulations in case of a log corruption. Set to 0 if it doesn’t need.
ErrorHandler m_pErrorHandler;
//Pointer to a function which obfuscates each string writing to a log file. Set to 0 if it doesn’t need.
Obfuscater m_pObfuscater;
size_t m_uiLogMaxSize;
unsigned short m_siMaxSavedLogs;
//Is the thread synchronization needed?
bool m_bIsMultiThreaded;
//Indicates whether log will be saved or not. If this flag is set then log will be saved when its size exceed m_uiLogMaxSize.
//Use m_siMaxSavedLogs to control how many log files will be saved. If the current number of log files has reached the m_siMaxSavedLogs then
//new saved log would replace the oldest one.
bool m_bIsSaveLog;
LogLevel m_xLogLevel;
//Path to the log location. It will be created if no exists.
boost::filesystem::path m_xLogSavedPath;
>;

class Logger
<
//—————————————Data
size_t m_uiCurrentLogSize;
short int m_siCurrentSavedLogs;
LogParameters m_xParameters;
std::ofstream m_xOfstream;
boost::interprocess::named_mutex m_xMutex;
//File name with full path in which it will be create
boost::filesystem::path m_xFullFileName;
//—————————————Internal methods
private :
//Common method for message writing
void WriteLog(LogLevel xLevel, const std:: string & strMessage);
void HandleLogSizeExcess();
std:: string Timestamp();
void CreatePath(boost::filesystem::path xPath);
//—————————————Interface
public :
Logger( const LogParameters& xParameters);

//Set of methods which concretize the common WriteLog method to log levels.
void WriteNormalLog( const std::ostringstream& strMessage)
<
WriteLog( eNormal, strMessage.str() );
>
void WriteExtendedLog( const std::ostringstream& strMessage)
<
WriteLog( eExtended, strMessage.str() );
>
void WriteDebugLog( const std::ostringstream& strMessage)
<
WriteLog( eDebug, strMessage.str() );
>
//————————————Setters
void SetErrorHandler(ErrorHandler pErrorHandler)
<
m_xParameters.m_pErrorHandler = pErrorHandler;
>
void SetLogMode(LogLevel xLevel)
<
m_xParameters.m_xLogLevel = xLevel;
>
>;
>
#endif _LOGGER_

namespace fs = boost::filesystem;
namespace multiprocess = boost::interprocess;
using namespace smart_log;

void Logger::WriteLog(LogLevel xLevel, const std:: string & strMessage)
try
<
multiprocess::scoped_lock xLock;
if (m_xParameters.m_bIsMultiThreaded)
<
xLock = multiprocess::scoped_lock (m_xMutex, multiprocess::defer_lock_type());
xLock. lock ();
>
CreatePath(m_xParameters.m_xLogSavedPath);

>
catch (fs::basic_filesystem_error )
<
if (m_xParameters.m_pErrorHandler)
m_xParameters.m_pErrorHandler( «Problem with a directory creation» );
else
throw ;
>

std:: string Logger::Timestamp()
<
SYSTEMTIME xTime;
::GetSystemTime(&xTime);
std::ostringstream xStream;
xStream «.»
«.»
«-»
«.»
«.»
«.»
return xStream.str();
>

Пример создания удобного интерфейса к классу:

class LogInstance
<
static boost::scoped_ptr m_spLogger;
public :
static const boost::scoped_ptr & GetLog()
<
if (!m_spLogger)
<
smart_log::LogParameters xParams;
xParams.m_bIsMultiThreaded = true ;
xParams.m_pErrorHandler = 0;
xParams.m_pObfuscater = 0;
xParams.m_siMaxSavedLogs = 0;
xParams.m_strLogFileName = «log_file» ;
xParams.m_uiLogMaxSize = 8192;
xParams.m_xLogLevel = smart_log::eNormal;
xParams.m_xLogSavedPath = «./log/log/log» ;
m_spLogger.reset( new smart_log::Logger(xParams));
>
return m_spLogger;
>

#define NORMAL_LOG(MSG)\
<\
std::ostringstream xStrm;\
xStrm «: » » » «(): » WriteNormalLog(xStrm);\
>
#define EXTENDED_LOG(MSG)\
<\
std::ostringstream xStrm;\
xStrm «: » » » «(): » WriteExtendedLog(xStrm);\
>
#define DEBUG_LOG(MSG)\
<\
std::ostringstream xStrm;\
xStrm «: » » » «(): » WriteDebugLog(xStrm);\
>

Надеюсь этим постом я сподвигну людей не использующих логи, на их использование и надеюсь моя реализацию будет им полезна. Удачной всем отладки 🙂

Источник

Логирование как способ отлаживать код

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

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

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

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

Проблематика: Сложно отлаживать составной код

Возможный алгоритм решения проблемы:

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

Давайте посмотрим пример. Вы знаете, что по отдельности все реализации интерфейсов работают (т.к. написаны тесты, доказывающие это). Но при взаимодействии всего вместе возникает некорректное поведение. Что вам нужно? Нужно логировать ответы от «корректных» интерфейсов:

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

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

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

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

Источник

Логирование как инструмент повышения стабильности веб-приложения

Для чего нужны логи. Смотреть фото Для чего нужны логи. Смотреть картинку Для чего нужны логи. Картинка про Для чего нужны логи. Фото Для чего нужны логи

техлид в Dunice

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

Существует много различных инструментов для повышения стабильности проекта:

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

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

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

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

Для чего нужны логи. Смотреть фото Для чего нужны логи. Смотреть картинку Для чего нужны логи. Картинка про Для чего нужны логи. Фото Для чего нужны логи

В данном примере не важны язык/фреймворк бэкенда, фронтенда или тип базы данных, а вот про веб-сервер Nginx давайте поговорим. В данный момент Nginx популярнее остальных решений для высоконагруженных сайтов. Среди известных проектов, использующих Nginx: Рамблер, Яндекс, ВКонтакте, Facebook, Netflix, Instagram, Mail.ru и многие другие. Nginx записывает логи по умолчанию, без каких-либо дополнительных настроек.

Логи доступны 2 типов:

Клиент отправляет запрос на сервер, и в данной ситуации Nginx будет записывать все входящие запросы. Если возникнут ошибки при обработке запросов, сервером будет записана ошибка.

2020/04/10 13:20:49 [error] 4891#4891: *25197 connect() failed (111: Connection refused) while connecting to upstream, client: 5.139.64.242, server: app.dunice-testing.com, request: «GET /api/v1/users/levels HTTP/2.0», upstream: «http://127.0.0.1:5000/api/v1/users/levels», host: «app.dunice-testing.com»

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

Первым делом каждый запрос должен получать свой уникальный идентификатор, что поможет отличить его от других запросов. Для этого используем UUID/v4. На случай возникновения ошибки, каждый обработчик запроса на сервере должен иметь обёртку, которая отловит эти самые ошибки. В этой ситуации может помочь конструкция try/catch, реализация которой есть в большинстве языков.

В конце каждого запроса должен сохраняться лог об успешной обработке запроса или, если произошла ошибка, сервер должен обработать её и записать следующие данные: ID запроса, все заголовки, тело запроса, параметры запроса, отметку времени и информацию об ошибке (имя, сообщение, трассировка стека).

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

Для чего нужны логи. Смотреть фото Для чего нужны логи. Смотреть картинку Для чего нужны логи. Картинка про Для чего нужны логи. Фото Для чего нужны логи

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

Трассировка — процесс пошагового выполнения программы. В режиме трассировки программист видит последовательность выполнения команд и значения переменных на каждом шаге выполнения программы.

В нашем случае требуется передавать метаинформацию о запросе при взаимодействии серверов и записывать логи в единое хранилище (такими могут быть ClickHouse, Apache Cassandra или MongoDB). Такой подход позволит привязать различные контексты серверов к уникальному идентификатору запроса, а отметки времени — понять последовательность и последнюю выполненную операцию. После этого команда разработки сможет приступить к устранению.

Для чего нужны логи. Смотреть фото Для чего нужны логи. Смотреть картинку Для чего нужны логи. Картинка про Для чего нужны логи. Фото Для чего нужны логи

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

С сервером разобрались, что же делать, если у нас сбои даёт клиент и запросы просто не приходят? В такой ситуации нам помогут логи на стороне клиента. Все обработчики должны отправлять информацию на сервер с пометкой, что ошибка с клиента, а также общие сведения: версия и тип браузера, тип устройства и версия операционной системы. Данная информация позволит понять, какой участок кода дал сбой и в каком окружении пользователь взаимодействовал с информацией.

Для чего нужны логи. Смотреть фото Для чего нужны логи. Смотреть картинку Для чего нужны логи. Картинка про Для чего нужны логи. Фото Для чего нужны логи

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

Способы, которые мы рассмотрели в статье, помогут следить за качеством продукта и минимизируют затраты на исправление недочётов в системе.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *