Как сделать лог консоли
Используем console.log() в Chrome на полную
Сложно представить себе разработку на JS без вывода информации в консоль. Говоря метафорически, console.log() — лекарство от большинства болезней кода.
Отладка — почти как расследование преступления, где главный преступник тоже вы — Филипе Фортес
Но помимо повсеместно используемой функции console.log(), есть ещё много инструментов, позволяющий сильно упростить процесс. Давайте разберём некоторые из них на простых примерах.
Самое простое — печать строки цветом, соответствующем типу события.
Используем плейсхолдеры
Для того, чтобы подставить данные в строку с сообщением, удобнее всего использовать плейсхолдеры.
%o — для объекта
%s — для строки
%d — для десятичного или целого числа
Добавляем CSS
Не хватает info/warn/error? Не беда! К консольным сообщениям можно применять CSS.
Хотите применить CSS только к части сообщения? Это делается вот так:
console.dir()
Часто гораздо удобнее напечатать JSON представление интересующего нас объекта.
Выводим HTML
HTML элементы в консоли можно исследовать так же, как в инспекторе.
console.table()
Хотите быстро посмотреть данные в списке из JSON?
console.group() и console.groupEnd()
Сообщения в консоли можно группировать для удобства.
console.count()
Эта функция записывает, сколько раз она была вызвана.
Если передан опциональный аргумент label, то функция будет записывать количество вызовов с той же label.
Если функция вызвана без параметров, то она запишет количество вызовов на той же строке.
console.assert()
Удобно использовать, когда вы хотите выводить информацию по условию. Будут напечатаны только те сообщения, где первый аргумент assert() ложен.
console.trace()
Этот метод поможет понять, каким путём код дошёл до определённой точки.
console.time()
Самый простой способ замерить время исполнения участка кода.
console.memory
Хотите наконец-то узнать, куда пропала вся свободная оперативная память?
console.clear()
Используйте, чтобы начать работу с чистого листа. Полностью очищает консоль от предыдущих сообщений.
Уроки JavaScript – ознакомление с функцией console.log()
Когда вы пишете приложение на JavaScript, очень полезно использовать отладчик (или дебаггер, от англ. debugger), т.е., программу, которая предназначена для поиска ошибок в других программах. Все браузеры поставляются с подобной программой, которая выполняет функции отладчика, — речь идет о Консоли (Console). Здесь вы найдете все ошибки, которые возникают при взаимодействии браузера с сайтом. Например, здесь вы можете увидеть недоступные ресурсы сайта (которые возвращают 404 ошибку), ошибки в JavaScript коде и массу других полезных данных.
Откройте Консоль в браузере и посмотрим на основные моменты по работе с ней.
Вызов инструментов разработчика (и консоли) в разных браузерах осуществляется так:
После того как вы открыли Консоль, попробуйте использовать этот инструмент в качестве калькулятора. Напишите следующее выражение:
Чуть ниже вы сразу увидите результат данной арифметической операции:
Если вам понравилось, можете поиграться дальше, с использованием других арифметических операций :).
В Консоли вы можете писать JavaScript код и сразу видеть результат его выполнения. Вот простой пример, напишите в Консоли следующий код и нажмите Enter:
Теперь, если вы, например, напишете переменную areaOfBox в Консоли, вы сразу увидите результат выполнения данного кода:
Попробуйте самостоятельно писать здесь JavaScript код, чтобы увидеть, как работает Консоль в качестве локального сервера.
Объект console в JavaScript дает вам доступ к Консоли браузера. Это позволяет вам выводить строки, массивы и объекты, которые помогают отлаживать код. Данная функция является частью объекта window и предоставляется объектной моделью браузера (BOM).
Самый простой пример – вывод сообщения (строки):
Пример работы с массивом в Консоли:
Пример работы с объектом в Консоли:
Пример работы с функцией в Консоли:
Пример отслеживания события click в Консоли:
Теперь, если вы нажмете кнопку на странице, вы увидите запись лога в Консоли браузера.
Готовим console.log() правильно
Специально к старту нового потока курса «Frontend-разработчик» делимся с вами полезным переводом. Автор рассказывает, как использует методы логирования в производственной среде собственного проекта и в чём именно они помогают. Кроме того, нас знакомят с платформой AppSignal, созданной, чтобы напрямую уведомлять разработчика о возникающих у пользователя исключениях в приложении. Подробности под катом.
Я считаю себя инженером внутреннего программного обеспечения — и, как может подтвердить любой внутренний инженер, большая часть нашей жизни уходит на мониторинг, поиск и устранение неисправностей, а также отладку наших приложений. Фундаментальное правило разработки ПО: программное обеспечение будет давать сбои. Новых разработчиков от опытных отличает то, как они планируют эти сбои. Надежное и эффективное логирование — важная часть планирования на случай неудач и, в конечном счёте, смягчения их последствий. Как и в случае разработки бэкенда, логирование может быть полезно в разработке программного обеспечения фронтенда, но оно гораздо больше, чем просто поиск и устранение неисправностей и отладка. Эффективное фронтенд-логирование, кроме того, может сделать разработку продуктивной, быстрой и радостной.
Советы по быстрому, грязному логированию разработки с console.log()
Не используйте console.log()
Используйте имена вычисляемых свойств ES6 для идентификации объектов и чтобы не путать их с именами переменных.
Отображение уровней логирования: ERROR, WARN, INFO
При логировании списков элементов пользуйтесь 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, а всё, что после него, — это сообщение.
Я выраженный визуал, мне нравится тратить какое-то время на то, чтобы информационные и отладочные логи выглядели красиво и в то же время были полезны. Я широко использую эту функцию в производственном логировании Firecode.io. И это прекрасная тема для следующего раздела.
Логирование через console.log() в производственной среде
Но когда приложение используете вы, скорее всего, вы хотите добиться тонкого логирования, чтобы понимать, как ваше приложение работает, а также находить и устранять ошибки. Если ваше приложение используется другими людьми, хочется получать уведомления, когда они сталкиваются с ошибками, чтобы проследить их в коде и исправить их. Вот, что делаю в этом случае я.
Не пользуюсь console.log()
Вместо этого я написал обёртку, которая содержит логику условного логирования, основанную на уровне логирования, который, в свою очередь, основывается на глобальной переменной бэкенда.
Внимание! Впереди фрагменты кода TypeScript. Если вы не знакомы с TypeScript, думайте о нём, как о надмножестве JavaScript с типами, на которых сделан акцент (это грубое упрощение). Иначе говоря, const str = «some string»; превращается в const str: string = «some string» — типы добавляются после имени переменной с двоеточием.
Защитите логи установкой уровня логирования на бэкенде
Я настроил 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 на полную
Метод console.log() — отличный способ вывести отладочную информацию, не мешая пользователю. Но знаете ли Вы, что объект console имеет еще уйму других не менее полезных методов? Очень редко разработчики используют этот функционал, ограничиваясь неблокирующим alert’ом. Что-ж, давайте исправим это положение.
Небольшое примечание: использование отладочного кода может негативно сказаться на производительности. Удаляйте его из продакшн версии.
Больше, чем просто сообщения
Перед тем, как погрузиться в малоизвестные методы console, рассмотрим функционал console.log подробнее. Например, возможность передачи любого числа аргументов:
В результате все переданные аргументы будут выведены и разделены пробелом. Это, конечно, хорошо, но было бы еще лучше, если бы мы могли как-нибудь вывести все эти аргументы в виде красиво отформатированного сообщения. Хотя, постойте… мы можем!
Если Вы знакомы с функцией printf() в других языках, то спешим обрадовать: console.log() умеет вести себя похожим образом. Возьмем последний пример и передадим первый аргумент в немного измененном виде.
Что за %s?
Отличный вопрос! Это управляющие последовательности, которые заменяются на соответствующие им значения (в порядке очередности). %s означает «трактовать значение как строку», %d — как число (Также можно использовать %i или %f).
Каждое вхождение такой последовательности будет заменено на следующий по порядку аргумент. Первое вхождение — на первый (за первым аргументом-строкой, конечно), ну и так далее.
Эта команда как бы говорит «Я начну со второго аргумента и продолжу, начиная со следующего». Как Вы видите, последовательности, которым не хватило аргументов, остались нетронутыми.
Первый аргумент (строка формата) также участвует в нумерации (она идет с нуля) аргументов. Таким образом, в нашем примере последний аргумент будет иметь номер 5. Но мы задали всего 5 аргументов и, при этом, начали со второго. Поэтому, последней управляющей последовательности аргументов не досталось, и она не изменилась.
Чтобы это исправить, можно изменить формат строки таким образом, чтобы «указатель» не следующий элемент синхронизировался со списком аргументов в определенный момент. Тогда все будет работать как положено.
Для того, чтобы аргументы были выведены правильно, нам нужно изменить порядок вывода второго и третьего элементов. Другие элементы и так в правильном положении, так что нет необходимости указывать их позиции. Аргументы будут использованы в следующем порядке: 2, 1, 3, 4, 5.
Форматирование строк — мощный инструмент, и я охватил только вершину айсберга. Попробуйте поиграться самостоятельно и почитать, что пишет Joe Hewitts о консоли.
Различные типы сообщения
Есть еще пара методов, подобных log, но отличающихся внешне. А именно: console.info(), console.warn() и console.error().
console.info(), console.warn() и console.error() в Firebug’е.
Все три метода умеют выводить строки в соответствие с форматом и принимать любое количество аргументов.
Логи DOM’а
Когда Вам нужно как-то указать в логах на DOM узел лучшего всего использовать методы console.dir() или console.dirxml(), которые могут перечислить свойства элемента или вывести HTML кода элемента.
Знакомьтесь: console.dir() и console.dirxml() в Chrome.
Группировка
Иногда бывает полезно сгруппировать логи для упрощения работы с ними. Для этого существуют методы console.group(), console.groupCollapsed() и console.groupEnd().
Группировка в консоли Safari.
Как Вы можете видеть, подряд идущие вызовы group создают вложенные папки. Чтобы закрывать папку, используйте метод console.groupEnd(). Метод console.groupCollapsed() аналогичен console.group() за тем лишь исключением, что группа со всем содержимым будет изначально свернута.
Профилирование и замеры
Также консоль позволяет точно замерять время, используя метод console.time() и console.timeEnd(). Расположите вызов первого из них перед кодом, время исполнения которого хотите замерить, а второго — после.
Пример работы console.time() и console.timeEnd() в Firefox
Таймеры связаны между собой метками (передаются первым аргументом и могут быть любой строкой), так что Вы можете запустить несколько таймеров одновременно. Когда сработает console.timeEnd(), будет выведено сообщение с меткой и прошедшим временем в миллисекундах.
Помимо замера времени можно профилировать Ваш код и вывести стек профилирования, который подробно показывает, где и сколько времени потратил браузер.
Профилирование в Chrome.
Assert’ы
Когда Вы работаете над сложным проектом, важно покрывать код юнит тестами. Это позволит избежать глупых ошибок и возможных регрессий. К счастью, консоль включает в себя assert’ы.
Assert’ы позволяют обеспечивать соблюдение правил в коде и быть уверенным, что результаты выполнения этого кода соответствуют ожиданиям. Метод console.assert() позволяет проводить элементарное тестирование кода: если что-то пойдет не так, будет выброшено исключение. Первым аргументом может быть все, что угодно: функция, проверка на равенство или проверка существования объекта.
Assert в Chrome
Метод assert принимает условие, которое является обязательным к выполнению (в данном случае простая строгая проверка на равенство) и, вторым аргументом, сообщение, которое будет выведено в консоль вместе с выброшенным исключением, если первое условие не будет выполнено.
Поддержка браузерами
Большинство перечисленных методов поддерживаются достаточно хорошо. IE8+, Firefox с расширением firebug, Opera или webkit-браузер вроде Safari или Chrome. Есть, правда, некоторые различия: Firefox, Safari и Chrome отличаются более широкой поддержкой. Проще всего проверить совместимость можно выполнив console.dir(console), результатом которого будет вывод объекта console со всеми его методами.
Opera с Dragonfly поддерживает большинство методов, за исключением форматирования строк и профилирования (хотя методы profile, profileEnd и реализованы, это всего лишь заглушки).
IE8 также поддерживает много вкусностей, включая форматирование строк и assert’ы, но не замеры времени, профилирование, методы dir или dirxml.
Стоит отметить, что firebug lite может добавить некоторые методы к console в браузерах, их не поддерживающих.
Это не полный список того, что есть в console, но я перечислил наиболее полезные возможности, существенно упрощающие процесс отладки и тестирования. Используйте приобретенные знания и не ограничивайтесь одним лишь логированием строк.
Extra
Итак, это был очень вольный перевод статьи, но теперь я бы хотел добавить немного от себя:
Node.JS (ветка 0.2) поддерживает методы log, info, warn, error, dir, time / timeEnd, assert и trace.
log не умеет изменять порядок аргументов для подстановок, но сами подстановки реализованы. При вызове метода trace в консоль будет выведен стек вызовов (все методы ничего не возвращают, а просто пишут в консоль). Работает это также как минимум в Chrome и Opera.
В Opera и Chrome, помимо уже перечисленных, реализованы следующие методы:
count — выводит, сколько раз уже выполнялась строка, на которой расположен вызов метода. Аргументом передается строка, которая будет выведена перед количеством вызовов.
debug — ничем не отличается от log.
Также в Chrome у объекта console есть свойство memory, являющееся объектом со свойствами totalJSHeapSize и usedJSHeapSize. Однако, в Chromium’е мне так и не удалось застать эти свойства со значениями, отличными от нуля.