Журнал логирования что это
Что такое логирование?
Известно, что программисты проводят много времени, отлаживая свои программы, пытаясь разобраться, почему они не работают — или работают неправильно. Когда говорят про отладку, обычно подразумевают либо отладочную печать, либо использование специальных программ – дебагеров. С их помощью отслеживается выполнение кода по шагам, во время которого видно, как меняется содержимое переменных. Эти способы хорошо работают в небольших программах, но в реальных приложениях быстро становятся неэффективными.
Сложность реальных приложений
Возьмем для примера типичный сайт. Что он в себя включает?
И это только самый простой случай. Реальность же значительно сложнее: множество разноплановых серверов, системы кеширования (ускорения доступа), асинхронный код, очереди, внешние сервисы, облачные сервисы. Все это выглядит как многослойный пирог, внутри которого где-то работает нами написанный код. И этот код составляет лишь небольшую часть всего происходящего. Как в такой ситуации понять, на каком этапе был сбой, или все пошло не по плану? Для этого, как минимум, нужно определить, в каком слое произошла ошибка. Но даже это не самое сложное. Об ошибках в работающем приложении узнают не сразу, а уже потом, — когда ошибка случилась и, иногда, больше не воспроизводится.
Логирование
И для всего этого многообразия систем существует единое решение — логирование. В простейшем случае логирование сводится к файлу на диске, куда разные программы записывают (логируют) свои действия во время работы. Такой файл называют логом или журналом. Как правило, внутри лога одна строчка соответствует одному действию.
Выше небольшой кусок лога веб-сервера Хекслета. Из него видно ip-адрес, с которого выполнялся запрос на страницу и какие ресурсы загружались, метод HTTP, ответ бекенда (кода) и размер тела ответа в HTTP. Очень важно наличие даты. Благодаря ей всегда можно найти лог за конкретный период, например на то время, когда возникла ошибка. Для этого логи грепают:
Когда программисты только начинают свой путь, они, часто не зная причину ошибки, опускают руки и говорят «я не знаю, что случилось, и что делать». Опытный же разработчик всегда первым делом говорит «а что в логах?». Анализировать логи — один из базовых навыков в разработке. В любой непонятной ситуации нужно смотреть логи. Логи пишут все программы без исключения, но делают это по-разному и в разные места. Чтобы точно узнать, куда и как, нужно идти в документацию конкретной программы и читать соответствующий раздел документации. Вот несколько примеров:
Многие программы логируют прямо в консоль, например Webpack показывает процесс и результаты сборки:
Во фронтенде файлов нет, поэтому логируют либо прямо в консоль, либо к себе в бекенды (что сложно), либо в специализированные сервисы, такие как LogRocket.
Уровни логирования
Чем больше информации выводится в логах, тем лучше и проще отладка, но когда данных слишком много, то в них тяжело искать нужное. В особо сложных случаях логи могут генерироваться с огромной скоростью и в гигантских размерах. Работать в такой ситуации нелегко. Чтобы как-то сгладить ситуацию, системы логирования вводят разные уровни. Обычно это:
Поддержка уровней осуществляется двумя способами. Во-первых, внутри самой программы расставляют вызовы библиотеки логирования в соответствии с уровнями. Если произошла ошибка, то логируем как error, если это отладочная информация, которая не нужна в обычной ситуации, то уровень debug.
Во-вторых, во время запуска программы указывается уровень логирования, необходимый в конкретной ситуации. По умолчанию используется уровень info, который используется для описания каких-то ключевых и важных вещей. При таком уровне будут выводиться и warning, и error. Если поставить уровень error, то будут выводиться только ошибки. А если debug, то мы получим лог, максимально наполненный данными. Обычно debug приводит к многократному росту выводимой информации.
Уровни логирования, обычно, выставляются через переменную окружения во время запуска программы. Например, так:
Существует и другой подход, основанный не на уровнях, а на пространствах имен. Этот подход получил широкое распространение в JS-среде, и является там основным. Фактически, он построен вокруг одной единственной библиотеки debug для логирования, которой пронизаны практически все JavaScript-библиотеки как на фронтенде, так и на бекенде.
Принцип работы здесь такой. Под нужную ситуацию создается специализированная функция логирования с указанием пространства имен, которая затем используется для всех событий одного процесса. В итоге библиотека позволяет легко отфильтровать только нужные записи, соответствующие нужному пространству.
Запуск с нужным пространством:
Ротация логов
Со временем количество логов становится большим, и с ними нужно что-то делать. Для этого используется ротация логов. Иногда за это отвечает сама программа, но чаще — внешнее приложение, задачей которого является чистка. Эта программа по необходимости разбивает логи на более мелкие файлы, сжимает, перемещает и, если нужно, удаляет. Подобная система встроена в любую операционную систему для работы с логами самой системы и внешних программ, которые могут встраиваться в нее.
С веб-сайтами все еще сложнее. Даже на небольших проектах используется несколько серверов, на каждом из которых свои логи. А в крупных проектах тысячи серверов. Для управления такими системы созданы специализированные программы, которые следят за логами на всех машинах, скачивают их, складывают в заточенные под логи базы данных и предоставляют удобный способ поиска по ним.
Здесь тоже есть несколько путей. Можно воспользоваться готовыми решениями, такими как DataDog Logging, либо устанавливать и настраивать все самостоятельно через, например, ELK Stack
Архитектура логирования
Мой опыт разработки в основном строится вокруг разнообразных сетевых cервисов под Windows и Linux. Я обычно стремлюсь добиться максимальной кроссплатформенности вплоть до бинарной совместимости. И конечно, накопилось некоторое количество стабильных решений связанных с логированием.
Топик написан как продолжение к этой статье и будет полезен в первую очередь начинающим программистам.
Итак, начну со своих дополнений к предыдущей статье.
Я как и автор пользуюсь NLog’ом и разумеется широко использую его особенности. Конечно, после
их реализации в любом другом логгере, нижеописанную практику можно применять и у них.
Кстати, log4net продолжает развиваться.
Под капотом NLog
Сразу обсудим полезность второй фичи.
Часто, при разработке кода, возникает необходимость посмотреть значение какой либо переменной в процессе выполнения. Обычно, используют дебаггер и останавливают программу в интересующем месте. Для меня же, это явный признак, что этом месте будет полезен Trace вывод. В комплекте с юнит-тестами мы сразу получаем развертку этой переменной во времени и протокол для сравнения с тестами в других условиях. Таким образом, дебаггером я практически не пользуюсь.
Очевидно, что в боевом применении, даже выключенное подробное логирование, может мешать как скорости выполнения так и параллельности.
Исходный код класса можно посмотреть тут.
Отлично! Для NLog можно быть уверенным, что ваши сколь угодно детальные сообщения могут быть отключены и это минимально скажется на производительности. Но, это не повод посвящать логированию половину кода.
Что и как логировать
Следует придерживаться правил:
В целом, при выводе в лог, всегда отмечайте, то количество потенциально лишних вычислений, которые потребуются для случая когда лог отключен.
Простой пример (фрагмент некоторого класса):
private static Logger Log = LogManager. GetCurrentClassLogger ( ) ;
public string Request ( string cmd, string getParams )
Uri uri = new Uri ( _baseUri, cmd + «?» + getParams ) ;
HttpWebRequest webReq = ( HttpWebRequest ) WebRequest. Create ( uri ) ;
webReq. Method = «GET» ;
webReq. Timeout = _to ;
using ( WebResponse resp = webReq. GetResponse ( ) )
using ( Stream respS = resp. GetResponseStream ( ) )
using ( StreamReader sr = new StreamReader ( respS ) )
page = sr. ReadToEnd ( ) ;
catch ( Exception err )
Все аргументы логирования требовались для логики. Сообщение Debug отмечает аргументы с которыми мы пришли в функцию. В обработчике ошибки мы дублируем входные параметры на случай отключения Debug уровня. А это уже даст информацию при необходимости написать юнит-тест. Стек исключения не выводим, так как остается возможность сделать это вышестоящим обработчиком.
Вообще, в текущем обработчике ошибок полезно детализировать контекст который к привел к исключению и специфичные особенности исключения. В примере было бы полезно вывести поле Status для случая WebException.
Гарантии сохранности лога
Несмотря на некоторые возможности NLog по авто записи логов, нет гарантии сохранности лога при завершении процесса.
Первое, что следует сделать, это обработать событие AppDomain.UnhandledException. В нем следует записать в лог полную информацию об ошибке и вызвать LogManager.Flush(). Обработчик этого события использует тот же поток, который и вызвал исключение, а по окончании, немедленно выгружает приложение.
private static readonly Logger Log = LogManager. GetCurrentClassLogger ( ) ;
public static void Main ( string [ ] args )
static void OnUnhandledException ( object sender, UnhandledExceptionEventArgs e )
Кроме того, следует вызывать LogManager.Flush() везде, где потенциально возможно завершение процесса. В конце всех не фоновых потоков.
Если ваше приложение представляет собой win-service или Asp.Net, то следует обработать соответствующие события начала и завершения кода.
Сколько логировать
Серьезная проблема для разработчика. Всегда хочется получать больше информации, но код начинает выглядеть очень плохо. Я руководствуюсь следующими соображениями.
Вывод в лог это по сути комментарий. Логирование уровня Trace по большей части их и заменяет.
Уровни Trace и Debug читают разработчики, а все что выше — техподдержка и админы. Поэтому до уровня Info сообщения должны точно отвечать на вопросы: «Что произошло?», «Почему?» и по возможности «Как исправить?». Особенно это касается ошибок в файлах конфигурации.
Боевое развертывание
Предположим, разработка дошла до внедрения.
Отложим вопросы ротации логов, размера файлов и глубины истории. Это все очень специфично для каждого проекта и настраивается в зависимости от реальной работы сервиса.
Остановлюсь только на смысловой организации файлов. Их следует разделить на 3 группы. Может потребуется развести логи модулей в разные файлы, но дальше я все равно буду говорить об одном файле для каждой группы.
Если приложение успешно внедрено, то в работе остаются только первые две группы.
Расследование сбоев
Когда работающий сервис подает признаки ошибки, то не следует его пытаться сразу перезагружать. Возможно нам «повезло» поймать ошибки связанные с неверной синхронизацией потоков. И не известно сколько в следующий раз ждать ее повторения.
В первую очередь следует подключить заготовленные заранее конфиги для группы наблюдения. Как раз это и должен позволять делать приличный логгер. Когда мы получили подтверждение о том, что новая конфигурация успешно применена, то пытаемся опять спровоцировать сбой. Желательно несколько раз. Это обеспечит возможность для его воспроизведения в «лабораторных» условиях. Дальше уже работа программистов. А пока можно и перезагрузиться.
name = «fileInfo» type = «AsyncWrapper» queueLimit = «5000» overflowAction = «Block» >
type = «File» fileName = «$
name = «fileWarn» type = «AsyncWrapper» queueLimit = «5000» overflowAction = «Block» >
type = «File» fileName = «$
name = «*» minlevel = «Info» writeTo = «fileInfo» />
name = «*» minlevel = «Warn» writeTo = «fileWarn» />
При настройке фильтров следует учитывать относительность уровней логирования для каждой из подсистем. Например, некоторый модуль, имея Info сообщение об инициализации, может быть создан для каждого подключенного пользователя. Разумеется, его вывод в Info группу следует ограничить уровнем Warn.
Чего с логгером делать не следует
Логгер должен быть простым и надежным как молоток. И у него должна быть четко очерчена область применения в конкретном проекте. К сожалению, разработчиков часто трудно удержать. Паттерны проектирования, это в основном полезно, но не этом случае. Достаточно часто стал замечать предложения выделить для логгера обобщенный интерфейс (пример) или реализовать обертку в проекте, чтобы отложить муки выбора NLog vs log4net на потом.
Что бы ни было тому причиной, надо точно помнить, что в первую очередь, такие удобства напрочь убивают компилятору возможность оптимизации.
Не стоит напрямую выводить информацию логгера пользователю, даже с фильтрами. Проблема в том, что эта информация зависит от внутренней структуры программы. Вряд ли вы в процессе рефакторинга пытаетесь сохранить вывод логгера. Наверное, здесь стоит просто задуматься и разделить функционал. Возможно, в проекте просто требуется еще один уровень логирования. В этом случае как раз и уместна будет обертка над логгером.
Чего же мне еще не хватает в NLog?
NLog, Log4Net, Enterprise Library, SmartInspect.
Разнообразные сравнения логгеров между собой, упускают одну важную деталь.
Важно сравнивать не только ограничения/возможности, но и возможность быстро добавить свои «хотелки».
Поэтому, буду пока дружить с NLog.
Чего и Вам желаю.
Что такое логи
Логи (лог-файлы) — это файлы, содержащие системную информацию работы сервера или компьютера, в которые заносятся определенные действия пользователя или программы. Иногда также употребляется русскоязычный аналог понятия — журнал.
Их предназначение — протоколирование операций, выполняемых на машине, для дальнейшего анализа администратором. Регулярный просмотр журналов позволит определить ошибки в работе системы в целом, конкретного сервиса или сайта (особенно скрытые ошибки, которые не выводятся при просмотре в браузере), диагностировать злонамеренную активность, собрать статистику посещений сайта.
Содержание
Виды логов
Поскольку основное программное обеспечение, установленное на сервере, чаще всего производит запись в системные журналы, то для каждой из таких программ будет свой журнал. В частности, можно выделить такие наиболее распространенные логи:
Расположение
Месторасположение журналов зависит от программного обеспечения, реализации настроек по умолчанию или пути, заданного администратором. То есть, в зависимости от того, что вы используете (возможно, это виртуальный хостинг, доступный VPS-план или аренда серверов в Европе или США), доступность и расположение логов будут значительно отличаться. Как правило, большая часть логов сервера хранится по пути /var/log/, но некоторые сервисы могут хранить логи в других каталогах. Для удобства всегда можно задать подходящий путь в конфигурационных файлах нужного программного обеспечения. Например, на сервере можно настроить демон syslog/rsyslog, который будет упорядочивать поступающие в него записи о работе сервисов и сохранять их в заданные пользователем файлы логов.
Рассмотрим расположение основных логов для наиболее распространенных дистрибутивов Linux. По умолчанию журналы в Linux хранятся в /var/log.
CentOS / Fedora
Для распространенного веб-сервера Apache файлы журналов называются access.log (журнал доступа к серверу) и error.log (журнал ошибок и уведомлений). Путь по умолчанию для журнала ошибок Apache — /var/log/httpd/error_log.
Основной файл лога — /var/log/syslog.
Лог загрузки системы — /var/log/dmesg.
Debian / Ubuntu
По умолчанию логи Apache будут сохраняться по пути /var/log/apache2.
Логи nginx — /var/log/nginx.
Журнал ошибок MySQL — /var/log/mysql/error.log.
Основной файл лога — /var/log/syslog.
Лог загрузки системы — /var/log/dmesg.
Вам нужно купить Wildcard SSL-сертификат? У нас вы найдете лучшие предложения от Центров сертификации Comodo, GeoTrust и Symantec.
Что такое логи
Логи (лог-файлы) — это файлы, содержащие системную информацию работы сервера или компьютера, в которые заносятся определенные действия пользователя или программы. Иногда также употребляется русскоязычный аналог понятия — журнал.
Их предназначение — протоколирование операций, выполняемых на машине, для дальнейшего анализа администратором. Регулярный просмотр журналов позволит определить ошибки в работе системы в целом, конкретного сервиса или сайта (особенно скрытые ошибки, которые не выводятся при просмотре в браузере), диагностировать злонамеренную активность, собрать статистику посещений сайта.
Содержание
Виды логов
Поскольку основное программное обеспечение, установленное на сервере, чаще всего производит запись в системные журналы, то для каждой из таких программ будет свой журнал. В частности, можно выделить такие наиболее распространенные логи:
Расположение
Месторасположение журналов зависит от программного обеспечения, реализации настроек по умолчанию или пути, заданного администратором. То есть, в зависимости от того, что вы используете (возможно, это виртуальный хостинг, доступный VPS-план или аренда серверов в Европе или США), доступность и расположение логов будут значительно отличаться. Как правило, большая часть логов сервера хранится по пути /var/log/, но некоторые сервисы могут хранить логи в других каталогах. Для удобства всегда можно задать подходящий путь в конфигурационных файлах нужного программного обеспечения. Например, на сервере можно настроить демон syslog/rsyslog, который будет упорядочивать поступающие в него записи о работе сервисов и сохранять их в заданные пользователем файлы логов.
Рассмотрим расположение основных логов для наиболее распространенных дистрибутивов Linux. По умолчанию журналы в Linux хранятся в /var/log.
CentOS / Fedora
Для распространенного веб-сервера Apache файлы журналов называются access.log (журнал доступа к серверу) и error.log (журнал ошибок и уведомлений). Путь по умолчанию для журнала ошибок Apache — /var/log/httpd/error_log.
Основной файл лога — /var/log/syslog.
Лог загрузки системы — /var/log/dmesg.
Debian / Ubuntu
По умолчанию логи Apache будут сохраняться по пути /var/log/apache2.
Логи nginx — /var/log/nginx.
Журнал ошибок MySQL — /var/log/mysql/error.log.
Основной файл лога — /var/log/syslog.
Лог загрузки системы — /var/log/dmesg.
Вам нужно купить Wildcard SSL-сертификат? У нас вы найдете лучшие предложения от Центров сертификации Comodo, GeoTrust и Symantec.
Что полезного можно вытащить из логов рабочей станции на базе ОС Windows
Пользовательская рабочая станция — самое уязвимое место инфраструктуры по части информационной безопасности. Пользователям может прийти на рабочую почту письмо вроде бы из безопасного источника, но со ссылкой на заражённый сайт. Возможно, кто-то скачает полезную для работы утилиту из неизвестно какого места. Да можно придумать не один десяток кейсов, как через пользователей вредоносное ПО может внедриться на внутрикорпоративные ресурсы. Поэтому рабочие станции требуют повышенного внимания, и в статье мы расскажем, откуда и какие события брать для отслеживания атак.
Для выявления атаки на самой ранней стадии в ОС Windows есть три полезных событийных источника: журнал событий безопасности, журнал системного мониторинга и журналы Power Shell.
Журнал событий безопасности (Security Log)
Это главное место хранения системных логов безопасности. Сюда складываются события входа/выхода пользователей, доступа к объектам, изменения политик и других активностей, связанных с безопасностью. Разумеется, если настроена соответствующая политика.
Перебор пользователей и групп (события 4798 и 4799). Вредоносное ПО в самом начале атаки часто перебирает локальные учетные записи пользователей и локальные группы на рабочей станции, чтобы найти учетные данные для своих тёмных делишек. Эти события помогут обнаружить вредоносный код раньше, чем он двинется дальше и, используя собранные данные, распространится на другие системы.
Создание локальной учётной записи и изменения в локальных группах (события 4720, 4722–4726, 4738, 4740, 4767, 4780, 4781, 4794, 5376 и 5377). Атака может также начинаться, например, с добавления нового пользователя в группу локальных администраторов.
Попытки входа с локальной учётной записью (событие 4624). Добропорядочные пользователи заходят с доменной учётной записью и выявление входа под локальной учётной записью может означать начало атаки. Событие 4624 включает также входы под доменной учетной записью, поэтому при обработке событий нужно зафильтровать события, в которых домен отличается от имени рабочей станции.
Попытка входа с заданной учётной записью (событие 4648). Такое бывает, когда процесс выполняется в режиме “Запуск от имени” (run as). В нормальном режиме работы систем такого не должно быть, поэтому такие события должны находиться под контролем.
Блокировка/разблокировка рабочей станции (события 4800-4803). К категории подозрительных событий можно отнести любые действия, которые происходили на заблокированной рабочей станции.
Изменения конфигурации файрволла (события 4944-4958). Очевидно, что при установке нового ПО настройки конфигурации файрволла могут меняться, что вызовет ложные срабатывания. Контролировать такие изменения в большинстве случаев нет необходимости, но знать о них точно лишним не будет.
Подключение устройств Plug’n’play (событие 6416 и только для WIndows 10). За этим важно следить, если пользователи обычно не подключают новые устройства к рабочей станции, а тут вдруг раз — и подключили.
Windows включает в себя 9 категорий аудита и 50 субкатегорий для тонкой настройки. Минимальный набор субкатегорий, который стоит включить в настройках:
Системный монитор (Sysmon)
Sysmon — встроенная в Windows утилита, которая умеет записывать события в системный журнал. Обычно требуется его устанавливать отдельно.
Эти же события можно в принципе найти в журнале безопасности (включив нужную политику аудита), но Sysmon даёт больше подробностей. Какие события можно забирать из Sysmon?
Создание процесса (ID события 1). Системный журнал событий безопасности тоже может сказать, когда запустился какой-нибудь *.exe и даже покажет его имя и путь запуска. Но в отличие от Sysmon не сможет показать хэш приложения. Злонамеренное ПО может называться даже безобидным notepad.exe, но именно хэш выведет его на чистую воду.
Сетевые подключения (ID события 3). Очевидно, что сетевых подключений много, и за всеми не уследить. Но важно учитывать, что Sysmon в отличие от того же Security Log умеет привязать сетевое подключение к полям ProcessID и ProcessGUID, показывает порт и IP-адреса источника и приёмника.
Изменения в системном реестре (ID события 12-14). Самый простой способ добавить себя в автозапуск — прописаться в реестре. Security Log это умеет, но Sysmon показывает, кто внёс изменения, когда, откуда, process ID и предыдущее значение ключа.
Создание файла (ID события 11). Sysmon, в отличие от Security Log, покажет не только расположение файла, но и его имя. Понятно, что за всем не уследишь, но можно же проводить аудит определённых директорий.
А теперь то, чего в политиках Security Log нет, но есть в Sysmon:
Изменение времени создания файла (ID события 2). Некоторое вредоносное ПО может подменять дату создания файла для его скрытия из отчётов с недавно созданными файлами.
Загрузка драйверов и динамических библиотек (ID событий 6-7). Отслеживание загрузки в память DLL и драйверов устройств, проверка цифровой подписи и её валидности.
Создание потока в выполняющемся процессе (ID события 8). Один из видов атаки, за которым тоже нужно следить.
События RawAccessRead (ID события 9). Операции чтения с диска при помощи “\\.\”. В абсолютном большинстве случаев такая активность должна считаться ненормальной.
Создание именованного файлового потока (ID события 15). Событие регистрируется, когда создается именованный файловый поток, который генерирует события с хэшем содержимого файла.
Создание named pipe и подключения (ID события 17-18). Отслеживание вредоносного кода, который коммуницирует с другими компонентами через named pipe.
Активность по WMI (ID события 19). Регистрация событий, которые генерируются при обращении к системе по протоколу WMI.
Для защиты самого Sysmon нужно отслеживать события с ID 4 (остановка и запуск Sysmon) и ID 16 (изменение конфигурации Sysmon).
Журналы Power Shell
Power Shell — мощный инструмент управления Windows-инфраструктурой, поэтому велики шансы, что атакующий выберет именно его. Для получения данных о событиях Power Shell можно использовать два источника: Windows PowerShell log и Microsoft-WindowsPowerShell / Operational log.
Windows PowerShell log
Загружен поставщик данных (ID события 600). Поставщики PowerShell — это программы, которые служат источником данных для PowerShell для просмотра и управления ими. Например, встроенными поставщиками могут быть переменные среды Windows или системный реестр. За появлением новых поставщиков нужно следить, чтобы вовремя выявить злонамеренную активность. Например, если видите, что среди поставщиков появился WSMan, значит был начат удаленный сеанс PowerShell.
Microsoft-WindowsPowerShell / Operational log (или MicrosoftWindows-PowerShellCore / Operational в PowerShell 6)
Журналирование модулей (ID события 4103). В событиях хранится информация о каждой выполненной команде и параметрах, с которыми она вызывалась.
Журналирование блокировки скриптов (ID события 4104). Журналирование блокировки скриптов показывает каждый выполненный блок кода PowerShell. Даже если злоумышленник попытается скрыть команду, этот тип события покажет фактически выполненную команду PowerShell. Ещё в этом типе события могут фиксироваться некоторые выполняемые низкоуровневые вызовы API, эти события обычно записывается как Verbose, но если подозрительная команда или сценарий используются в блоке кода, он будет зарегистрирован как c критичностью Warning.
Обратите внимание, что после настройки инструмента сбора и анализа этих событий потребуется дополнительное время на отладку для снижения количества ложных срабатываний.
Расскажите в комментариях, какие собираете логи для аудита информационной безопасности и какие инструменты для этого используете. Одно из наших направлений — решения для аудита событий информационной безопасности. Для решения задачи сбора и анализа логов можем предложить присмотреться к Quest InTrust, который умеет сжимать хранящиеся данные с коэффициентом 20:1, а один его установленный экземпляр способен обрабатывать до 60000 событий в секунду из 10000 источников.