Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!
Специально к старту нового потока курса «Frontend-разработчик» делимся с вами полезным переводом. Автор рассказывает, как использует методы логирования в производственной среде собственного проекта и в чём именно они помогают. Кроме того, нас знакомят с платформой AppSignal, созданной, чтобы напрямую уведомлять разработчика о возникающих у пользователя исключениях в приложении. Подробности под катом.
Я считаю себя инженером внутреннего программного обеспечения — и, как может подтвердить любой внутренний инженер, большая часть нашей жизни уходит на мониторинг, поиск и устранение неисправностей, а также отладку наших приложений. Фундаментальное правило разработки ПО: программное обеспечение будет давать сбои. Новых разработчиков от опытных отличает то, как они планируют эти сбои. Надежное и эффективное логирование — важная часть планирования на случай неудач и, в конечном счёте, смягчения их последствий. Как и в случае разработки бэкенда, логирование может быть полезно в разработке программного обеспечения фронтенда, но оно гораздо больше, чем просто поиск и устранение неисправностей и отладка. Эффективное фронтенд-логирование, кроме того, может сделать разработку продуктивной, быстрой и радостной.
Несмотря на то, что я разделяю и практикую разработку через тестирование, мне нравятся гибкость, богатство информации и надёжность кода, предоставляемые разработчикам фронтенда, которые эффективно используют
Советы по быстрому, грязному логированию разработки с
.
Да, правда. Я не пользуюсь
Это просто — используйте синтаксис вычисляемых свойств ES6: оберните объекты, которые вы хотите логировать, в фигурные скобки вот так:
Отображение уровней логирования:
При логировании списков элементов пользуйтесь
Одна из моих любимых функций говорит сама за себя. Если вам когда-нибудь понадобится логировать список объектов, дайте шанс
Дебажим быстро с помощью
Хотите сэкономить несколько драгоценных секунд? Вместо того чтобы искать файл в консоли разработчика, в который хотите добавить точку останова, впишите в код строку
Тонкое профилирование с
Хотите профилировать поток пользователя в вашем приложении, чтобы найти горячие точки? Укажите триггер
Кроме того, можно точно измерить, сколько времени занимает выполнение потока, поместив
Подсчёт количества выполнений кода через
Это одна из тех функций, для которых я не нашёл особого применения, тем не менее польза от нее есть:
Безусловно, это моя любимая консольная функция, которую я широко использую при логировании в производственной среде (подробнее об этом — в соответствующем разделе). Ближе к сути: мы можем использовать строки форматирования, чтобы форматировать сообщения лога. Здесь
Можно стилизовать несколько элементов, расширив строку через
Я выраженный визуал, мне нравится тратить какое-то время на то, чтобы информационные и отладочные логи выглядели красиво и в то же время были полезны. Я широко использую эту функцию в производственном логировании Firecode.io. И это прекрасная тема для следующего раздела.
Логирование через
.
Подготовка кода фронтенда включает несколько этапов. Некоторые из них — это уменьшение размера и сжатие вашего кода, генерация дайджестов кэшируемых ассетов и удаление
Но когда приложение используете вы, скорее всего, вы хотите добиться тонкого логирования, чтобы понимать, как ваше приложение работает, а также находить и устранять ошибки. Если ваше приложение используется другими людьми, хочется получать уведомления, когда они сталкиваются с ошибками, чтобы проследить их в коде и исправить их. Вот, что делаю в этом случае я.
Вместо этого я написал обёртку, которая содержит логику условного логирования, основанную на уровне логирования, который, в свою очередь, основывается на глобальной переменной бэкенда.
Внимание! Впереди фрагменты кода TypeScript. Если вы не знакомы с TypeScript, думайте о нём, как о надмножестве JavaScript с типами, на которых сделан акцент (это грубое упрощение). Иначе говоря,
Разрабатывая Firecode.io, я написал собственный фронтенд-фреймворк, который использует RxJS, но содержит знакомые концепции, такие как компоненты, из других популярных фреймворков, к примеру, React и Vue. При этом добавлены и другие концепции: движки для блоков тяжёлого для процессора кода, каналы для сообщений WebSocket и клиенты для HTTP-запросов. Очень важна была визуализация совместной работы всех этих частей, поэтому я реализовал пользовательское форматирование в классе-обёртке
Вместо вызова
Так я во время разработки визуально концентрируюсь на компонентах приложения. Например, когда я хочу посмотреть, что делает
Я настроил Firecode.io на включение логирования на уровне отладки по умолчанию для пользователей-администраторов через переменную JavaScript, она устанавливается бэкендом. При этом предприимчивые пользователи все еще могут найти и установить соответствующие флаги в консоли разработчика, чтобы включить точный журнал. Это лучше, чем ситуация, когда каждому пользователю приложения по умолчанию представлены все логи, и лучше, чем постпроцессор, полностью удаляющий логи из приложения в производственной среде. Установка уровня логирования на бэкенде в Ruby on Rails:
И в классе
И последнее, но не менее важное: хочется получать уведомления, когда пользователи сталкиваются с исключениями в приложении, не обязательно при этом с выводом на консоль разработчика. Это возможно. Включите вызов, передающий ваши ошибки в APM-сервис стороннего вендора (например AppSignal) в функцию ошибок вашего логгера. Пример:
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 % к скидке на баннере.
Я считаю себя инженером внутреннего программного обеспечения — и, как может подтвердить любой внутренний инженер, большая часть нашей жизни уходит на мониторинг, поиск и устранение неисправностей, а также отладку наших приложений. Фундаментальное правило разработки ПО: программное обеспечение будет давать сбои. Новых разработчиков от опытных отличает то, как они планируют эти сбои. Надежное и эффективное логирование — важная часть планирования на случай неудач и, в конечном счёте, смягчения их последствий. Как и в случае разработки бэкенда, логирование может быть полезно в разработке программного обеспечения фронтенда, но оно гораздо больше, чем просто поиск и устранение неисправностей и отладка. Эффективное фронтенд-логирование, кроме того, может сделать разработку продуктивной, быстрой и радостной.
Несмотря на то, что я разделяю и практикую разработку через тестирование, мне нравятся гибкость, богатство информации и надёжность кода, предоставляемые разработчикам фронтенда, которые эффективно используют
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 % к скидке на баннере.
- Обучение профессии Data Science
- Обучение профессии Data Analyst
- Онлайн-буткемп по Data Analytics
- Курс «Python для веб-разработки»
Eще курсы
- Продвинутый курс «Machine Learning Pro + Deep Learning»
- Курс «Математика и Machine Learning для Data Science»
- Курс по Machine Learning
- Разработчик игр на Unity
- Курс по JavaScript
- Профессия Веб-разработчик
- Профессия Java-разработчик
- C++ разработчик
- Курс по аналитике данных
- Курс по DevOps
- Профессия iOS-разработчик с нуля
- Профессия Android-разработчик с нуля
Рекомендуемые статьи
- Как стать Data Scientist без онлайн-курсов
- 450 бесплатных курсов от Лиги Плюща
- Как изучать Machine Learning 5 дней в неделю 9 месяцев подряд
- Сколько зарабатывает аналитик данных: обзор зарплат и вакансий в России и за рубежом в 2020
- Machine Learning и Computer Vision в добывающей промышленности