Лог программы что это
Что такое лог (log) программы.
Решая различные компьютерные задачи, можно не раз столкнуться с таким понятием как лог (с англ. log). Лог какой-то программы. Давайте попробуем разобраться что это такое и для чего это нужно.
Log (с англ. журнал). У большинства программ, которые установлены на вашем компьютере, есть этот самый журнал.
Т.е. это такой же обычный файл, который мы с вами можем создать на компьютере. Таким же образом программа работая на компьютере, может создать этот файл и вносить туда программным образом какие-то текстовые пометки.
Зачем же программе вести какие-то записи, какой-то журнал?
Дело в том, что если мы с вами будем следить за человеком, который работает на компьютере, мы можем сказать, что этот человек делал в конкретный момент времени, какие программы он запускал, какие ошибки он совершал при работе на компьютере и.т.д.
Но, если мы говорим о компьютерной программе, здесь все не так ясно. Все действия, которые производит программа, они скрыты от взгляда обычного пользователя. Они обычно происходят с такой большой скоростью событий, что человеческий глаз просто не успеет за все этим уследить.
Для того, чтобы отслеживать состояние какой-то программы. Что делала программа в какой-то конкретный момент времени, какие при этом возникали ошибки, кто с этой программой взаимодействовал и др. вопросы. Все события, которые происходили с этой программой, эта программа может записывать в специальный журнал, так называемый лог-файл.
В каждой записи содержится информация о том, что происходило с программой и когда это происходило.
Давайте подведем итог, что такое лог и зачем он нужен. Это текстовый файл, в который программа записывает какие-то события, которые с ней происходят. Благодаря этим событиям мы можем получить какую-то дополнительную информацию, что происходило с этой программой в какой-то определенный момент времени, получить отладочную информацию, чтобы легче устранить какую-то ошибку.
Надеюсь, что стало понятнее что такое лог-файл и зачем он нужен и вы теперь будете использовать этот журнал в своей работе.
Что такое логи
Логи (лог-файлы) — это файлы, содержащие системную информацию работы сервера или компьютера, в которые заносятся определенные действия пользователя или программы. Иногда также употребляется русскоязычный аналог понятия — журнал.
Их предназначение — протоколирование операций, выполняемых на машине, для дальнейшего анализа администратором. Регулярный просмотр журналов позволит определить ошибки в работе системы в целом, конкретного сервиса или сайта (особенно скрытые ошибки, которые не выводятся при просмотре в браузере), диагностировать злонамеренную активность, собрать статистику посещений сайта.
Содержание
Виды логов
Поскольку основное программное обеспечение, установленное на сервере, чаще всего производит запись в системные журналы, то для каждой из таких программ будет свой журнал. В частности, можно выделить такие наиболее распространенные логи:
Расположение
Месторасположение журналов зависит от программного обеспечения, реализации настроек по умолчанию или пути, заданного администратором. То есть, в зависимости от того, что вы используете (возможно, это виртуальный хостинг, доступный 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.
Как читать логи сервера и что это такое?
Логи – это инструмент, при помощи которого можно отслеживать рабочий процесс сервера или сайта. Поэтому знать, как читать логи это полезное умение для выявления сбоев в работе ПО, быстрого и результативного реагирования на другие проблемы (выявление злонамеренных действий), эффективного анализа рабочий процесс, противодействия DDoS-атакам.
Содержание:
Что такое логи и зачем они нужны
Логи (log) – это специальные текстовые файлы, в которых в хронологическом порядке фиксируется информация обо всех действиях программы или пользователей. Проще говоря, это журнал регистрации всех событий происходивших в системе:
Логи доступа указывают на уязвимые места сайта (в случае взлома), помогают собирать статистику посещаемости, узнавать откуда проводились запросы и какие ресурсы ссылаются на этот сайт, оценивать популярность страниц. По файлам ошибок проще найти источник проблемы и оперативно устранить баги и сбои. Журналы сервера (server logs) облегчают контроль рабочего процесса серверной машины.
В файлах логов записывается и отслеживается история работы всего программного комплекса. Поэтому специалисты рекомендуют периодически просматривать их, даже если никаких подозрительных моментов не произошло. И тем более немедленно обратиться к ним, если резко возросло количество ошибок, посыпался спам или заметно увеличилась нагрузка на сервер.
Типы логов и где их найти
Месторасположение логов зависит от используемого ПО, настроек, прописанного админом пути. Чаще всего server logs сохраняются в var/log/. Однако, не все сервисы помещают файлы регистрации в эту директорию. В любом случае, можно уточнить такую информацию у веб-хостера.
У дистрибутивов Linux CentOS или Fedora логи серверной машины лежат в /var/log/. Там можно найти:
Лог ошибок MySQL ($hostname.err) хранится в /var/lib/mysql/. Для Debian или Ubuntu местоположение логов аналогично, за исключением log file ошибок MySQL: /mysql/error.log. А также – логи веб сервера Apache сохраняются по пути /var/log/apache2.
У ОС Windows дружной метод структурирования log-файлов. События делятся на несколько уровней:
Их можно отсортировать или отфильтровать и выбрать необходимое.
Запуск и отключение логов осуществляется с административной панели. Как правило, доступ через раздел «журнал» или «логи». При этом стоит учитывать, что файлы не сохраняются годами. Поэтому, при необходимости посмотреть log, это нужно сделать своевременно.
Какая информация хранится в логах и как ее интерпретировать?
Для большинства пользователей содержимое log-файлов это бессмысленный набор символов. Как читать логи, чтобы понять, что в них зашифровано?
Строка access.log сервера содержит:
Как правило, такой информации достаточно, чтобы проанализировать ситуацию и сделать нужные выводы. Например, заблокировать бота, который создал чрезмерную нагрузку на сайт.
Файл ошибок (error.log) регистрирует моменты, когда что-то пошло не так. Из них можно узнать:
Конечно, даже после расшифровки, данных логов еще нужно проанализировать. Для этого существует различное ПО, которое помогает отрабатывать данные из логов – Weblog Expert, WebAlyzer, Analog, Webtrends, Awstats, SpyLOG Flexolyzer и другие платные и бесплатные программы.
Что такое логирование?
Известно, что программисты проводят много времени, отлаживая свои программы, пытаясь разобраться, почему они не работают — или работают неправильно. Когда говорят про отладку, обычно подразумевают либо отладочную печать, либо использование специальных программ – дебагеров. С их помощью отслеживается выполнение кода по шагам, во время которого видно, как меняется содержимое переменных. Эти способы хорошо работают в небольших программах, но в реальных приложениях быстро становятся неэффективными.
Сложность реальных приложений
Возьмем для примера типичный сайт. Что он в себя включает?
И это только самый простой случай. Реальность же значительно сложнее: множество разноплановых серверов, системы кеширования (ускорения доступа), асинхронный код, очереди, внешние сервисы, облачные сервисы. Все это выглядит как многослойный пирог, внутри которого где-то работает нами написанный код. И этот код составляет лишь небольшую часть всего происходящего. Как в такой ситуации понять, на каком этапе был сбой, или все пошло не по плану? Для этого, как минимум, нужно определить, в каком слое произошла ошибка. Но даже это не самое сложное. Об ошибках в работающем приложении узнают не сразу, а уже потом, — когда ошибка случилась и, иногда, больше не воспроизводится.
Логирование
И для всего этого многообразия систем существует единое решение — логирование. В простейшем случае логирование сводится к файлу на диске, куда разные программы записывают (логируют) свои действия во время работы. Такой файл называют логом или журналом. Как правило, внутри лога одна строчка соответствует одному действию.
Выше небольшой кусок лога веб-сервера Хекслета. Из него видно ip-адрес, с которого выполнялся запрос на страницу и какие ресурсы загружались, метод HTTP, ответ бекенда (кода) и размер тела ответа в HTTP. Очень важно наличие даты. Благодаря ей всегда можно найти лог за конкретный период, например на то время, когда возникла ошибка. Для этого логи грепают:
Когда программисты только начинают свой путь, они, часто не зная причину ошибки, опускают руки и говорят «я не знаю, что случилось, и что делать». Опытный же разработчик всегда первым делом говорит «а что в логах?». Анализировать логи — один из базовых навыков в разработке. В любой непонятной ситуации нужно смотреть логи. Логи пишут все программы без исключения, но делают это по-разному и в разные места. Чтобы точно узнать, куда и как, нужно идти в документацию конкретной программы и читать соответствующий раздел документации. Вот несколько примеров:
Многие программы логируют прямо в консоль, например Webpack показывает процесс и результаты сборки:
Во фронтенде файлов нет, поэтому логируют либо прямо в консоль, либо к себе в бекенды (что сложно), либо в специализированные сервисы, такие как LogRocket.
Уровни логирования
Чем больше информации выводится в логах, тем лучше и проще отладка, но когда данных слишком много, то в них тяжело искать нужное. В особо сложных случаях логи могут генерироваться с огромной скоростью и в гигантских размерах. Работать в такой ситуации нелегко. Чтобы как-то сгладить ситуацию, системы логирования вводят разные уровни. Обычно это:
Поддержка уровней осуществляется двумя способами. Во-первых, внутри самой программы расставляют вызовы библиотеки логирования в соответствии с уровнями. Если произошла ошибка, то логируем как error, если это отладочная информация, которая не нужна в обычной ситуации, то уровень debug.
Во-вторых, во время запуска программы указывается уровень логирования, необходимый в конкретной ситуации. По умолчанию используется уровень info, который используется для описания каких-то ключевых и важных вещей. При таком уровне будут выводиться и warning, и error. Если поставить уровень error, то будут выводиться только ошибки. А если debug, то мы получим лог, максимально наполненный данными. Обычно debug приводит к многократному росту выводимой информации.
Уровни логирования, обычно, выставляются через переменную окружения во время запуска программы. Например, так:
Существует и другой подход, основанный не на уровнях, а на пространствах имен. Этот подход получил широкое распространение в JS-среде, и является там основным. Фактически, он построен вокруг одной единственной библиотеки debug для логирования, которой пронизаны практически все JavaScript-библиотеки как на фронтенде, так и на бекенде.
Принцип работы здесь такой. Под нужную ситуацию создается специализированная функция логирования с указанием пространства имен, которая затем используется для всех событий одного процесса. В итоге библиотека позволяет легко отфильтровать только нужные записи, соответствующие нужному пространству.
Запуск с нужным пространством:
Ротация логов
Со временем количество логов становится большим, и с ними нужно что-то делать. Для этого используется ротация логов. Иногда за это отвечает сама программа, но чаще — внешнее приложение, задачей которого является чистка. Эта программа по необходимости разбивает логи на более мелкие файлы, сжимает, перемещает и, если нужно, удаляет. Подобная система встроена в любую операционную систему для работы с логами самой системы и внешних программ, которые могут встраиваться в нее.
С веб-сайтами все еще сложнее. Даже на небольших проектах используется несколько серверов, на каждом из которых свои логи. А в крупных проектах тысячи серверов. Для управления такими системы созданы специализированные программы, которые следят за логами на всех машинах, скачивают их, складывают в заточенные под логи базы данных и предоставляют удобный способ поиска по ним.
Здесь тоже есть несколько путей. Можно воспользоваться готовыми решениями, такими как DataDog Logging, либо устанавливать и настраивать все самостоятельно через, например, ELK Stack
Необходимо ли логирование программ?
Мне часто приходилось сталкиваться с полным отсутствием понимания назначения логирования в приложениях, хотя система логирования это далеко не второстепенная фаза в разработке проекта. Но, зачастую, люди это понимают уже на стадии сдачи поекта, когда введение полноценной системы логирования — процесс достаточно затратный и как результат, оставляют все как есть. Что в результате имеем? А имеем мы систему, в которой любая проблема у заказчика превращается в головную боль разработчика, т.к невозможно восстановить причины возникновения проблемы у заказчика, т.е у разработчика есть только описание проблемы от человека, у которого эта проблема воспроизвелась. К сожалению, мы живем не в идеальном мире и как правило описания проблемы носит малоинформативный характер, т.к пользователи системы не являются грамотными тестерами и не могут описать проблему подробно(есть конечно приятные исключения, но их мало). Особенно остро проблема логирования стоит когда нет возможности воспроизведения проблемы на своей стороне.
Реализация:
#include string >
#include
#include
#include
#include
#include
namespace smart_log
<
typedef void (*ErrorHandler)( const std:: string &);
typedef const std:: string (*Obfuscater)( const std:: string &);
//This type provides constant which set the writing log mode.
//If a current mode is bigger then methods mode the writing will be ignored.
//It needs for log flood control
enum LogLevel
struct LogParameters
<
std:: string m_strLogFileName;
//Pointer to a function which does appropriate manipulations in case of a log corruption. Set to 0 if it doesn’t need.
ErrorHandler m_pErrorHandler;
//Pointer to a function which obfuscates each string writing to a log file. Set to 0 if it doesn’t need.
Obfuscater m_pObfuscater;
size_t m_uiLogMaxSize;
unsigned short m_siMaxSavedLogs;
//Is the thread synchronization needed?
bool m_bIsMultiThreaded;
//Indicates whether log will be saved or not. If this flag is set then log will be saved when its size exceed m_uiLogMaxSize.
//Use m_siMaxSavedLogs to control how many log files will be saved. If the current number of log files has reached the m_siMaxSavedLogs then
//new saved log would replace the oldest one.
bool m_bIsSaveLog;
LogLevel m_xLogLevel;
//Path to the log location. It will be created if no exists.
boost::filesystem::path m_xLogSavedPath;
>;
class Logger
<
//—————————————Data
size_t m_uiCurrentLogSize;
short int m_siCurrentSavedLogs;
LogParameters m_xParameters;
std::ofstream m_xOfstream;
boost::interprocess::named_mutex m_xMutex;
//File name with full path in which it will be create
boost::filesystem::path m_xFullFileName;
//—————————————Internal methods
private :
//Common method for message writing
void WriteLog(LogLevel xLevel, const std:: string & strMessage);
void HandleLogSizeExcess();
std:: string Timestamp();
void CreatePath(boost::filesystem::path xPath);
//—————————————Interface
public :
Logger( const LogParameters& xParameters);
//Set of methods which concretize the common WriteLog method to log levels.
void WriteNormalLog( const std::ostringstream& strMessage)
<
WriteLog( eNormal, strMessage.str() );
>
void WriteExtendedLog( const std::ostringstream& strMessage)
<
WriteLog( eExtended, strMessage.str() );
>
void WriteDebugLog( const std::ostringstream& strMessage)
<
WriteLog( eDebug, strMessage.str() );
>
//————————————Setters
void SetErrorHandler(ErrorHandler pErrorHandler)
<
m_xParameters.m_pErrorHandler = pErrorHandler;
>
void SetLogMode(LogLevel xLevel)
<
m_xParameters.m_xLogLevel = xLevel;
>
>;
>
#endif _LOGGER_
namespace fs = boost::filesystem;
namespace multiprocess = boost::interprocess;
using namespace smart_log;
void Logger::WriteLog(LogLevel xLevel, const std:: string & strMessage)
try
<
multiprocess::scoped_lock xLock;
if (m_xParameters.m_bIsMultiThreaded)
<
xLock = multiprocess::scoped_lock (m_xMutex, multiprocess::defer_lock_type());
xLock. lock ();
>
CreatePath(m_xParameters.m_xLogSavedPath);
>
catch (fs::basic_filesystem_error )
<
if (m_xParameters.m_pErrorHandler)
m_xParameters.m_pErrorHandler( «Problem with a directory creation» );
else
throw ;
>
std:: string Logger::Timestamp()
<
SYSTEMTIME xTime;
::GetSystemTime(&xTime);
std::ostringstream xStream;
xStream «.»
«.»
«-»
«.»
«.»
«.»
return xStream.str();
>
Пример создания удобного интерфейса к классу:
class LogInstance
<
static boost::scoped_ptr m_spLogger;
public :
static const boost::scoped_ptr & GetLog()
<
if (!m_spLogger)
<
smart_log::LogParameters xParams;
xParams.m_bIsMultiThreaded = true ;
xParams.m_pErrorHandler = 0;
xParams.m_pObfuscater = 0;
xParams.m_siMaxSavedLogs = 0;
xParams.m_strLogFileName = «log_file» ;
xParams.m_uiLogMaxSize = 8192;
xParams.m_xLogLevel = smart_log::eNormal;
xParams.m_xLogSavedPath = «./log/log/log» ;
m_spLogger.reset( new smart_log::Logger(xParams));
>
return m_spLogger;
>
#define NORMAL_LOG(MSG)\
<\
std::ostringstream xStrm;\
xStrm «: » » » «(): » WriteNormalLog(xStrm);\
>
#define EXTENDED_LOG(MSG)\
<\
std::ostringstream xStrm;\
xStrm «: » » » «(): » WriteExtendedLog(xStrm);\
>
#define DEBUG_LOG(MSG)\
<\
std::ostringstream xStrm;\
xStrm «: » » » «(): » WriteDebugLog(xStrm);\
>
Надеюсь этим постом я сподвигну людей не использующих логи, на их использование и надеюсь моя реализацию будет им полезна. Удачной всем отладки 🙂