https://habr.com/ru/company/skillfactory/blog/526978/- Блог компании SkillFactory
- Разработка веб-сайтов
- CSS
- JavaScript
Специально к старту нового потока курса
«Frontend-разработчик» делимся с вами полезным переводом. Автор рассказывает, как использует методы логирования в производственной среде собственного проекта и в чём именно они помогают. Кроме того, нас знакомят с платформой AppSignal, созданной, чтобы напрямую уведомлять разработчика о возникающих у пользователя исключениях в приложении. Подробности под катом.
Я считаю себя инженером внутреннего программного обеспечения — и, как может подтвердить любой внутренний инженер, большая часть нашей жизни уходит на мониторинг, поиск и устранение неисправностей, а также отладку наших приложений. Фундаментальное правило разработки ПО: программное обеспечение будет давать сбои. Новых разработчиков от опытных отличает то, как они планируют эти сбои. Надежное и эффективное логирование — важная часть планирования на случай неудач и, в конечном счёте, смягчения их последствий. Как и в случае разработки бэкенда, логирование может быть полезно в разработке программного обеспечения фронтенда, но оно гораздо больше, чем просто поиск и устранение неисправностей и отладка. Эффективное фронтенд-логирование, кроме того, может сделать разработку продуктивной, быстрой и радостной.
Несмотря на то, что я разделяю и практикую разработку через тестирование, мне нравятся гибкость, богатство информации и надёжность кода, предоставляемые разработчикам фронтенда, которые эффективно используют
console.log()
. Я решил поделиться некоторыми советами и хитростями, которые изучил и включил в свой рабочий процесс во время работы над
Firecode.io в надежде, что некоторые из них помогут сделать ваш рабочий процесс разработки немного продуктивнее и веселее. С удовольствием разделю эти советы на две широкие категории: быстрое и грязное логирование, когда вы активно собираете и отлаживаете приложение, и долговременная запись в лог для понимания, когда ваше приложение работает, как ожидалось, а когда нет.
Советы по быстрому, грязному логированию разработки с console.log()
.
Не используйте console.log()
.
Да, правда. Я не пользуюсь
console.log()
. Хотя… Ладно. Я пишу обёртки, которые используют
console.log
. Подробнее об этом — в разделе логирования в производственной среде. Но, если вы хотите логировать что-то в приложении, чтобы увидеть, что происходит, используйте
console.trace()
. В дополнение ко всему из
console.log()
этот метод выводит всю трассировку стека, чтобы вы точно знали, откуда идёт сообщение.
Используйте имена вычисляемых свойств ES6 для идентификации объектов и чтобы не путать их с именами переменных.
Это просто — используйте синтаксис вычисляемых свойств ES6: оберните объекты, которые вы хотите логировать, в фигурные скобки вот так:
console.log({user})
, а не
console.log(user)
. Логирование аккуратное: ключ — имя переменной, а значение — сам объект. Такой подход особенно полезен, когда вы спешите и хотите логировать несколько объектов одной командой
console.log()
.
Отображение уровней логирования: ERROR, WARN, INFO
console.log(param)
по умолчанию имеет значение
INFO
— однако в вашем распоряжении 3 других уровня логирования, которыми вы не должны пренебрегать —
console.debug()
,
console.warning()
и
console.error()
. Помимо различий в форматировании (заметили разные цвета?) консоль разработчика в браузере позволяет легко отфильтровывать логи разных уровней с помощью удобного выпадающего списка, ненужные логи убираются вот так:
При логировании списков элементов пользуйтесь console.table()
Одна из моих любимых функций говорит сама за себя. Если вам когда-нибудь понадобится логировать список объектов, дайте шанс
console.table()
.
Дебажим быстро с помощью debugger
Хотите сэкономить несколько драгоценных секунд? Вместо того чтобы искать файл в консоли разработчика, в который хотите добавить точку останова, впишите в код строку
debugger
эта строка остановит выполнение кода. Это всё, теперь можно отлаживать и переходить к функциям, как обычно.
Тонкое профилирование с console.profile()
и console.time()
Хотите профилировать поток пользователя в вашем приложении, чтобы найти горячие точки? Укажите триггер
console.profile(profileName)
в начале профилируемого кода и
console.profileEnd(profileName)
в его конце, чтобы исследовать профиль процессора в потоке.
Кроме того, можно точно измерить, сколько времени занимает выполнение потока, поместив
console.time(id)
в его начале и
console.timeEnd(id)
в его конце.
Подсчёт количества выполнений кода через console.count()
Это одна из тех функций, для которых я не нашёл особого применения, тем не менее польза от нее есть:
console.count(label)
помогает точно узнать, сколько раз выполняется фрагмент кода, это полезно при поиске и устранении состояния гонки и в других ситуациях.
Красивое логирование с помощью CSS
Безусловно, это моя любимая консольная функция, которую я широко использую при логировании в производственной среде (подробнее об этом — в соответствующем разделе). Ближе к сути: мы можем использовать строки форматирования, чтобы форматировать сообщения лога. Здесь
%c
— модификатор для кода CSS, а всё, что после него, — это сообщение.
Можно стилизовать несколько элементов, расширив строку через
%s
, вот так:
Я выраженный визуал, мне нравится тратить какое-то время на то, чтобы информационные и отладочные логи выглядели красиво и в то же время были полезны. Я широко использую эту функцию в производственном логировании Firecode.io. И это прекрасная тема для следующего раздела.
Логирование через console.log()
в производственной среде
.
Подготовка кода фронтенда включает несколько этапов. Некоторые из них — это уменьшение размера и сжатие вашего кода, генерация дайджестов кэшируемых ассетов и удаление
console.log()
из кода приложения. Почему удаляется
console.log()
? Потому что не хочется, чтобы пользователи открывали консоль разработчика и видели логи — дыры в безопасности для пытливых умов.
Но когда приложение используете вы, скорее всего, вы хотите добиться тонкого логирования, чтобы понимать, как ваше приложение работает, а также находить и устранять ошибки. Если ваше приложение используется другими людьми, хочется получать уведомления, когда они сталкиваются с ошибками, чтобы проследить их в коде и исправить их. Вот, что делаю в этом случае я.
Не пользуюсь console.log()
Вместо этого я написал обёртку, которая содержит логику условного логирования, основанную на уровне логирования, который, в свою очередь, основывается на глобальной переменной бэкенда.
Внимание! Впереди фрагменты кода TypeScript. Если вы не знакомы с TypeScript, думайте о нём, как о надмножестве JavaScript с типами, на которых сделан акцент (это грубое упрощение). Иначе говоря,
const str = "some string";
превращается в
const str: string = "some string"
— типы добавляются после имени переменной с двоеточием.
Разрабатывая Firecode.io, я написал собственный фронтенд-фреймворк, который использует RxJS, но содержит знакомые концепции, такие как компоненты, из других популярных фреймворков, к примеру, React и Vue. При этом добавлены и другие концепции: движки для блоков тяжёлого для процессора кода, каналы для сообщений WebSocket и клиенты для HTTP-запросов. Очень важна была визуализация совместной работы всех этих частей, поэтому я реализовал пользовательское форматирование в классе-обёртке
Logger
, этот класс форматирует и визуально отделяет журналы от каждой части приложения.
Вместо вызова
console.log("Cache SET to", {value})
я вызываю
Logger.debug("Cache set to", {value}, Framework.Cache)
. В классе
Logger
есть перечисление TypeScript, сопоставляющее каждый компонент фреймворка с цветом:
Так я во время разработки визуально концентрируюсь на компонентах приложения. Например, когда я хочу посмотреть, что делает
WsRequestCache
, я могу «отключиться» от всех логов, кроме бирюзовых.
Защитите логи установкой уровня логирования на бэкенде
Я настроил Firecode.io на включение логирования на уровне отладки по умолчанию для пользователей-администраторов через переменную JavaScript, она устанавливается бэкендом. При этом предприимчивые пользователи все еще могут найти и установить соответствующие флаги в консоли разработчика, чтобы включить точный журнал. Это лучше, чем ситуация, когда каждому пользователю приложения по умолчанию представлены все логи, и лучше, чем постпроцессор, полностью удаляющий логи из приложения в производственной среде. Установка уровня логирования на бэкенде в Ruby on Rails:
const logLevel: number = <%= @app.get_log_level_for_user %>
И в классе
Logger
:
class Logger {
...
...
static info(...) {
shouldLog(Level.INFO) && console.log(...);
...
}
}
Логируйте возможные ошибки и уведомляйте о них
И последнее, но не менее важное: хочется получать уведомления, когда пользователи сталкиваются с исключениями в приложении, не обязательно при этом с выводом на консоль разработчика. Это возможно. Включите вызов, передающий ваши ошибки в APM-сервис стороннего вендора (например
AppSignal) в функцию ошибок вашего логгера. Пример:
class Logger {
...
...
static error(e) {
if (shouldLog(Level.ERROR)) {
console.error(e);
}
appsignal.sendError(e);
}
}
AppSignal содержит интеграции для передачи ваших ошибок в службы исходящих уведомлений, таких как Slack, PagerDuty и OpsGenie, — вы даже можете подключить инструмент управления проектами, например JIRA или Trello, чтобы автоматически создавать Issues и баги для удобства вашей команды.
Итоги
Я очень надеюсь, что эти советы и истории сделают вашу фронтенд-разработку немного продуктивнее и веселее! Очевидно, что в этом посте я коснулся только поверхности боевого искусства логирования, так что, если у вас есть еще какие-то советы, которыми можно поделиться, я бы с удовольствием прочитал их в своём
Twitter.
И два дополнения. Я перестраиваю Firecode.io с нуля, добавляя совершенно новый набор вопросов для собеседований по кодированию JavaScript, Java, Python и Scala.
Если вы заинтересованы в написании кода для подготовки к собеседованию, который адаптируется к вашему стилю обучения и доставляет удовольствие, зарегистрируйтесь, указав свой адрес электронной почты
здесь. При запуске нового Firecode.io я предоставлю вам бесплатную трёхмесячную подписку. Я буду размещать больше материалов о создании веб-приложений промышленного масштаба (таких как Firecode.io) с нуля в качестве стороннего проекта. Если вы новичок в JavaScript и хотите понять, как объектноориентированный JavaScript и прототипное наследование работают под капотом, ознакомьтесь с моей любимой книгой по этой теме —
The Principles of Object-Oriented JavaScript, и, если вам интересно узнать больше о том, почему вместо JS следует использовать TypeScript, ознакомьтесь с
Effective TypeScript.
А помимо специальной литературы вам поможет промокод
HABR, добавляющий 10 % к скидке на баннере.
Рекомендуемые статьи