Commit d40f8a8c authored by Pavel Vainerman's avatar Pavel Vainerman

(LogServer): реализовал поддержку "регулярных выражений" при обработке

названия log-ов (DebugStream) которым посылается команда.. (для возможности управления группой логов удовлятворяющих шаблону, одной командой)
parent 70ecd289
......@@ -51,10 +51,6 @@ SQL:
- добавить работу с History (при передаче указателя на SM в конструкторе).
Оптимизация
============
- сделать в TransportMessage поле consumer..
Version 2.5
============
- smonit запись значений в файл (csv?,sqlite?)
......
......@@ -459,6 +459,7 @@ mv -f %buildroot%python_sitelibdir_noarch/* %buildroot%python_sitelibdir/%oname
- (optimization): TransportMessage change format
- (uniset-codegen): minor fixes
- (SharedMemory): add new tests
- (LogServer): add regexp support for logname
* Thu May 28 2015 Pavel Vainerman <pv@altlinux.ru> 2.1-alt1
- repack header files..
......
......@@ -40,7 +40,8 @@ class LogAgregator:
std::shared_ptr<DebugStream> getLog( const std::string& logname );
LogInfo getLogInfo( const std::string& logname );
std::list<std::shared_ptr<DebugStream>> getLogList();
std::list<LogInfo> getLogList();
std::list<LogInfo> getLogList( const std::string& regexp_str );
protected:
void logOnEvent( const std::string& s );
......
#include <memory>
#include <regex>
#include "DebugExtBuf.h"
#include "LogAgregator.h"
// -------------------------------------------------------------------------
......@@ -108,12 +109,32 @@ LogAgregator::LogInfo LogAgregator::getLogInfo( const std::string& logname )
return LogInfo();
}
// -------------------------------------------------------------------------
std::list<std::shared_ptr<DebugStream>> LogAgregator::getLogList()
std::list<LogAgregator::LogInfo> LogAgregator::getLogList()
{
std::list< std::shared_ptr<DebugStream> > l;
std::list<LogAgregator::LogInfo> l;
for( auto && i : lmap )
l.push_back(i.second.log);
for( auto&& i : lmap )
l.push_back(i.second);
return std::move(l);
}
// -------------------------------------------------------------------------
std::list<LogAgregator::LogInfo> LogAgregator::getLogList( const std::string& regex_str )
{
std::list<LogAgregator::LogInfo> l;
try
{
std::regex rule(regex_str);
for( auto&& i : lmap )
{
if( std::regex_match(i.second.log->getLogName(), rule) )
l.push_back(i.second);
}
}
catch( const std::exception& ex )
{
cerr << "(LogAgregator::getLogList): " << ex.what() << std::endl;
}
return std::move(l);
}
......
......@@ -2,6 +2,7 @@
#include <memory>
#include <string>
#include <sstream>
#include <regex>
#include <fcntl.h>
#include <errno.h>
#include <cstring>
......@@ -102,10 +103,9 @@ void LogSession::run()
else
{
slog.info() << peername << "(run): receive command: '" << msg.cmd << "'" << endl;
string cmdLogName(msg.logname);
auto cmdlog = log;
string logfile(log->getLogFile());
std::list<LogAgregator::LogInfo> loglist;
if( !cmdLogName.empty () )
{
......@@ -113,98 +113,87 @@ void LogSession::run()
if( lag )
{
LogAgregator::LogInfo inf = lag->getLogInfo(cmdLogName);
if( inf.log )
{
cmdlog = inf.log;
logfile = inf.logfile;
}
if( cmdLogName == "ALL" )
loglist = lag->getLogList();
else
{
// если имя задали, но такого лога не нашлось
// то игнорируем команду
cmdlog = 0;
logfile = "";
}
loglist = lag->getLogList(cmdLogName);
}
else
{
// если имя лога задали, а оно не совпадает с текущим
// игнорируем команду
if( log->getLogFile() != cmdLogName )
if( cmdLogName == "ALL" || log->getLogFile() == cmdLogName )
{
cmdlog = 0;
logfile = "";
LogAgregator::LogInfo log0(log);
loglist.push_back(log0);
}
}
}
// это команда по всем логам..
if( msg.cmd == LogServerTypes::cmdList )
{
ostringstream s;
s << "List of managed logs:" << endl;
s << "=====================" << endl;
auto lag = dynamic_pointer_cast<LogAgregator>(log);
if( !lag )
{
s << log->getLogName() << endl;
}
else
{
auto lst = lag->getLogList();
for( const auto& i : lst )
s << i.log->getLogName() << endl;
}
s << "=====================" << endl;
if( isPending(Socket::pendingOutput, cmdTimeout) )
{
*tcp() << s.str();
tcp()->sync();
}
}
// обрабатываем команды только если нашли log
if( cmdlog )
for( auto&& li: loglist )
{
// Обработка команд..
// \warning Работа с логом ведётся без mutex-а, хотя он разделяется отдельными потоками
switch( msg.cmd )
{
case LogServerTypes::cmdSetLevel:
cmdlog->level( (Debug::type)msg.data );
break;
li.log->level( (Debug::type)msg.data );
break;
case LogServerTypes::cmdAddLevel:
cmdlog->addLevel( (Debug::type)msg.data );
break;
li.log->addLevel( (Debug::type)msg.data );
break;
case LogServerTypes::cmdDelLevel:
cmdlog->delLevel( (Debug::type)msg.data );
break;
li.log->delLevel( (Debug::type)msg.data );
break;
case LogServerTypes::cmdRotate:
if( !logfile.empty() )
cmdlog->logFile(logfile, true);
break;
case LogServerTypes::cmdList:
{
if( isPending(Socket::pendingOutput, cmdTimeout) )
{
ostringstream s;
s << "List of managed logs:" << endl;
s << "=====================" << endl;
auto lag = dynamic_pointer_cast<LogAgregator>(log);
if( !lag )
{
s << log->getLogName() << endl;
}
else
{
auto lst = lag->getLogList();
for( const auto& i : lst )
s << i->getLogName() << endl;
}
s << "=====================" << endl;
*tcp() << s.str();
tcp()->sync();
}
if( !li.logfile.empty() )
li.log->logFile(li.logfile, true);
}
break;
case LogServerTypes::cmdList: // обработали выше (в начале)
break;
case LogServerTypes::cmdOffLogFile:
{
if( !logfile.empty() )
cmdlog->logFile("");
}
li.log->logFile("");
break;
case LogServerTypes::cmdOnLogFile:
{
if( !logfile.empty() )
cmdlog->logFile(logfile);
if( !li.logfile.empty() )
li.log->logFile(li.logfile);
}
break;
......
......@@ -94,6 +94,17 @@ TEST_CASE("LogAgregator", "[LogServer][LogAgregator]" )
log2->any() << test_msg2;
REQUIRE( la_msg.str() == test_msg2 );
auto lst = la->getLogList();
REQUIRE( lst.size() == 2 );
// Проверка поиска по регулярным выражениям
auto lst2 = la->getLogList("lo.*");
REQUIRE( lst2.size() == 2 );
auto lst3 = la->getLogList("log\\d{1}");
REQUIRE( lst3.size() == 2 );
}
// --------------------------------------------------------------------------
TEST_CASE("LogServer", "[LogServer]" )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment