@DVoropaev
Ставлю + к карме на хабре за ответы на вопросы

Как на C++ дергать логи из syslog?

Как на С++ лучше всего получить логи из файла /var/log/syslog с такое то по такое то время ?
  • Вопрос задан
  • 722 просмотра
Пригласить эксперта
Ответы на вопрос 3
leahch
@leahch Куратор тега Linux
3D специалист. Dолго, Dорого, Dерьмово.
Проблема с логами, что они не специфицированы, от слова - совсем. Формат файлов логов разный в зависимости от системы логирования, syslog делает одно, rsyslog делает второе, апач- третье, и т.д. причем еще есть ротация этих логов, которая запускается по крону (обычно).
Так что боюсь, парсер логов придется писать самому, либо поискать готовую библиотеку на c/c++. На ум библиотек не приходит, но есть программы-собиратели логов типа logstash, которые могут преобразовывать логи к какому-то единому знаменателю и кидать например в базу данных. Так вот из базы данных логи легче всего выдернуть, тем более на C.
Ответ написан
@vitaly_il1
DevOps Consulting
Как уже сказали, есть ротация логов, поэтому в общем случае выдернуть за определенный период времени трудно, т.к. надо найти логи за предыдущие периоды.
Варианты:
- складывать все syslog логи в базу данных - самая популярная на сегодня Elasticsearch. У нее есть API на всех языках, взять оттуда логи за период времени нет проблем.
Для нее же есть log shipper, который умеет парсить и посылать логи в Elasticsearch
- ограничиться частным случаем - ротация происходит раз в неделю, формат названий старых syslog такой-то.
- или писать все самому - по-моему, нет смысла
Ответ написан
Комментировать
myjcom
@myjcom Куратор тега C++
Oct  2 23:39:48 dvrh systemd-resolved[562]: Server returned er....

для такого вида примитив.
только по времени.

#include <iostream>
#include <string>
#include <fstream>
#include <sys/utsname.h>

std::string getTimestamp(const std::string& line)
{
  auto pos = line.rfind(' ');
  return line.substr(pos + 1, line.size() - pos);
}

int main(int argc, char* argv[])
{
  if(argc < 3)
  {
    std::cerr << "usage: file timestamp timestamp\n/var/log/syslog 11:00:00 12:00:00\n";
    exit(EXIT_FAILURE);
  }

  struct utsname uts;

  if(uname(&uts) == -1)
  {
    exit(EXIT_FAILURE);
  }

  if(std::ifstream flog(argv[1]); flog)
  {
    std::string start{argv[2]};
    std::string stop {argv[3]};
    std::string line;

    while(getline(flog, line))
    {
      std::string header = getTimestamp(line.substr(0, line.find(uts.nodename) - 1));
      if(header >= start && header <= stop)
      {
        std::cout << line << "\n";
      }
    }
  }
  else
  {
    std::cerr << "Cannot open file: " << argv[1];
  }
}


если еще и с датой - чуть больше.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы