Трейсить что это значит
Введение в паттерн распределенной трассировки
Когда дело доходит до работоспособности и мониторинга, распределенная архитектура может подкинуть вам пару проблем. Вы можете иметь дело с десятками, если не сотнями микросервисов, каждый из которых мог быть создан разными командами разработчиков.
При работе с крупномасштабной системой очень важно следить за ключевыми показателями этой системы, работоспособностью приложений и достаточным объемом данных, чтобы иметь возможность быстро отслеживать и устранять проблемы. Пребывание в ОБЛАЧНОЙ среде, такой как AWS, Google Cloud, Azure, еще больше усугубляет проблему и затрудняет обнаружение, устранение и локализацию проблем из-за динамического характера инфраструктуры (вертикальное масштабирование, временные машины, динамические IP-адреса и т. д.).
Базис наблюдаемости:
В этой статье я сосредоточусь на двух аспектах наблюдаемости: логах (только сгенерированных приложением) и трейсах.
Использование централизованной системы логирования в распределенной архитектуре, чтобы иметь возможность собирать логи и визуализировать их, стало обычной практикой. Логи, сгенерированные различными микросервисами, будут автоматически отправляться в централизованную базу для хранения и анализа. Вот некоторые из популярных решений централизованных систем логирования для приложений:
Логи предоставляют полезную информацию о событиях, которые произошли в вашем приложении. Это могут быть логи INFO-уровня или логи ошибок с подробными стек трейсами исключений.
Кореляция логов между микросервисами
В большинстве случаев это может быть userId, связанный с запросом, или какой-нибудь уникальный UUID, сгенерированный в первой точке входа в приложение. Эти идентификаторы будут прикреплены к каждому сообщению в логе и будут передаваться последовательно от одного микросервиса к другому в заголовке запроса (в случае, если идентификатор не является частью последовательно обрабатываемого запроса). Так можно легко использовать requestId или userId для запроса к системе логирования, чтобы найти все логи, связанные с запросом в нескольких сервисах.
Рисунок 1. Централизованное логирование.
Ниже приведены несколько примеров того, как пометить (tag) ваши логи необходимой информацией на Java с помощью фильтров запросов (RequestFilter).
Рисунок 2: Конфигурация и образец лога Log4J2
Рисунок 3: Фильтры запросов по UUID или UserId
Трассировка
Путь запроса через распределенную систему.
Задержка запроса при каждой пересылке/вызове (например, от одного сервиса к другому).
Ниже приведен пример трассировки для запроса, взаимодействующего с двумя микросервисами (сервисом-аукционом рекламы и сервисом-интегратором рекламы).
Рисунок 4. Трассировка
В приведенном выше примере данные были захвачены и визуализированы с помощью инструмента DataDog. Есть несколько других способов захвата трейсов, о которых я расскажу в следующем разделе.
Составляющие трейса
Трейс представляет из себя древовидную структуру с родительским трейсом и дочерними спанами. Трейс запроса охватывает несколько сервисов и далее разбивается на более мелкие фрагменты по операциям/функциям, называемые спанами. Например, спан может охватывать вызов от одного микросервиса к другому. В рамках одного микросервиса может быть несколько спанов (в зависимости от того, сколько уровней классов/функций или зависимых микросервисов вызывается для обслуживания запроса).
Трассировка зиждется на создании уникального идентификатора для каждого запроса в точке входа и распространения его на последующие системы в качестве контекста трассировки в заголовках запросов. Это позволяет связать различную трассировочную информацию, исходящую от нескольких служб, в одном месте для анализа и визуализации.
Корреляция логов и трейсов
В итоге мы можем фильтровать логи по userId или другому уникальному идентификатору (например, сгенерированному UUID) и можем отслеживать по трейсам производительность/поведение отдельного запроса. Было бы неплохо, если бы мы могли связать это воедино и иметь возможность сопоставлять логи и трейсы для конкретного запроса!!
Наличие такой корреляции между логами и запросами позволяет:
Сопоставлять метрики производительности напрямую с логами.
Направлять в систему специальный запрос для устранения неполадок.
Выполнять искусственные транзакции с системой в разные моменты времени и иметь возможность сравнивать текущие трейсы с историческими, а также автоматически собирать системные логи связанные с этими запросами.
Реализация распределенной трассировки с помощью корреляции логов и трейсов
ПОДХОД #1: Инструментация с помощью сторонних решений, таких как DATADOG
Datadog по существу берет на себя заботу о централизованном логировании и сборе трассировочной информации. Datadog генерирует уникальные идентификаторы трейсов и автоматически распространяет их на все инструментированные нижестоящие микросервисы. Единственное, что от нас требуется, это связать DD traceId с логами, и мы сможем получим корреляцию логов и трейсов.
Рисунок 6: Инструментация приложения с DataDog
Рисунок 7: Корреляция логов и трейсов в DataDog
ПОДХОД #2: ZIPKINS, CLOUD-SLEUTH СО SPRING BOOT
Полная интеграция в SPRING boot
Простота в использовании
Трейсы можно визуализировать с помощью пользовательского интерфейса Zipkins.
Поддерживает стандарты OpenTracing через внешние библиотеки.
Поддерживает корреляцию логов через контексты Log4j2 MDC.
Нет решения для автоматического сбора логов, связанных с трейсами. Нам придется самостоятельно отправлять логи в ElasticSearch и выполнять поиск, используя идентификаторы трейсов, сгенерированные cloud-sleuth (как заголовок X-B3-TraceId).
Рисунок 8: Zipkins, Cloud Sleuth и Spring Boot.
ПОДХОД #3: AMAZON XRAY
Нативно поддерживает все ресурсы AWS, что очень хорошо, если ваши распределенные сервисы развернуты и работают в AWS
Балансировщики нагрузки AWS автоматически генерируют идентификаторы (REQUEST ID) для каждого входящего запроса, что освобождает приложение от этой заботы. (Ссылка)
Позволяет выполнять трассировку на всем пути от шлюза API до балансировщика нагрузки, сервиса и других зависимых ресурсов AWS.
Реализует корреляцию логов с помощью логов в CLOUDWATCH logs
Cloudwatch log может стать очень дорогими при большом объеме логов
Поддерживает opentracing по умолчанию
Имеет библиотеки, которые работают со Spring
Поддерживает Jager Agent, который можно установить в качестве средства распространения трейсов и логов.
С точки зрения обслуживания и настройки инфраструктуры достаточно сложен.
ЗАКЛЮЧЕНИЕ
Логи и трейсы сами по себе безусловно полезны. Но когда они связаны вместе с помощью корреляции, они становятся мощным инструментом для ускорения устранения проблем в производственной среде и в то же время дают девопсу представление о работоспособности, производительности и поведении распределенных систем. Как вы увидели выше, существует несколько способов реализации этого решения. Выбор за вами 🙂
Перевод статьи подготовлен в преддверии старта курса «Архитектура и шаблоны проектирования». Узнать подробнее о курсе.
Трейсить что это значит
Войти
Авторизуясь в LiveJournal с помощью стороннего сервиса вы принимаете условия Пользовательского соглашения LiveJournal
Трассировка тушевой графики
В сегодняшней статье я расскажу о своем способе трассировки (перевода растрового изображения в векторный формат), а также объясню, почему я предпочитаю не применять векторизацию к своим работам.
Как же превратить растровое изображение в векторную форму?
Строго говоря, нам ни к чему знать в деталях, за что отвечает каждая из настроек, поскольку по-настоящиму важными являются лишь несколько из них. Я расскажу о них, и дальше можно будет браться за дело, если Вы планируете попробовать оттрассировать какое-то свое изображение вместе со мной.
И наконец, я очень рекомендую включать чекбокс Ignore White при трассировке черно-белых тушевых иллюстраций. Таким образом Иллюстратор понимает, что не нужно тратить ресурсы на белое пространство, и получается только черная тушь в векторном формате.
Как только я выбираю Sketched Art preset, программа начинает колдовать над миоим изображением. На данном этапе я еще ничего не настраивала, только Preset и Ignore White.
Наконец, последний шаг, который нужно сделать, чтоб изображение стало действительно векторным, это нажать кнопку Expand на верхней панели инструментов.
Только что мы рассмотрели быстрый путь трассировки изображения со сравнительно большим количеством деталей (ведь у нас тут целых три наброска на одном листе бумаги). Если у Вас похожая ситуация с количеством объектов, Вы можете использовать подобный алгоритм действий, или же, если позволяет время и хочется достичь лучшего результата, применить другую стратегию, и трассировать каждый рисунок по отдельности. В моем случае это значит, что я выделяю поодиночке каждый набросок, и повторяю уже знакомые Вам шаги.
Плюсы и минусы трассировки тушевой графики, или всегда ли можно положиться на возможности программы
А теперь я хотела бы вернуться к вопросу, почему я не трассирую масштабные детализированные работы. Вот мой принт (читатели наверняка его помнят), который я сейчас попробую превратить в образец векторной графики. Это большой рисунок, формат бумаги А3, со множеством крошечных деталей, выполненных линерами 0.03 и 0.05 мм. Я помещаю эту картинку в Иллюстратор.
Выбираю Sketched Art preset.
. и получается нечто совершенно разочаровывающее, лишенное деталей и какой-либо внятности. Плохая новость в том, что как бы я ни пыталась выправить это изображение, оно не станет похожим на оригинал. Можно достичь лишь небольших, практически незаметных, изменений к лучшему.
Вот почему я не перевожу свои принты и сложные иллюстрации в вектор. Я также не рисую в векторных программах с нуля, не обрисовываю эскизы. Таким образом, думаю, становится понятно, почему я говорю «нет» каждому, кто интересуется «принтом как этот, только векторным» 🙂
Как правило, в свои наборы графики на Creative Market я вкладываю растровые варианты, сделанные именно с оригинальных рисунков, а не растровые версии векторного изображения. Все дело в том, насколько оцифрованная версия сохраняет связь со своим источником, важно, чтобы она была «живой». Я хочу, чтобы даже от небольших превью моих рисунков создавалось ощущение, будто эти работы помнят мое прикосновение.
Порой растровые форматы вызывают беспокойство, мол, файлы будут не масштабируемы. Но ведь растровое изображение тоже можно увеличивать, главное, чтобы оно было изначально нарисовано на достаточном размере бумаги и отсканировано в высоком разрешении.
Вот, собственно, и всё, что я хотела рассказать сегодня. Спасибо за внимание!
Положение вещей
Фото, рисунки, микростоки
Как я делаю трейс простых рисунков / Репост из моего LJ
Для начала — какой софт у меня есть:
1) Adobe Photoshop CS2. Возможно многие в курсе, что Адоб как-то выложили весь пакет CS2 с серийниками. Предполагалось, что им будут пользоваться старые клиенты, но ссылки широко распространились и пакет скачали все, кто хотел. Если не ошибаюсь, скачать можно до сих пор. Адоб сначала сказали «Ээээ!» (тут гифка с Траволтой), а потом махнули рукой.
2) Бесплатный плагин Fine Threshold.
3) Бесплатный векторный редактор Inkscape.
4) Инструмент для автотрейса VectorMagic.
Рисунки я фотографирую мобилкой и потом скачиваю с ГуглФото.
Возьмем для примера картинку с котиком, нацарапанную на листочке. Нарисовано неаккуратно, грязновато, но тем и лучше. Если вы нарисуете чистыми линями рисунок на белой бумаге — все будет намного проще.
Обработаем рисунок в Фотошопе. Сначала я его обесцвечиваю.
Выделяю нужную часть и обрезаю лишнее
Автоматически выравниваю уровни.
После этого снова вызываю окно Levels и белой пипеткой тыкаю в самое темное место на белой бумаге (чтобы сделать бумагу полностью белой), а черной пипеткой — она первая из трех — тыкаю какую-нибудь из линий котика, которая выглядит слишком светло. Так я линии делаю темнее.
После я округлой жесткой кистью с белым цветом замазываю пятна и стираю ненужные линии.
Но поскольку рисунок грязноват и неровен, я добавляю толщины и цвета линиям через Filter-Other-Minimum. Если ваш рисунок ровный и аккуратный, это скорее не понадобится.
Еще один способ избавиться от мусора — слегка разблюрить рисунок.(Filter — Blur — Gaussian Blur) Это может уничтожить важные мелкие элементы, так что смотрите по обстоятельствам.
После этого я применяю замечательный фильтр Fine Threshold.
Чтобы пояснить его работу: вот это ДО применения фильтра…
… а это уже после.
Дальше переходим уже к конкретно трейсу.
Вариант №1 — автотрейс с помощью программы VectorMagic.
Просто перетягиваем картинку в окно программы, выбираем расширенный режим.
Количество цветов — указываем два.
Количество сегментов («Настройка сегментации») берем среднее.
На этапе редактирования сегментов можно тыкнув пипеткой в нужный цвет и после выбрав карандаш, закрасить ненужные дырки и выровнять неровности.
Для обычного рисунка подходят среднее значение силы сглаживания и количества узлов. Но у меня рисунок неаккуратный поэтому я уменьшаю количество узлов и увеличиваю силу сглаживания.
Инструментом «Ножницы» я могу удалить ненужный бэкграунд, что и делаю.
В общем готово, я сохраняю. Эта программа объекты одного цвета собирает в группу, поэтому темные линии и белое наполнение будут сгруппированы по отдельности.
Вариант №2.
Автотрейс с помощью программы Inkscape.
Сначала нужно импортировать растровый рисунок, что вы подготовили в Фотошопе через Файл-Импорт.
Лучше рабочую область подогнать под размер картинки, для этого открываем «Файл — Свойства документа..»
Там разворачиваем область «Подогнать размер страницы под содержимое» и жмем аналогичную кнопку.
Далее собственно векторизация.
Я, честно сказать, не разбираюсь в трассировщике Inkscape, поэтому просто выбираю «Множественное сканирование / Цвет» и указываю 2, что должно подразумевать 2 цвета.
После этого нужно нажать кнопку ОК и если ваш рисунок простой, то кнопка ненадолго станет ненажимаемой, а после — снова активной. Это значит что векторизация произошла, просто закройте окно.
Но поскольку растровый рисунок более не нужен, его стоит удалить.
Открываем редактор XML (если конечно он уже не открыт в правой панели, что часто бывает)
Ищем там элемент с именем image[число] и удаляем либо кнопкой в интерфейсе, либо клавишей Del.
Также стоит обратить внимание, что в Inkscape есть отличный инструмент, заливающий замкнутые области. В линейке инструментов он третий снизу.
Методом тыка я установила, что в верхней панели для этого инструмента нужно выбрать «Закрыть интервалы — Нет» и «Увеличить/уменьшить на 1 px». Можно и чуть больше, тогда заливка как бы немного перекрывает контур.
Еще для неаккуратных контуров есть команда «Контур — Упростить», это добавляет сглаживания. Но мне не понравился результат, местами линии сильно исказились.
Далее сохраняйте результат в EPS или SVG.
НО! Независимо от выбранного способа результат векторизации нужно пересохранить в EPS 8 или EPS 10 в Иллюстраторе.
Ручной трейс. Тут все просто — импортируем растровую картинку в векторный редактор и отрисовываем поверх линиями.
Большой плюс тут в том, что к кривым можно применить разные кисти, создать хоть акварельный эффект.
И в общем-то ручной трейс бывает порой не только более качественным, но и даже более быстрым.
Если я что-то забыла — спрашивайте.
Трасси… что? Доклад Яндекса
Отладка приложения занимает бо́льшую часть нашего времени. Кто-то пользуется DevTools, кто-то обходится обычным console.log, кто-то использует профайлеры. Зачастую этих инструментов более чем достаточно. Но есть еще один, не такой известный и популярный в JavaScript-мире. О нем я и рассказал в докладе.
— Всем привет! Надеюсь, вы бодры, веселы, перекусили, заварили себе кофейку, потому что сейчас будет очень интересная и при этом доступная тема: «Трасси… что?». Правильнее было бы называть доклад «Трасси… что-о-о?!», но не будем так.
Давайте познакомимся. Меня зовут Алексей Охрименко, я разработчик Яндекс.Музыки. У Музыки 12 стран присутствия, 15 млн активных слушателей и больше 65 млн активных треков. Там я работаю разработчиком и стараюсь делать этот проект лучше.
Помимо того, что я пишу в Яндексе на React, я еще и Google Developer Expert по Angular. Кому еще нравится фильм «Сплит»?
Также, кому интересно, заходите в созданное мной телеграм-комьюнити tensorflow_js. Если вы когда-то интересовались машинным обучение и знаете JavaScript или Python, обязательно заходите в эти группы, будем рады вам помочь. Подписывайтесь на мои социальные сети, там я под никнеймом obe’njiro или obenjíro, как удобно. И у меня есть телеграм-канал obenjiro_notes, в котором я периодически выкладываю самое интересное и классное, что только бывает.
Я обожаю странные инструменты, которые экономят огромное количество времени. Сейчас хочу с вами поговорить о трассировщиках.
Что такое трассировка?
Смотрите, у нас у всех есть некий словарный запас: трассировка, отладка, профилирование, логирование. Мы все эти термины слышали. Но как их поделить, как сделать четкую иерархию?
Самое главное: у нас есть одна главная цель — отладить наше приложение. С помощью отладки мы пытаемся улучшить качество, скорость, еще что-то.
А вот трассировка, профилирование, логирование — это всего лишь некие подходы/методологии, позволяющие достичь нашей цели.
Кстати, есть огромное количество разных интересных способов достичь целей отладки. К примеру, Wolf fence algorithm, Delta Debugging, Saff Squeeze, Causality tracking, PostMortem debug.
Сейчас вы подумаете: «Вот это классные темы! Поговорим о них».
Но что мы скажем богу прокрастинации? Не сегодня! В этот раз мы поговорим только про трассировку и существующие инструменты.
И еще раз. Что такое трассировка?
Трассировка — это получение информации о каждом шаге выполнения. Самое важное отличие от других подходов — в том, что мы получаем информацию о каждом шаге. Но что означает «шаг»?
Для трассировки нет необходимости получать информацию о каждой строчке кода.
Нам достаточно, к примеру, получать информацию о том, какие функции были вызваны, с какими аргументами, и что они вернули. Этой информации часто более чем достаточно, чтобы понять, как наш код отработал и как его исправить/оптимизировать.
Базовые способы трассировки
Трассировка может быть сделана множеством разных способов. Вы можете банально вставить console.log везде.
Если вам не хочется делать это вручную, настраивать, есть огромное количество хороших библиотек: Winston, Log4js, Scribe и многие другие — я тут не перечислял все.
Есть наш замечательный Chrome DevTools со своим пошаговым отладчиком. Мы можем трассировать нашу программу с помощью него.
Есть огромное количество профессиональных инструментов: Dtrace, Ptrace и многие другие. Но у них есть ряд ограничений. Я поговорю о них чуть попозже.
И, конечно, есть некие специализированные инструменты, которые и являются предметом доклада.
Именно о них я и хочу вам рассказать. Но прежде чем мы приступим, посмотрим на существующие подходы к трассировке.
console.log (Winston, Log4js, Scribe)
Сначала про логи. Самое простое, банальное, но при этом проверенное временем решение.
Простейший вариант — я вставляю console.log вначале, и в конце нашей функции вывожу информацию об аргументах и результате выполнения функции.
Естественно, я не хочу выводить trace-логи каждый раз. Они нужны мне только во время отладки.
Поэтому я добавляю некое условие — проверку на то, что у нас есть, к примеру, environment-переменная Trace. Или, если мы в браузере, я могу взять за основу какой-нибудь query-параметр либо проверить наличие определенной куки.
Также я могу это делать более автоматизированно — воспользоваться библиотекой, у которой уже настроены специальные транспорты, есть огромное количество настроек.
Теперь я могу просто указать, какой тип уровня логирования мне нужен и в зависимости от этого типа выводить или не выводить эту трассировочную информацию. Я могу ее включить и выключить, когда мне нужно.
Я видел некоторые библиотеки и проекты, которые делают прямо хорошую работу и покрывают логами каждую функцию, но это огромное количество работы, которой хочется избежать.
Chrome DevTools, Step Debugger
Давайте посмотрим что-нибудь более автоматизированное. К примеру, Chrome DevTools и его Step Debugger.
Как только мы откроем DevTools, у нас будет панелька, которая позволяет выполнять пошаговую отладку нашего приложения, и мы будем, скажем так, близки к термину трассировка. То есть будем выполнять программу шаг за шагом, каждый раз нажимать на следующий шаг и получать информацию о каждом шаге.
Круто? Увы, не очень.
Dtrace, Ptrace, etc.
Безусловно, есть профессиональные инструменты, которые были очень давно сделаны. Dtrace — один из самых популярных.
Для эффективного использования, чтобы вы получали именно хорошую отладочную информацию, необходимо подключить провайдер и создать так называемые пробы. И эти пробы будут использоваться как некий объект, через который вы будете сообщать Dtrace о происходящих событиях.
И все замечательно, но, к сожалению, это не все. Вам не только JavaScript придется писать, но и Dtrace скрипт. То есть есть такая штука. Она не сильно сложная, но, в любом случае, вам придется с ней ознакомиться.
Написав ее, вы можете получить эту интересную отладочную информацию и получать ее на нативном, скажем так, уровне — то, что делают ребята из C++, из других языков программирования.
Всё это, конечно, замечательно. Но в основном все эти инструменты для Node.js, они слишком низкоуровневые, ну правда. Те, кто знают C/C++, будут чувствовать себя как рыба в воде. А остальным будет тяжеловато. И требуется некая поддержка кодовой базы. То есть вам придется дополнять ваш код в зависимости от изменений. Это дополнительная работа, которой все-таки хочется избежать.
Специализированные инструменты
И теперь самое интересное. Есть специально созданные инструменты для трассировки, именно под JavaScript, под веб и Node.js.
Давайте взглянем на некоторые из них. Лично я знаю два засветившихся в мире фронтенда: TraceGL от Рика Арендса и SpyJS от Артема Говорова.
TraceGL
Это инструмент, который изначально был бесплатен, но вы могли заплатить за него дополнительно, как бы поддержать автора. В какой-то момент, к сожалению, этот инструмент просто перестал существовать. К сожалению, поддержка комьюнити оказалась не такая большая, как ожидал автор, плюс наложились проблемы самого инструмента. Но есть ряд разработчиков, которые форкнули когда-то выложенный TraceGL, запатчили основные существенные баги, и мы можем склонировать этот репозиторий и воспользоваться trace-сервером из этого репозитория.
После чего мы можем указать нашу программу и передать ее в TraceGL клиент как аргумент. Она запустится, то есть TraceGL аугментирует вашу кодовую базу и добавит отладочную информацию.
Давайте взглянем на этот инструмент. Всё очень быстро и качественно работает. И огромное количество отладочной информации, которую вы видите на экране, — все это отрисовано с помощью WebGL. Вы всё рисуете с помощью WebGL и шейдеров: шрифты, кнопки, тексты, скроллы. Автор проделал огромную работу. Но в связи с этим появились и дополнительные проблемы — не на всех машинах доступны и хорошо работают шейдеры. Кто пытался сделать качественные кроссбраузерные и кроссплатформенные веб-игры — поймет, о чем речь.
Если мы посмотрим на программу, то увидим три замечательные особенности: мини-карту, то есть некую общую карту того, что вообще произошло; набор stack traces, нажав на которые, мы можем перейти к нашей кодовой базе и увидеть, к примеру, как выполнялись те или иные if, else, switch statements, операторы условного перехода. То есть мы можем проанализировать, как выполнялась наша программа в реальном времени. Не знаю, как для вас, а для меня это безумно круто. Когда я впервые это увидел, был просто в безумном восторге.
Но, как и говорил, инструмент устарел, он не поддерживает TypeScript, не поддерживает современный JavaScript, поэтому нам он не подойдет.
SpyJS
Есть инструмент для трассировки, который действительно полезен и при этом ближе к вам, чем вы можете думать.
SpyJS — это инструмент, который интегрирован в WebStorm. Все, что нужно, чтобы прямо сейчас начать трассировку вашего приложения с помощью SpyJS: вместо профиля отладки создать профиль для SpyJS. Вы также запускаете через WebStorm ваше приложение — как Node.js, так и фронтенд…
SpyJS через проксирование дополняет вашу кодовую базу, добавляет все необходимое для трассировки вашего приложения.
Если посмотреть, что происходит, то у вас появляется дополнительная отладочная информация либо в момент прогона, либо после него, и вы можете по stack traces, по событиям исследовать и открывать так называемый trace view. Это view, в котором есть вся отладочная информация, необходимая, чтобы понять, какие операторы условного перехода отработали, какие функции когда и при каких условиях были вызваны.
SpyJS встроен в среду разработки, и вы можете отлаживать ваше приложение вообще без браузера. Ну, класс!
У этого инструмента есть ряд нюансов. Все-таки он накладывает довольно большой overhead по производительности, имейте это в виду. Вообще SpyJS изначально конкурировал с TraceGL, и TraceGL выигрывал как раз за счет производительности, наличия мини-карты и более понятного и простого интерфейса. Но SpyJS сейчас монополист в плане специализированных инструментов по отладке.
Фатальный недостаток
Но все вышеперечисленные инструменты обладают фатальным недостатком. Они написаны не мной. 🙂 Поэтому была начата разработка инструмента под названием TraceMePlz.
Зачем?
Это важный вопрос, всегда задавайте его себе, прежде чем что-то писать.
Если кто-то его еще не видел — попробуйте, реально классный инструмент. К примеру, у нас есть простой файл main.ts без типов:
Мы запускаем TypeWiz:
И в нашем коде магически появляются типы:
Он в рантайме, добавляя в вашу кодовую базу некий код и собирая с помощью него информацию о типах объектов во время выполнения, превратить ваш TypeScript, у которого, допустим, нет типов, в TypeScript, у которого указаны все типы. Он использует информацию из рантайма, берет эти типы и вставляет их обратно в файл. Вы можете за считанные минуты получить полный type coverage вашего приложения.
Это все, конечно, круто. Но чем TypeWiz меня так вдохновил?
У него есть режим под названием CLI. Он вам позволяет просто добавить в готовый исходный код вот эти консоль-логи, эту необходимую отладочную информацию.
И как?
Давайте посмотрим, как это происходит.
Чтобы все это сделать, достаточно использовать Babel. У него есть парсер, который позволяет получить поддержку почти всей современной кодовой базы. Есть traverse, позволяющий ходить по AST, которые мы распарсили, и получать из этого информацию. Есть генератор и типы, которые позволяют нам создавать дополнительную кодовую базу и с помощью генератора обратно сгенерировать это синтаксическое дерево в файл.
Самое простое, что можем сделать: создать этот парсер и подключить вообще все существующие плагины, за исключением Flow. Flow и TypeScript несовместимы, поэтому приходится выбирать, что вам нужно поддерживать в текущий момент.
Дальше мы проходимся по нашему дереву и для ArrowFunctionExpression, FunctionExpression, FunctionDeclaration, Method вставляем дополнительный код, то есть вызов функции, который позволит передать трассировочную информацию.
Теперь мы берем типы и делаем call expression, вызов функции. В нем мы передаем наши параметры, аргументы, текущее название файла, что мы вызываем и в каком месте мы это делаем.
Всё это превращается в некую строчку в нашей кодовой базе, которая автоматически расставляется во всех местах, необходимых для сбора информации о трассировке.
Помните, как я показывал консоль-логи, когда мы расставляли вручную? Мы всё это можем автоматизировать. Затем генерируем и вставляем это в кодовую базу.
Но есть одна проблема. babel/generator ломает форматирование кода. Тут пришлось прибегнуть к магии MagicString (подробнее о нем можете прочитать у меня в статье). MagicString решило не только проблему с форматированием кода, упростило добавление новых языков в будущем и увеличило производительность инструмента.
И всё. Неважно, что вы используете: Webpack, Babel, TypeScript, Flow или вообще PHP. Подход будет одним и тем же, абсолютно. Поменяется лишь некий набор библиотек. И этот подход универсален, он подходит для всего. Неважно, как вы деплоите, есть ли у вас свой сборщик, язык и парсер или вы делаете что-то свое, уникальное. У вас все будет работать.
Смотрите, как это выглядит со стороны. Вы запускаете инструмент для трассировки и указываете, к примеру, что в папке public лежит все, что связано с фронтендом. Я туда передаю, соответственно, некий паттерн, по которому найдутся все фронтенд-файлы, и указываю channel (это именно параметр «с»), что это информация о фронтенде для сервера.
Для сервера делаю аналогично: указываю некий паттерн, который позволит нам понять, что эти файлы связаны именно с серверной разработкой, и указываю канал, отмечаю, что это бэкенд. Теперь здесь есть некая информация, которая поможет мне потом разделить кодовую базу: что выполняется на фронтенде, а что на бэкенде.
Затем надо запустить сервер, который будет получать эту информацию в реальном времени и отображать ее.
Рассмотрим на максимально простом примере. У нас есть некая кнопка. При нажатии на нее мы делаем fetch, это уходит на бэкенд, бэкенд идет за какими-то моковыми данными и возвращает результат на фронтенд.
Давайте глянем, как это выглядит в TraceMePlz. Не обращайте внимания на код. Я хочу лишь показать две особенности. Смотрите, слева находится фронтенд, клики и всё, что происходит, а справа бэкенд. Как видите, это одна из особенностей, о которых я рассказывал: side by side.
То есть я вижу в реальном времени, что сначала выполнился такой кусок фронтедной кодовой базы, а потом справа выполнился совершенно другой кусочек кодовой базы, но уже на бэкенде, и все это с помощью определенного алгоритма матчится и отображается в реальном времени. Вы в реальном времени видите, что это нажатие на кнопку вызвало некие действия на бэкенде, а они потом вызвали ответные действия на фронтенде. Причем этих каналов может быть сколько захотите. Естественно, в разумных пределах, так, чтобы ваш браузер с этим справлялся.
Один из дополнительных плюсов, которые есть уже из коробки, — мини-карта. То, чего не хватает в SpyJS, и то, что было в TraceGL.
Еще один бонус — «быстрый поиск».
Все это возможно благодаря тому, что мы просто используем Monaco Editor. Он из коробки поддерживает множество вариантов, умеет делать fallback для старых систем. Мало того, из коробки получилось сделать syntax highlight для более полумиллиона строчек трассировочного кода. Этого более чем достаточно даже для очень большой сессии трассировки.
Единственный шаг, который необходимо будет потом сделать: почистить нашу кодовую базу как для фронтенда, так и для бэкенда.
Просто убрать всю эту отладочную информацию, когда она нам больше не нужна.
Теперь немножко про трасировочную информацию. Как она сейчас выглядит?
У нас есть названия наших функций, если у функции нет имени — оно формируется по некоему алгоритму в зависимости от того, где, когда и при каких условиях вызывается метод. В любом случае мы получаем информацию о том, когда мы зашли в функцию, когда из нее вышли, какой метод инициировал вызов другого метода и что это за методы. То есть мы получаем эту цепочку вызовов stack trace.
Также мы получаем информацию, где находится этот файл, его позицию, строку и колонку. Мы можем перейти в редактор по данному пути и продолжить исследование нашей кодовой базы там.
Мы получаем информацию об аргументах, которые были переданы. Изначально мы это делаем, копируя только верхнюю часть свойств объекта. Остальное превращается в запись вида [Object object]. Делаем мы это, потому что объекты иногда могут достигать множества мегабайтов в размере, поэтому по умолчанию ограничивается максимальный размер дампа. Но вы это сможете регулировать.
TraceMePlz — крут, но.
Возможно, неожиданное применение
Прежде чем мы закончим, я хочу рассказать про одно очень странное и неожиданное, возможно, применение. Все инструменты трассировки — замечательные, классные, но всегда возникает спор: «А он мне точно нужен?»
Однако есть один кейс, в котором инструменты трассировки мне помогали. А именно — увеличение bus factor (фактора автобуса). Для тех, кто не знает, bus factor — это когда один автобус сбивает одного программиста. Сколько таких автобусов нужно, чтобы остановилась разработка нашего проекта, то есть сколько людей должен сбить автобус, чтобы мы перестали понимать, что происходит в нашем проекте?
Так вот, в проектах с большой кодовой базой, которые еще и живут очень долго, bus factor часто стремится к нулю. Чтобы этого избежать, у нас есть один маленький трюк — трассировщик. Вы не представляете, сколько раз он меня спасал. Он помогал мне вливаться в кодовую базу очень быстро без какой-либо помощи. Я просто запускал трассировщик, выполнял некие действия и тут же в реальном времени понимал, что происходит с системой, как она работает. И это очень-очень круто.
Мало того, в TraceMePlz есть встроенная возможность сделать Diff и визуально понять, в чем отличие работающего кода от неработающего.
Вы можете даже не разбираться в кодовой базе, а просто найти место первого отличия. Часто проблема будет именно в нем.
Прислушивайтесь к себе и своему коду, обязательно пользуйтесь инструментами для трассировки.
Подписывайтесь на мой телеграм-канал. Там обязательно будет отдельный анонс о релизе TraceMePlz.