Wiki

Clone wiki

vxlog / HomeRU

English version

Руководство по использованию vxlog

1. Краткое описание

vxlog - это С++ библиотека для записи сообщений в журнальные файлы. Ее главной отличительной чертой является printf-подобный синтаксис.

Пример использования:

#include <vxlog/logger.h>
#include <vxlog/file-outputter.h>

// Create a new log module (external linkage)
VXLOG_DEFINE_MODULE(MainLogMod, "Test Module");

int main(int argc, char *argv[]) {
  vxlog::FileOutputterPtr outputter(new vxlog::FileOutputter("test.log", true, 0644));

  // set max level and bind the outputter to the log module
  typedef vxlog::Logger<MainLogMod> Log;
  Log::BindOutputter<vxlog::FileOutputter>(vxlog::Level::kInfo, outputter);

  Log::Info("Hello, World!");
  Log::Info("%_ != %_ != %_", 2, 2.1, -5);

  return 0;
}

Содержимое файла test.log:

01/09/09 11:59:42.602  INFO <Test Module> Hello, World!
01/09/09 11:59:42.607  INFO <Test Module> 2 != 2.1 != -5

По-умолчанию, каждый новый модуль выводит все сообщения на консоль. Все уровни включены. Например, для вывода на консоль достаточно:

#include <vxlog/logger.h>

VXLOG_DEFINE_MODULE(MainLogMod, "Test Module");
typedef vxlog::Logger<MainLogMod> Log;

int main(int argc, char *argv[]) {
  Log::Info("Hello, World!");
  Log::Info("%_ != %_ != %_", 2, 2.1, -5);

  return 0;
}

2. Термины

ТерминОписание
Метка-заполнительМесто в строке куда подставляется переменная. Например, vxlog::Info("Hello, %_", name) содержит метку-заполнитель %_. name - ее значение.
Аутпутер (Outputter)Объект, который осуществляет запись сообщений. Аутпутеры реализуют интерфейс vxlog::OutputterInterface, поэтому при желании можно определить свой аутпутер.
Журнальный модульОбъект, с помощью которого определяется различное поведение процесса журналирования.
УровеньВажность сообщения.
Строка форматированияЛитеральная строка с возможностью включения меток-заполнителей.


3. Дизайн

3.1. Особенности

  • Типобезопасный (type-safe) printf-подобный синтаксис.
  • Отсутствие спецификаторов типа и размера у метки-заполнителя.
  • Возможность вывода сообщений в файл, в консоль и с помощью syslog.
  • Фильтрация вывода сообщений по журнальным модулям.
  • Поддержка многопоточности (thread-safe).

3.2. Ограничения

  • Функции вывода могут иметь максимум только 15 параметров.
  • Отсутствие спецификторов ширины и точности у метки-заполнителя.
  • Невозможность указать журнальный модуль по-умолчанию.

3.3. Общий принцип работы

Для того чтобы воспользоваться vxlog необходимо:

  1. Определить журнальные модули с помощью макроса VXLOG_DEFINE_MODULE.
  2. Создать аутпутеры.
  3. Установить максимальный уровень и выбрать аутпутер для определенного журнального модуля.
  4. Вызвать одну из функций вывода.

4. Уровни

Доступные уровни:

НазваниеОписание
vxlog::Level::kNoneпсевдо-уровень
vxlog::Level::kFatalкритическая ошибка
vxlog::Level::kErrorошибка
vxlog::Level::kWarnпредупреждение
vxlog::Level::kInfoинформативное сообщение
vxlog::Level::kDebugотладочное сообщение, полезное для разработчиков

В таблице уровни перечислены в возрастающем порядке. Это значит, что если указать максимальный уровень vxlog::Level::kWarn, то выводиться будут сообщения только с уровнями: vxlog::Level::kFatal, vxlog::Level::kError и vxlog::Level::kWarn.

Использование vxlog::Level::kNone дает возможность отключить все уровни.

5. Аутпутеры

5.1. Вывод на консоль

Заголовочный файл для vxlog::ConsoleOutputter:

#include <vxlog/console-outputter.h>

Вывод происходит в /dev/stderr. Дата и время не выводятся.

5.2. Вывод в файл

Заголовочный файл для vxlog::FileOutputter:

#include <vxlog/file-outputter.h>

Инициализация:

// filename - имя журнального файла
// append   - определяет писать в конец файла или перезаписать его полностью
// mode     - права доступа для создаваемого журнального файла
FileOutputter(const char *filename, bool append, mode_t mode);

Буферизация не производится. Каждая запись (PIPE_BUF байт) в журнальный файл атомарна.

5.2.1. Ротация журнальных файлов

Объект типа vxlog::FileOutputter имеет функцию-член Reopen(), которая позволяет аутпутеру переоткрыть журнальный файл. Т.е. достаточно на определенный сигнал (например, SIGHUP) повесить переоткрытие файлов, чтобы сделать возможным ротацию.

Например:

#include <vector>
#include <vxlog/logger.h>
#include <vxlog/file-outputter.h>
#include <stdio.h>
#include <signal.h>
#include <string.h>

namespace {

void SigHandler(int sig, siginfo_t *siginfo, void *context) {
  vxlog::FileOutputterPtr *outputter =
      reinterpret_cast<vxlog::FileOutputterPtr *>(context);
  outputter->Reopen();
  // ...
}

}  // namespace

int main(int argc, char *argv[]) {
  vxlog::FileOutputterPtr outputter(new vxlog::FileOutputter("test.log", false, 0644));

  struct sigaction act;
  memset(&act, 0, sizeof(act));
  act.sa_sigaction = &SigHandler;
  act.sa_flags = SA_SIGINFO;
  if (sigaction(SIGHUP, &act, &outputter) < 0) {
    perror("sigaction");
    return 1;
  }

  // ...

  return 0;
}

5.3. Вывод с помощью syslog

Заголовочный файл для vxlog::SyslogOutputter:

#include <vxlog/syslog-outputter.h>

Инициализация:

// ident    - название программы
// option   - флаги для openlog
// facility - тип программы
bool SyslogOutputter(const char *ident, int option, int facility);

Уровень vxlog::Level::kFatal соотвествует LOG_CRIT для syslog.

6. Вывод сообщений

Шаблонный класс template<typename ModuleT> Logger содержит функции-члены, которые выводят сообщения в журнальный файл:

  • vxlog::Logger<ModuleT>::Fatal;
  • vxlog::Logger<ModuleT>::Error;
  • vxlog::Logger<ModuleT>::Warn;
  • vxlog::Logger<ModuleT>::Info;
  • vxlog::Logger<ModuleT>::Debug;

Каждая функция вывода, на самом деле, представлена 15 шаблонными функциями-членами (+1 нешаблонная) по количеству возможных меток-заполнителей. Например для vxlog::Info:

template<typename ModuleT>
class Logger {
 public:

  // ...

  void Info(const char *fmt);

  template<typename T1>
  void Info(const char *fmt, const T1 &t1);

  // ...

  template<typename T1, typename T2, ... , typename T15>
  void Info(const char *fmt, const T1 &t1, const T2 &t2, ..., const T15 &t15);

  // ...
};

7. Журнальные модули

С помощью журнальных модулей можно разделить программу на несколько подсистем. Для каждой такой подсистемы отдельно настраивается уровень и задается аутпутер. Несколько журнальный модулей могут разделять один аутпутер.

Для создания модуля необходимо воспользоваться макросом VXLOG_DEFINE_MODULE. Например, для модуля mTEST:

VXLOG_DEFINE_MODULE(mTEST, "Test module");

Этот макрос раскрывается в:

struct mTEST { static const char * name() { return "Test module"; } };

Чтобы начать пользоваться модулем необходимо его привязать к аутпутеру и задать выводимые уровни. Например:

vxlog::Logger<mTEST>::BindOutputter<vxlog::FileOutputter>(vxlog::Level::kInfo, outputter);

C помощью vxlog::Logger::BindOutputter можно повторно переинициализировать модуль, задав новый максимальный уровень и/или новый аутпутер.

8. Строка форматирования

Функции вывода вторым аргументом принимают строку форматирования, которая может содержать от 0 до 15 меток-заполнителей. Метка-заполнитель обозначается символом %_. Значением метки-заполнителя может выступать:

  • все целочисленные типы;
  • все типы с плавающей запятой;
  • тип char;
  • тип bool;
  • тип const char *;
  • тип std::string;
  • любой указатель.

Updated

Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.