Commit 9f043270 authored by Pavel Vainerman's avatar Pavel Vainerman

(LogAgregator): добавлена поддержка иерархии агрегаторов,

необоходимая для удобства использования LogServer. (uniset-log): сменил названия аргументов командной строки на более "логичные"
parent 3de2c879
...@@ -20,10 +20,10 @@ static struct option longopts[] = ...@@ -20,10 +20,10 @@ static struct option longopts[] =
{ "del", required_argument, 0, 'd' }, { "del", required_argument, 0, 'd' },
{ "set", required_argument, 0, 's' }, { "set", required_argument, 0, 's' },
{ "off", required_argument, 0, 'o' }, { "off", required_argument, 0, 'o' },
{ "on", required_argument, 0, 'n' }, { "on", required_argument, 0, 'e' },
{ "list", no_argument, 0, 'm' }, { "list", no_argument, 0, 'l' },
{ "rotate", required_argument, 0, 'r' }, { "rotate", required_argument, 0, 'r' },
{ "logname", required_argument, 0, 'l' }, { "logname", required_argument, 0, 'n' },
{ "command-only", no_argument, 0, 'b' }, { "command-only", no_argument, 0, 'b' },
{ "timeout", required_argument, 0, 'w' }, { "timeout", required_argument, 0, 'w' },
{ "reconnect-delay", required_argument, 0, 'x' }, { "reconnect-delay", required_argument, 0, 'x' },
...@@ -36,7 +36,7 @@ static void print_help() ...@@ -36,7 +36,7 @@ static void print_help()
printf("-v, --verbose - Print all messages to stdout\n"); printf("-v, --verbose - Print all messages to stdout\n");
printf("[-i|--iaddr] addr - LogServer ip or hostname.\n"); printf("[-i|--iaddr] addr - LogServer ip or hostname.\n");
printf("[-p|--port] port - LogServer port.\n"); printf("[-p|--port] port - LogServer port.\n");
printf("[-l|--logname] name - Send command only for 'logname'.\n"); printf("[-n|--logname] name - Send command only for 'logname'.\n");
printf("[-b|--command-only] - Send command and break. (No read logs).\n"); printf("[-b|--command-only] - Send command and break. (No read logs).\n");
printf("[-w|--timeout] msec - Timeout for wait data. Default: 0 - endless waiting\n"); printf("[-w|--timeout] msec - Timeout for wait data. Default: 0 - endless waiting\n");
printf("[-x|--reconnect-delay] msec - Pause for repeat connect to LogServer. Default: 5000 msec.\n"); printf("[-x|--reconnect-delay] msec - Pause for repeat connect to LogServer. Default: 5000 msec.\n");
...@@ -48,9 +48,9 @@ static void print_help() ...@@ -48,9 +48,9 @@ static void print_help()
printf("[--del | -d] info,warn,crit,... - Delete log levels.\n"); printf("[--del | -d] info,warn,crit,... - Delete log levels.\n");
printf("[--set | -s] info,warn,crit,... - Set log levels.\n"); printf("[--set | -s] info,warn,crit,... - Set log levels.\n");
printf("--off, -o - Off the write log file (if enabled).\n"); printf("--off, -o - Off the write log file (if enabled).\n");
printf("--on, -n - On the write log file (if before disabled).\n"); printf("--on, -e - On(enable) the write log file (if before disabled).\n");
printf("--rotate, -r - rotate log file.\n"); printf("--rotate, -r - rotate log file.\n");
printf("--list, -m - List of managed logs.\n"); printf("--list, -l - List of managed logs.\n");
} }
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
int main( int argc, char** argv ) int main( int argc, char** argv )
...@@ -73,7 +73,7 @@ int main( int argc, char** argv ) ...@@ -73,7 +73,7 @@ int main( int argc, char** argv )
try try
{ {
while( (opt = getopt_long(argc, argv, "hvma:p:i:d:s:l:onrbx:w:", longopts, &optindex)) != -1 ) while( (opt = getopt_long(argc, argv, "hvla:p:i:d:s:n:eorbx:w:", longopts, &optindex)) != -1 )
{ {
switch (opt) switch (opt)
{ {
...@@ -102,7 +102,7 @@ int main( int argc, char** argv ) ...@@ -102,7 +102,7 @@ int main( int argc, char** argv )
} }
break; break;
case 'm': case 'l':
cmd = LogServerTypes::cmdList; cmd = LogServerTypes::cmdList;
cmdonly = 1; cmdonly = 1;
break; break;
...@@ -111,7 +111,7 @@ int main( int argc, char** argv ) ...@@ -111,7 +111,7 @@ int main( int argc, char** argv )
cmd = LogServerTypes::cmdOffLogFile; cmd = LogServerTypes::cmdOffLogFile;
break; break;
case 'n': case 'e':
cmd = LogServerTypes::cmdOnLogFile; cmd = LogServerTypes::cmdOnLogFile;
break; break;
...@@ -123,7 +123,7 @@ int main( int argc, char** argv ) ...@@ -123,7 +123,7 @@ int main( int argc, char** argv )
addr = string(optarg); addr = string(optarg);
break; break;
case 'l': case 'n':
logname = string(optarg); logname = string(optarg);
break; break;
...@@ -171,7 +171,7 @@ int main( int argc, char** argv ) ...@@ -171,7 +171,7 @@ int main( int argc, char** argv )
data = (int)Debug::value(sdata); data = (int)Debug::value(sdata);
if( verb ) if( verb )
cout << "SEND COMMAND: '" << (LogServerTypes::Command)cmd << " data='" << sdata << "'" << endl; cout << "SEND COMMAND: '" << (LogServerTypes::Command)cmd << " data='" << sdata << "'(" << (int)data << ")" << endl;
} }
lr.readlogs( addr, port, (LogServerTypes::Command)cmd, data, logname, verb ); lr.readlogs( addr, port, (LogServerTypes::Command)cmd, data, logname, verb );
......
...@@ -91,13 +91,12 @@ int main( int argc, char** argv ) ...@@ -91,13 +91,12 @@ int main( int argc, char** argv )
// dlog.addLevel( Debug::type(Debug::CRIT | Debug::WARN | Debug::INFO) ); // dlog.addLevel( Debug::type(Debug::CRIT | Debug::WARN | Debug::INFO) );
} }
auto la = make_shared<LogAgregator>(); auto la = make_shared<LogAgregator>("la");
cerr << "create LogAgregator: " << la->getLogName() << endl;
auto dlog = make_shared<DebugStream>(); auto dlog = make_shared<DebugStream>();
dlog->setLogName("dlog"); dlog->setLogName("dlog");
la->add(dlog); la->add(dlog);
auto dlog2 = la->create("dlog2"); auto dlog2 = la->create("dlog2");
...@@ -115,11 +114,30 @@ int main( int argc, char** argv ) ...@@ -115,11 +114,30 @@ int main( int argc, char** argv )
} }
auto la2 = make_shared<LogAgregator>("la2");
cerr << "create LogAgregator: " << la2->getLogName() << endl;
auto dlog3 = la2->create("dlog3");
auto dlog4 = la2->create("dlog4");
la->add(la2);
if( la->getLog("la2/dlog3") == nullptr )
{
cerr << "Not found 'la2/dlog3'" << endl;
return 1;
}
LogServer ls(la); LogServer ls(la);
ls.setMaxSessionCount(msess); ls.setMaxSessionCount(msess);
dlog->addLevel(Debug::ANY); dlog->addLevel(Debug::ANY);
dlog2->addLevel(Debug::ANY); dlog2->addLevel(Debug::ANY);
dlog3->addLevel(Debug::ANY);
dlog4->addLevel(Debug::ANY);
ls.run( addr, port, true ); ls.run( addr, port, true );
...@@ -140,6 +158,14 @@ int main( int argc, char** argv ) ...@@ -140,6 +158,14 @@ int main( int argc, char** argv )
dlog2->warn() << ": dlog2: WARN message" << endl; dlog2->warn() << ": dlog2: WARN message" << endl;
dlog2->crit() << ": dlog2: CRIT message" << endl; dlog2->crit() << ": dlog2: CRIT message" << endl;
dlog3->info() << ": dlog3: INFO message" << endl;
dlog3->warn() << ": dlog3: WARN message" << endl;
dlog3->crit() << ": dlog3: CRIT message" << endl;
dlog4->info() << ": dlog4: INFO message" << endl;
dlog4->warn() << ": dlog4: WARN message" << endl;
dlog4->crit() << ": dlog4: CRIT message" << endl;
msleep(delay); msleep(delay);
} }
......
...@@ -171,48 +171,50 @@ ...@@ -171,48 +171,50 @@
virtual bool setMsg( UniSetTypes::ObjectId code, bool state = true ); virtual bool setMsg( UniSetTypes::ObjectId code, bool state = true );
std::shared_ptr&lt;DebugStream&gt; mylog; inline std::shared_ptr&lt;DebugStream&gt; log(){ return mylog; }
inline std::shared_ptr&lt;LogAgregator&gt; logAgregator(){ return loga; }
void init_dlog( std::shared_ptr&lt;DebugStream&gt; d ); void init_dlog( std::shared_ptr&lt;DebugStream&gt; d );
// "синтаксический сахар"..для логов // "синтаксический сахар"..для логов
#ifndef myinfo #ifndef myinfo
#define myinfo if( mylog->debugging(Debug::INFO) ) mylog->info() #define myinfo if( log()->debugging(Debug::INFO) ) log()->info()
#endif #endif
#ifndef mywarn #ifndef mywarn
#define mywarn if( mylog->debugging(Debug::WARN) ) mylog->warn() #define mywarn if( log()->debugging(Debug::WARN) ) log()->warn()
#endif #endif
#ifndef mycrit #ifndef mycrit
#define mycrit if( mylog->debugging(Debug::CRIT) ) mylog->crit() #define mycrit if( log()->debugging(Debug::CRIT) ) log()->crit()
#endif #endif
#ifndef mylog1 #ifndef mylog1
#define mylog1 if( mylog->debugging(Debug::LEVEL1) ) mylog->level1() #define mylog1 if( log()->debugging(Debug::LEVEL1) ) log()->level1()
#endif #endif
#ifndef mylog2 #ifndef mylog2
#define mylog2 if( mylog->debugging(Debug::LEVEL2) ) mylog->level2() #define mylog2 if( log()->debugging(Debug::LEVEL2) ) log()->level2()
#endif #endif
#ifndef mylog3 #ifndef mylog3
#define mylog3 if( mylog->debugging(Debug::LEVEL3) ) mylog->level3() #define mylog3 if( log()->debugging(Debug::LEVEL3) ) log()->level3()
#endif #endif
#ifndef mylog4 #ifndef mylog4
#define mylog4 if( mylog->debugging(Debug::LEVEL4) ) mylog->level4() #define mylog4 if( log()->debugging(Debug::LEVEL4) ) log()->level4()
#endif #endif
#ifndef mylog5 #ifndef mylog5
#define mylog5 if( mylog->debugging(Debug::LEVEL5) ) mylog->level5() #define mylog5 if( log()->debugging(Debug::LEVEL5) ) log()->level5()
#endif #endif
#ifndef mylog6 #ifndef mylog6
#define mylog6 if( mylog->debugging(Debug::LEVEL6) ) mylog->level6() #define mylog6 if( log()->debugging(Debug::LEVEL6) ) log()->level6()
#endif #endif
#ifndef mylog7 #ifndef mylog7
#define mylog7 if( mylog->debugging(Debug::LEVEL7) ) mylog->level7() #define mylog7 if( log()->debugging(Debug::LEVEL7) ) log()->level7()
#endif #endif
#ifndef mylog8 #ifndef mylog8
#define mylog8 if( mylog->debugging(Debug::LEVEL8) ) mylog->level8() #define mylog8 if( log()->debugging(Debug::LEVEL8) ) log()->level8()
#endif #endif
#ifndef mylog9 #ifndef mylog9
#define mylog9 if( mylog->debugging(Debug::LEVEL9) ) mylog->level9() #define mylog9 if( log()->debugging(Debug::LEVEL9) ) log()->level9()
#endif #endif
#ifndef mylogany #ifndef mylogany
#define mylogany mylog->any() #define mylogany log()->any()
#endif #endif
// Вспомогательные функции для удобства логирования // Вспомогательные функции для удобства логирования
...@@ -305,7 +307,7 @@ ...@@ -305,7 +307,7 @@
bool forceOut; /*!&lt; флаг принудительного обноления "выходов" */ bool forceOut; /*!&lt; флаг принудительного обноления "выходов" */
std::shared_ptr&lt;LogAgregator&gt; loga; std::shared_ptr&lt;LogAgregator&gt; loga;
std::shared_ptr&lt;DebugStream&gt; smlog; std::shared_ptr&lt;DebugStream&gt; mylog;
std::shared_ptr&lt;LogServer&gt; logserv; std::shared_ptr&lt;LogServer&gt; logserv;
std::string logserv_host = {""}; std::string logserv_host = {""};
int logserv_port = {0}; int logserv_port = {0};
...@@ -391,7 +393,7 @@ void <xsl:value-of select="$CLASSNAME"/>_SK::preSysCommand( const SystemMessage* ...@@ -391,7 +393,7 @@ void <xsl:value-of select="$CLASSNAME"/>_SK::preSysCommand( const SystemMessage*
{ {
// переоткрываем логи // переоткрываем логи
mylogany &lt;&lt; myname &lt;&lt; "(preSysCommand): logRotate" &lt;&lt; endl; mylogany &lt;&lt; myname &lt;&lt; "(preSysCommand): logRotate" &lt;&lt; endl;
string fname( mylog->getLogFile() ); string fname( log()->getLogFile() );
if( !fname.empty() ) if( !fname.empty() )
{ {
mylog->logFile(fname.c_str(),true); mylog->logFile(fname.c_str(),true);
...@@ -708,7 +710,7 @@ end_private(false) ...@@ -708,7 +710,7 @@ end_private(false)
conf->initLogStream(mylog,s.str()); conf->initLogStream(mylog,s.str());
} }
loga = make_shared&lt;LogAgregator&gt;(); loga = make_shared&lt;LogAgregator&gt;(myname+"-loga");
loga-&gt;add(mylog); loga-&gt;add(mylog);
loga-&gt;add(ulog()); loga-&gt;add(ulog());
...@@ -1099,7 +1101,7 @@ askPause(uniset_conf()->getPIntProp(cnode,"askPause",2000)) ...@@ -1099,7 +1101,7 @@ askPause(uniset_conf()->getPIntProp(cnode,"askPause",2000))
conf->initLogStream(mylog, s.str()); conf->initLogStream(mylog, s.str());
} }
loga = make_shared&lt;LogAgregator&gt;(); loga = make_shared&lt;LogAgregator&gt;(myname+"-loga");
loga-&gt;add(mylog); loga-&gt;add(mylog);
loga-&gt;add(ulog()); loga-&gt;add(ulog());
......
...@@ -38,6 +38,16 @@ void TestGen::sensorInfo( const SensorMessage* sm ) ...@@ -38,6 +38,16 @@ void TestGen::sensorInfo( const SensorMessage* sm )
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void TestGen::timerInfo( const TimerMessage* tm ) void TestGen::timerInfo( const TimerMessage* tm )
{ {
if( tm->id == 1 )
{
askTimer(1,0);
askTimer(2,3000);
}
else if( tm->id == 2 )
{
askTimer(1,2000);
askTimer(2,0);
}
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void TestGen::sigterm( int signo ) void TestGen::sigterm( int signo )
...@@ -45,3 +55,9 @@ void TestGen::sigterm( int signo ) ...@@ -45,3 +55,9 @@ void TestGen::sigterm( int signo )
TestGen_SK::sigterm(signo); TestGen_SK::sigterm(signo);
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void TestGen::sysCommand( const UniSetTypes::SystemMessage* sm )
{
if( sm->command == SystemMessage::StartUp )
askTimer(1,2000);
}
// -----------------------------------------------------------------------------
...@@ -11,13 +11,13 @@ class TestGen: ...@@ -11,13 +11,13 @@ class TestGen:
TestGen( UniSetTypes::ObjectId id, xmlNode* confnode = UniSetTypes::uniset_conf()->getNode("TestGen") ); TestGen( UniSetTypes::ObjectId id, xmlNode* confnode = UniSetTypes::uniset_conf()->getNode("TestGen") );
virtual ~TestGen(); virtual ~TestGen();
protected: protected:
TestGen(); TestGen();
virtual void step() override; virtual void step() override;
virtual void sensorInfo( const UniSetTypes::SensorMessage* sm ) override; virtual void sensorInfo( const UniSetTypes::SensorMessage* sm ) override;
virtual void timerInfo( const UniSetTypes::TimerMessage* tm ) override; virtual void timerInfo( const UniSetTypes::TimerMessage* tm ) override;
virtual void sysCommand( const UniSetTypes::SystemMessage* sm ) override;
virtual void sigterm( int signo ) override; virtual void sigterm( int signo ) override;
private: private:
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
Name: libuniset2 Name: libuniset2
Version: 2.1 Version: 2.1
Release: alt2 Release: alt3
Summary: UniSet - library for building distributed industrial control systems Summary: UniSet - library for building distributed industrial control systems
...@@ -455,6 +455,12 @@ mv -f %buildroot%python_sitelibdir_noarch/* %buildroot%python_sitelibdir/%oname ...@@ -455,6 +455,12 @@ mv -f %buildroot%python_sitelibdir_noarch/* %buildroot%python_sitelibdir/%oname
# .. # ..
%changelog %changelog
* Sun May 31 2015 Pavel Vainerman <pv@altlinux.ru> 2.1-alt3
- (LogAgregator):
- added support agregator hierarchy
- add docs
- add new tests
* Sat May 30 2015 Pavel Vainerman <pv@altlinux.ru> 2.1-alt2 * Sat May 30 2015 Pavel Vainerman <pv@altlinux.ru> 2.1-alt2
- (optimization): TransportMessage change format - (optimization): TransportMessage change format
- (uniset-codegen): minor fixes - (uniset-codegen): minor fixes
...@@ -470,7 +476,7 @@ mv -f %buildroot%python_sitelibdir_noarch/* %buildroot%python_sitelibdir/%oname ...@@ -470,7 +476,7 @@ mv -f %buildroot%python_sitelibdir_noarch/* %buildroot%python_sitelibdir/%oname
- minor fixes - minor fixes
* Sun May 24 2015 Pavel Vainerman <pv@altlinux.ru> 2.0-alt35 * Sun May 24 2015 Pavel Vainerman <pv@altlinux.ru> 2.0-alt35
- add supported LogServer for: - added support LogServer for:
SharedMemory,RRDServer,MBTCPMaster,MBSlave,UNetExchange,IOControl, SharedMemory,RRDServer,MBTCPMaster,MBSlave,UNetExchange,IOControl,
codegen,DBServer_xxx codegen,DBServer_xxx
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
ВСЕ ВАШИ ИЗМЕНЕНИЯ БУДУТ ПОТЕРЯНЫ. ВСЕ ВАШИ ИЗМЕНЕНИЯ БУДУТ ПОТЕРЯНЫ.
*/ */
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// generate timestamp: 2015-05-30+03:00 // generate timestamp: 2015-05-31+03:00
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
#ifndef UObject_SK_H_ #ifndef UObject_SK_H_
#define UObject_SK_H_ #define UObject_SK_H_
...@@ -28,7 +28,7 @@ class UObject_SK: ...@@ -28,7 +28,7 @@ class UObject_SK:
public LT_Object public LT_Object
{ {
public: public:
UObject_SK( UniSetTypes::ObjectId id, xmlNode* node = UniSetTypes::uniset_conf()->getNode("UObject"), const std::string& argprefix = "" ); UObject_SK( UniSetTypes::ObjectId id, xmlNode* node=UniSetTypes::uniset_conf()->getNode("UObject"), const std::string& argprefix="" );
UObject_SK(); UObject_SK();
virtual ~UObject_SK(); virtual ~UObject_SK();
...@@ -40,49 +40,51 @@ class UObject_SK: ...@@ -40,49 +40,51 @@ class UObject_SK:
virtual bool setMsg( UniSetTypes::ObjectId code, bool state = true ); virtual bool setMsg( UniSetTypes::ObjectId code, bool state = true );
std::shared_ptr<DebugStream> mylog; inline std::shared_ptr<DebugStream> log(){ return mylog; }
inline std::shared_ptr<LogAgregator> logAgregator(){ return loga; }
void init_dlog( std::shared_ptr<DebugStream> d ); void init_dlog( std::shared_ptr<DebugStream> d );
// "синтаксический сахар"..для логов // "синтаксический сахар"..для логов
#ifndef myinfo #ifndef myinfo
#define myinfo if( mylog->debugging(Debug::INFO) ) mylog->info() #define myinfo if( log()->debugging(Debug::INFO) ) log()->info()
#endif #endif
#ifndef mywarn #ifndef mywarn
#define mywarn if( mylog->debugging(Debug::WARN) ) mylog->warn() #define mywarn if( log()->debugging(Debug::WARN) ) log()->warn()
#endif #endif
#ifndef mycrit #ifndef mycrit
#define mycrit if( mylog->debugging(Debug::CRIT) ) mylog->crit() #define mycrit if( log()->debugging(Debug::CRIT) ) log()->crit()
#endif #endif
#ifndef mylog1 #ifndef mylog1
#define mylog1 if( mylog->debugging(Debug::LEVEL1) ) mylog->level1() #define mylog1 if( log()->debugging(Debug::LEVEL1) ) log()->level1()
#endif #endif
#ifndef mylog2 #ifndef mylog2
#define mylog2 if( mylog->debugging(Debug::LEVEL2) ) mylog->level2() #define mylog2 if( log()->debugging(Debug::LEVEL2) ) log()->level2()
#endif #endif
#ifndef mylog3 #ifndef mylog3
#define mylog3 if( mylog->debugging(Debug::LEVEL3) ) mylog->level3() #define mylog3 if( log()->debugging(Debug::LEVEL3) ) log()->level3()
#endif #endif
#ifndef mylog4 #ifndef mylog4
#define mylog4 if( mylog->debugging(Debug::LEVEL4) ) mylog->level4() #define mylog4 if( log()->debugging(Debug::LEVEL4) ) log()->level4()
#endif #endif
#ifndef mylog5 #ifndef mylog5
#define mylog5 if( mylog->debugging(Debug::LEVEL5) ) mylog->level5() #define mylog5 if( log()->debugging(Debug::LEVEL5) ) log()->level5()
#endif #endif
#ifndef mylog6 #ifndef mylog6
#define mylog6 if( mylog->debugging(Debug::LEVEL6) ) mylog->level6() #define mylog6 if( log()->debugging(Debug::LEVEL6) ) log()->level6()
#endif #endif
#ifndef mylog7 #ifndef mylog7
#define mylog7 if( mylog->debugging(Debug::LEVEL7) ) mylog->level7() #define mylog7 if( log()->debugging(Debug::LEVEL7) ) log()->level7()
#endif #endif
#ifndef mylog8 #ifndef mylog8
#define mylog8 if( mylog->debugging(Debug::LEVEL8) ) mylog->level8() #define mylog8 if( log()->debugging(Debug::LEVEL8) ) log()->level8()
#endif #endif
#ifndef mylog9 #ifndef mylog9
#define mylog9 if( mylog->debugging(Debug::LEVEL9) ) mylog->level9() #define mylog9 if( log()->debugging(Debug::LEVEL9) ) log()->level9()
#endif #endif
#ifndef mylogany #ifndef mylogany
#define mylogany mylog->any() #define mylogany log()->any()
#endif #endif
// Вспомогательные функции для удобства логирования // Вспомогательные функции для удобства логирования
// ------------------------------------------------------------ // ------------------------------------------------------------
...@@ -99,13 +101,13 @@ class UObject_SK: ...@@ -99,13 +101,13 @@ class UObject_SK:
\param id - идентификатор датчика \param id - идентификатор датчика
\param showLinkName - TRUE - выводить SensorName, FALSE - не выводить \param showLinkName - TRUE - выводить SensorName, FALSE - не выводить
*/ */
std::string str( UniSetTypes::ObjectId id, bool showLinkName = true ); std::string str( UniSetTypes::ObjectId id, bool showLinkName=true );
/*!< Вывод значения входа/выхода в формате: in_xxx(SensorName)=val /*!< Вывод значения входа/выхода в формате: in_xxx(SensorName)=val
\param id - идентификатор датчика \param id - идентификатор датчика
\param showLinkName - TRUE - выводить SensorName, FALSE - не выводить \param showLinkName - TRUE - выводить SensorName, FALSE - не выводить
*/ */
std::string strval( UniSetTypes::ObjectId id, bool showLinkName = true ); std::string strval( UniSetTypes::ObjectId id, bool showLinkName=true );
// ------------------------------------------------------------ // ------------------------------------------------------------
...@@ -133,10 +135,10 @@ class UObject_SK: ...@@ -133,10 +135,10 @@ class UObject_SK:
virtual void callback() override; virtual void callback() override;
virtual void processingMessage( UniSetTypes::VoidMessage* msg ) override; virtual void processingMessage( UniSetTypes::VoidMessage* msg ) override;
virtual void sysCommand( const UniSetTypes::SystemMessage* sm ) {}; virtual void sysCommand( const UniSetTypes::SystemMessage* sm ){};
virtual void askSensors( UniversalIO::UIOCommand cmd ) {} virtual void askSensors( UniversalIO::UIOCommand cmd ){}
virtual void sensorInfo( const UniSetTypes::SensorMessage* sm ) override {} virtual void sensorInfo( const UniSetTypes::SensorMessage* sm ) override{}
virtual void timerInfo( const UniSetTypes::TimerMessage* tm ) override {} virtual void timerInfo( const UniSetTypes::TimerMessage* tm ) override{}
virtual void sigterm( int signo ) override; virtual void sigterm( int signo ) override;
virtual bool activateObject() override; virtual bool activateObject() override;
virtual void testMode( bool state ); virtual void testMode( bool state );
...@@ -156,7 +158,7 @@ class UObject_SK: ...@@ -156,7 +158,7 @@ class UObject_SK:
int resetMsgTime; int resetMsgTime;
// Выполнение очередного шага программы // Выполнение очередного шага программы
virtual void step() {} virtual void step(){}
int sleep_msec; /*!< пауза между итерациями */ int sleep_msec; /*!< пауза между итерациями */
bool active; bool active;
...@@ -171,15 +173,9 @@ class UObject_SK: ...@@ -171,15 +173,9 @@ class UObject_SK:
xmlNode* confnode; xmlNode* confnode;
/*! получить числовое свойство из конф. файла по привязанной confnode */ /*! получить числовое свойство из конф. файла по привязанной confnode */
int getIntProp(const std::string& name) int getIntProp(const std::string& name) { return UniSetTypes::uniset_conf()->getIntProp(confnode, name); }
{
return UniSetTypes::uniset_conf()->getIntProp(confnode, name);
}
/*! получить текстовое свойство из конф. файла по привязанной confnode */ /*! получить текстовое свойство из конф. файла по привязанной confnode */
inline const std::string getProp(const std::string& name) inline const std::string getProp(const std::string& name) { return UniSetTypes::uniset_conf()->getProp(confnode, name); }
{
return UniSetTypes::uniset_conf()->getProp(confnode, name);
}
int smReadyTimeout; /*!< время ожидания готовности SM */ int smReadyTimeout; /*!< время ожидания готовности SM */
std::atomic_bool activated; std::atomic_bool activated;
...@@ -191,7 +187,7 @@ class UObject_SK: ...@@ -191,7 +187,7 @@ class UObject_SK:
bool forceOut; /*!< флаг принудительного обноления "выходов" */ bool forceOut; /*!< флаг принудительного обноления "выходов" */
std::shared_ptr<LogAgregator> loga; std::shared_ptr<LogAgregator> loga;
std::shared_ptr<DebugStream> smlog; std::shared_ptr<DebugStream> mylog;
std::shared_ptr<LogServer> logserv; std::shared_ptr<LogServer> logserv;
std::string logserv_host = {""}; std::string logserv_host = {""};
int logserv_port = {0}; int logserv_port = {0};
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
ВСЕ ВАШИ ИЗМЕНЕНИЯ БУДУТ ПОТЕРЯНЫ. ВСЕ ВАШИ ИЗМЕНЕНИЯ БУДУТ ПОТЕРЯНЫ.
*/ */
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// generate timestamp: 2015-05-30+03:00 // generate timestamp: 2015-05-31+03:00
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
#include <memory> #include <memory>
#include "Configuration.h" #include "Configuration.h"
...@@ -31,26 +31,26 @@ using namespace UniSetTypes; ...@@ -31,26 +31,26 @@ using namespace UniSetTypes;
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
UObject_SK::UObject_SK(): UObject_SK::UObject_SK():
// Инициализация идентификаторов (имена берутся из конф. файла) // Инициализация идентификаторов (имена берутся из конф. файла)
// Используемые идентификаторы сообщений (имена берутся из конф. файла) // Используемые идентификаторы сообщений (имена берутся из конф. файла)
// variables // variables
active(false), active(false),
idHeartBeat(DefaultObjectId), idHeartBeat(DefaultObjectId),
maxHeartBeat(10), maxHeartBeat(10),
confnode(0), confnode(0),
smReadyTimeout(0), smReadyTimeout(0),
activated(false), activated(false),
askPause(2000), askPause(2000),
forceOut(false), forceOut(false),
end_private(false) end_private(false)
{ {
ucrit << "UObject: init failed!!!!!!!!!!!!!!!" << endl; ucrit << "UObject: init failed!!!!!!!!!!!!!!!" << endl;
throw Exception( string(myname + ": init failed!!!") ); throw Exception( string(myname+": init failed!!!") );
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// ( val, confval, default val ) // ( val, confval, default val )
...@@ -58,7 +58,6 @@ static const std::string init3_str( const std::string& s1, const std::string& s2 ...@@ -58,7 +58,6 @@ static const std::string init3_str( const std::string& s1, const std::string& s2
{ {
if( !s1.empty() ) if( !s1.empty() )
return s1; return s1;
if( !s2.empty() ) if( !s2.empty() )
return s2; return s2;
...@@ -66,34 +65,34 @@ static const std::string init3_str( const std::string& s1, const std::string& s2 ...@@ -66,34 +65,34 @@ static const std::string init3_str( const std::string& s1, const std::string& s2
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
UObject_SK::UObject_SK( ObjectId id, xmlNode* cnode, const std::string& _argprefix ): UObject_SK::UObject_SK( ObjectId id, xmlNode* cnode, const std::string& _argprefix ):
UniSetObject(id), UniSetObject(id),
argprefix( (_argprefix.empty() ? myname + "-" : _argprefix) ), argprefix( (_argprefix.empty() ? myname+"-" : _argprefix) ),
// Инициализация идентификаторов (имена берутся из конф. файла) // Инициализация идентификаторов (имена берутся из конф. файла)
// Используемые идентификаторы сообщений (имена берутся из конф. файла) // Используемые идентификаторы сообщений (имена берутся из конф. файла)
// variables // variables
sleep_msec(150), sleep_msec(150),
active(true), active(true),
idHeartBeat(DefaultObjectId), idHeartBeat(DefaultObjectId),
maxHeartBeat(10), maxHeartBeat(10),
confnode(cnode), confnode(cnode),
smReadyTimeout(0), smReadyTimeout(0),
activated(false), activated(false),
askPause(uniset_conf()->getPIntProp(cnode, "askPause", 2000)), askPause(uniset_conf()->getPIntProp(cnode,"askPause",2000)),
forceOut(false), forceOut(false),
end_private(false) end_private(false)
{ {
auto conf = uniset_conf(); auto conf = uniset_conf();
if( UniSetTypes::findArgParam("--print-id-list", uniset_conf()->getArgc(), uniset_conf()->getArgv()) != -1 ) if( UniSetTypes::findArgParam("--print-id-list",uniset_conf()->getArgc(),uniset_conf()->getArgv()) != -1 )
{ {
// abort(); // abort();
} }
...@@ -109,10 +108,10 @@ UObject_SK::UObject_SK( ObjectId id, xmlNode* cnode, const std::string& _argpref ...@@ -109,10 +108,10 @@ UObject_SK::UObject_SK( ObjectId id, xmlNode* cnode, const std::string& _argpref
{ {
ostringstream s; ostringstream s;
s << argprefix << "log"; s << argprefix << "log";
conf->initLogStream(mylog, s.str()); conf->initLogStream(mylog,s.str());
} }
loga = make_shared<LogAgregator>(); loga = make_shared<LogAgregator>(myname+"-loga");
loga->add(mylog); loga->add(mylog);
loga->add(ulog()); loga->add(ulog());
...@@ -130,14 +129,12 @@ UObject_SK::UObject_SK( ObjectId id, xmlNode* cnode, const std::string& _argpref ...@@ -130,14 +129,12 @@ UObject_SK::UObject_SK( ObjectId id, xmlNode* cnode, const std::string& _argpref
logserv_port = conf->getArgPInt("--" + argprefix + "logserver-port", it.getProp("logserverPort"), getId()); logserv_port = conf->getArgPInt("--" + argprefix + "logserver-port", it.getProp("logserverPort"), getId());
} }
forceOut = conf->getArgPInt("--" + argprefix + "force-out", it.getProp("forceOut"), false); forceOut = conf->getArgPInt("--" + argprefix + "force-out",it.getProp("forceOut"),false);
string heart = conf->getArgParam("--" + argprefix + "heartbeat-id", it.getProp("heartbeat_id"));
string heart = conf->getArgParam("--" + argprefix + "heartbeat-id",it.getProp("heartbeat_id"));
if( !heart.empty() ) if( !heart.empty() )
{ {
idHeartBeat = conf->getSensorID(heart); idHeartBeat = conf->getSensorID(heart);
if( idHeartBeat == DefaultObjectId ) if( idHeartBeat == DefaultObjectId )
{ {
ostringstream err; ostringstream err;
...@@ -145,37 +142,34 @@ UObject_SK::UObject_SK( ObjectId id, xmlNode* cnode, const std::string& _argpref ...@@ -145,37 +142,34 @@ UObject_SK::UObject_SK( ObjectId id, xmlNode* cnode, const std::string& _argpref
throw SystemError(err.str()); throw SystemError(err.str());
} }
int heartbeatTime = conf->getArgPInt("--" + argprefix + "heartbeat-time", it.getProp("heartbeatTime"), conf->getHeartBeatTime()); int heartbeatTime = conf->getArgPInt("--" + argprefix + "heartbeat-time",it.getProp("heartbeatTime"),conf->getHeartBeatTime());
if( heartbeatTime>0 )
if( heartbeatTime > 0 )
ptHeartBeat.setTiming(heartbeatTime); ptHeartBeat.setTiming(heartbeatTime);
else else
ptHeartBeat.setTiming(UniSetTimer::WaitUpTime); ptHeartBeat.setTiming(UniSetTimer::WaitUpTime);
maxHeartBeat = conf->getArgPInt("--" + argprefix + "heartbeat-max", it.getProp("heartbeat_max"), 10); maxHeartBeat = conf->getArgPInt("--" + argprefix + "heartbeat-max",it.getProp("heartbeat_max"), 10);
} }
// Инициализация значений // Инициализация значений
sleep_msec = conf->getArgPInt("--" + argprefix + "sleep-msec", "150", 150); sleep_msec = conf->getArgPInt("--" + argprefix + "sleep-msec","150", 150);
string s_resetTime(""); string s_resetTime("");
if( s_resetTime.empty() ) if( s_resetTime.empty() )
s_resetTime = "500"; s_resetTime = "500";
resetMsgTime = uni_atoi(init3_str(conf->getArgParam("--" + argprefix + "resetMsgTime"), conf->getProp(cnode, "resetMsgTime"), s_resetTime)); resetMsgTime = uni_atoi(init3_str(conf->getArgParam("--" + argprefix + "resetMsgTime"),conf->getProp(cnode,"resetMsgTime"),s_resetTime));
ptResetMsg.setTiming(resetMsgTime); ptResetMsg.setTiming(resetMsgTime);
smReadyTimeout = conf->getArgInt("--" + argprefix + "sm-ready-timeout", ""); smReadyTimeout = conf->getArgInt("--" + argprefix + "sm-ready-timeout","");
if( smReadyTimeout == 0 ) if( smReadyTimeout == 0 )
smReadyTimeout = 60000; smReadyTimeout = 60000;
else if( smReadyTimeout < 0 ) else if( smReadyTimeout < 0 )
smReadyTimeout = UniSetTimer::WaitUpTime; smReadyTimeout = UniSetTimer::WaitUpTime;
smTestID = conf->getSensorID(init3_str(conf->getArgParam("--" + argprefix + "sm-test-id"), conf->getProp(cnode, "smTestID"), "")); smTestID = conf->getSensorID(init3_str(conf->getArgParam("--" + argprefix + "sm-test-id"),conf->getProp(cnode,"smTestID"),""));
activateTimeout = conf->getArgPInt("--" + argprefix + "activate-timeout", 20000); activateTimeout = conf->getArgPInt("--" + argprefix + "activate-timeout", 20000);
...@@ -232,7 +226,7 @@ bool UObject_SK::setMsg( UniSetTypes::ObjectId _code, bool _state ) ...@@ -232,7 +226,7 @@ bool UObject_SK::setMsg( UniSetTypes::ObjectId _code, bool _state )
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void UObject_SK::resetMsg() void UObject_SK::resetMsg()
{ {
// reset messages // reset messages
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
...@@ -310,13 +304,11 @@ void UObject_SK::preSysCommand( const SystemMessage* _sm ) ...@@ -310,13 +304,11 @@ void UObject_SK::preSysCommand( const SystemMessage* _sm )
{ {
case SystemMessage::WatchDog: case SystemMessage::WatchDog:
uinfo << myname << "(preSysCommand): WatchDog" << endl; uinfo << myname << "(preSysCommand): WatchDog" << endl;
if( !active || !ptStartUpTimeout.checkTime() ) if( !active || !ptStartUpTimeout.checkTime() )
{ {
uwarn << myname << "(preSysCommand): игнорируем WatchDog, потому-что только-что стартанули" << endl; uwarn << myname << "(preSysCommand): игнорируем WatchDog, потому-что только-что стартанули" << endl;
break; break;
} }
case SystemMessage::StartUp: case SystemMessage::StartUp:
{ {
if( !logserv_host.empty() && logserv_port != 0 && !logserv->isRunning() ) if( !logserv_host.empty() && logserv_port != 0 && !logserv->isRunning() )
...@@ -347,11 +339,10 @@ void UObject_SK::preSysCommand( const SystemMessage* _sm ) ...@@ -347,11 +339,10 @@ void UObject_SK::preSysCommand( const SystemMessage* _sm )
{ {
// переоткрываем логи // переоткрываем логи
mylogany << myname << "(preSysCommand): logRotate" << endl; mylogany << myname << "(preSysCommand): logRotate" << endl;
string fname( mylog->getLogFile() ); string fname( log()->getLogFile() );
if( !fname.empty() ) if( !fname.empty() )
{ {
mylog->logFile(fname.c_str(), true); mylog->logFile(fname.c_str(),true);
mylogany << myname << "(preSysCommand): ***************** mylog LOG ROTATE *****************" << endl; mylogany << myname << "(preSysCommand): ***************** mylog LOG ROTATE *****************" << endl;
} }
} }
...@@ -404,7 +395,7 @@ void UObject_SK::waitSM( int wait_msec, ObjectId _testID ) ...@@ -404,7 +395,7 @@ void UObject_SK::waitSM( int wait_msec, ObjectId _testID )
<< wait_msec << " msec" << wait_msec << " msec"
<< " testID=" << _testID << endl; << " testID=" << _testID << endl;
if( !ui->waitReady(_testID, wait_msec) ) if( !ui->waitReady(_testID,wait_msec) )
{ {
ostringstream err; ostringstream err;
err << myname err << myname
...@@ -412,11 +403,11 @@ void UObject_SK::waitSM( int wait_msec, ObjectId _testID ) ...@@ -412,11 +403,11 @@ void UObject_SK::waitSM( int wait_msec, ObjectId _testID )
<< wait_msec << " мсек"; << wait_msec << " мсек";
ucrit << err.str() << endl; ucrit << err.str() << endl;
// terminate(); // terminate();
// abort(); // abort();
raise(SIGTERM); raise(SIGTERM);
terminate(); terminate();
// throw SystemError(err.str()); // throw SystemError(err.str());
} }
...@@ -428,39 +419,37 @@ void UObject_SK::callback() ...@@ -428,39 +419,37 @@ void UObject_SK::callback()
{ {
if( !active ) if( !active )
return; return;
try try
{ {
// проверка таймеров // проверка таймеров
checkTimers(this); checkTimers(this);
if( resetMsgTime > 0 && trResetMsg.hi(ptResetMsg.checkTime()) ) if( resetMsgTime>0 && trResetMsg.hi(ptResetMsg.checkTime()) )
{ {
// cout << myname << ": ********* reset messages *********" << endl; // cout << myname << ": ********* reset messages *********" << endl;
resetMsg(); resetMsg();
} }
// обработка сообщений (таймеров и т.п.) // обработка сообщений (таймеров и т.п.)
for( unsigned int i = 0; i < 20; i++ ) for( unsigned int i=0; i<20; i++ )
{ {
if( !receiveMessage(msg) ) if( !receiveMessage(msg) )
break; break;
processingMessage(&msg); processingMessage(&msg);
updateOutputs(forceOut); updateOutputs(forceOut);
// updatePreviousValues(); // updatePreviousValues();
} }
// Выполнение шага программы // Выполнение шага программы
step(); step();
// "сердцебиение" // "сердцебиение"
if( idHeartBeat != DefaultObjectId && ptHeartBeat.checkTime() ) if( idHeartBeat!=DefaultObjectId && ptHeartBeat.checkTime() )
{ {
try try
{ {
ui->setValue(idHeartBeat, maxHeartBeat); ui->setValue(idHeartBeat,maxHeartBeat);
ptHeartBeat.reset(); ptHeartBeat.reset();
} }
catch( const Exception& ex ) catch( const Exception& ex )
...@@ -482,7 +471,7 @@ void UObject_SK::callback() ...@@ -482,7 +471,7 @@ void UObject_SK::callback()
ucrit << myname << "(execute): СORBA::SystemException: " ucrit << myname << "(execute): СORBA::SystemException: "
<< ex.NP_minorString() << endl; << ex.NP_minorString() << endl;
} }
catch( const std::exception& ex ) catch( const std::exception&ex )
{ {
ucrit << myname << "(execute): catch " << ex.what() << endl; ucrit << myname << "(execute): catch " << ex.what() << endl;
} }
...@@ -497,7 +486,7 @@ void UObject_SK::setValue( UniSetTypes::ObjectId _sid, long _val ) ...@@ -497,7 +486,7 @@ void UObject_SK::setValue( UniSetTypes::ObjectId _sid, long _val )
{ {
ui->setValue(_sid, _val); ui->setValue(_sid,_val);
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void UObject_SK::updateOutputs( bool _force ) void UObject_SK::updateOutputs( bool _force )
...@@ -514,7 +503,7 @@ void UObject_SK::preSensorInfo( const UniSetTypes::SensorMessage* _sm ) ...@@ -514,7 +503,7 @@ void UObject_SK::preSensorInfo( const UniSetTypes::SensorMessage* _sm )
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void UObject_SK::askSensor( UniSetTypes::ObjectId _sid, UniversalIO::UIOCommand _cmd, UniSetTypes::ObjectId _node ) void UObject_SK::askSensor( UniSetTypes::ObjectId _sid, UniversalIO::UIOCommand _cmd, UniSetTypes::ObjectId _node )
{ {
ui->askRemoteSensor(_sid, _cmd, _node, getId()); ui->askRemoteSensor(_sid,_cmd,_node,getId());
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
long UObject_SK::getValue( UniSetTypes::ObjectId _sid ) long UObject_SK::getValue( UniSetTypes::ObjectId _sid )
...@@ -536,12 +525,10 @@ long UObject_SK::getValue( UniSetTypes::ObjectId _sid ) ...@@ -536,12 +525,10 @@ long UObject_SK::getValue( UniSetTypes::ObjectId _sid )
void UObject_SK::preAskSensors( UniversalIO::UIOCommand _cmd ) void UObject_SK::preAskSensors( UniversalIO::UIOCommand _cmd )
{ {
PassiveTimer ptAct(activateTimeout); PassiveTimer ptAct(activateTimeout);
while( !activated && !ptAct.checkTime() ) while( !activated && !ptAct.checkTime() )
{ {
cout << myname << "(preAskSensors): wait activate..." << endl; cout << myname << "(preAskSensors): wait activate..." << endl;
msleep(300); msleep(300);
if( activated ) if( activated )
break; break;
} }
...@@ -561,7 +548,7 @@ void UObject_SK::preAskSensors( UniversalIO::UIOCommand _cmd ) ...@@ -561,7 +548,7 @@ void UObject_SK::preAskSensors( UniversalIO::UIOCommand _cmd )
{ {
ucrit << myname << "(preAskSensors): " << ex << endl; ucrit << myname << "(preAskSensors): " << ex << endl;
} }
catch( const std::exception& ex ) catch( const std::exception&ex )
{ {
ucrit << myname << "(execute): catch " << ex.what() << endl; ucrit << myname << "(execute): catch " << ex.what() << endl;
} }
......
...@@ -8,19 +8,120 @@ ...@@ -8,19 +8,120 @@
#include "DebugStream.h" #include "DebugStream.h"
#include "LogServerTypes.h" #include "LogServerTypes.h"
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
/*!
\page page_LogAgregator Агрегатор логов (LogAgregator)
- \ref sec_LogA_Comm
- \ref sec_LogA_Hierarchy
- \ref sec_LogA_Regexp
\section sec_LogA_Comm Общее описание
LogAgregator это класс предназначенный для объединения нескольких DebugStream
в один поток. При этом LogAgregator сам является DebugStream и обладает всеми его свойствами.
LogAgregator позволяет управлять каждым из своих логов в отдельности по имени лога.
\code
std::shared_ptr<DebugStream> dlog1 = std::make_shared<DebugStream>();
std::shared_ptr<DebugStream> dlog2 = std::make_shared<DebugStream>();
std::shared_ptr<DebugStream> la1 = make_shared<LogAgregator>("la1");
la1->add(dlog1,"dlog1");
la1->add(dlog1,"dlog2");
// Работа с логами через агрегатор
la1->addLevel("dlog1",Debug::INFO);
\endcode
Помимо этого при помощи агрегатора можно сразу создавать дочерние логи
\code
auto log10 = la1->create("dlog10");
log10->warn() << "WARNING MESSAGE" << endl;
\endcode
\section sec_LogA_Hierarchy Иерархия агрегаторов
Агрегатор позволяет строить иерархии из агрегаторов.
При добавлении дочернего агрегатора, все обращения к подчинённым логам другого агрегатора происходят
по имени включающим в себя имя дочернего агрегатора.
Пример:
\code
// Где-то в программе есть DebugStream (логи)
std::shared_ptr<DebugStream> dlog1 = std::make_shared<DebugStream>();
std::shared_ptr<DebugStream> dlog2 = std::make_shared<DebugStream>();
std::shared_ptr<DebugStream> dlog3 = std::make_shared<DebugStream>();
std::shared_ptr<DebugStream> dlog4 = std::make_shared<DebugStream>();
std::shared_ptr<LogAgregator> la1 = make_shared<LogAgregator>("la1");
la1->add(dlog1,"dlog1");
la1->add(dlog1,"dlog2");
// Работа с логами через агрегатор
la1->addLevel("dlog1",Debug::INFO);
..
// При этом можно выводить и напрямую в агрегатор
la1->info() << "INFO MESSAGE" << endl;
...
std::shared_ptr<LogAgregator> la2 = make_shared<LogAgregator>("la2");
la2->add(dlog1,"dlog3");
la2->add(dlog1,"dlog4");
// работа напрямую...
la2->addLevel("dlog4",Debug::WARN);
// Добавление второго агрегатора в первый..
la1->add(la2);
...
// теперь для обращения к логам второго агрегатора через первый..
// нужно добавлять его имя и разделитель "/" (LogAgregator::sep)
la1->addLevel("la2/dlog4",Debug::CRIT);
\endcode
\note Все эти свойства в полной мере используются при управлении логами через LogServer.
В обычной "жизни" агрегатор вряд ли особо нужен.
\section sec_LogA_Regexp Управление логами с использованием регулярных выражений
Агрегатор позволяет получать список подчинённых ему потоков (DebugStream) по именам удовлетворяющим
заданному регулярному выражению. Пример:
Предположим что иерархия подчинённых потоков выглядит следующим образом
\code
log1
log2
log3
loga2/log1
loga2/log2
loga2/loga3/log1
loga2/loga3/log2
loga2/loga3/log3
...
\endode
Для управления логами можно получить например список всех подчинённых потоков для loga3
\code
auto lst = la->getLogList(".*loga3.*");
for( auto&& l: lst )
{
..что-то делать..
}
\endcode
\note Полнота и формат поддерживаемых регулярных выражений зависит от поддержки компилятором стандарта с++11 (класс <regex>).
*/
// -------------------------------------------------------------------------
class LogAgregator: class LogAgregator:
public DebugStream public DebugStream
{ {
public: public:
explicit LogAgregator( Debug::type t = Debug::NONE ); const std::string sep={"/"}; /*< раздедитель для имён подчинённых агрегаторов */
explicit LogAgregator( char const* f, Debug::type t = Debug::NONE );
explicit LogAgregator( const std::string& name, Debug::type t );
explicit LogAgregator( const std::string& name="" );
virtual ~LogAgregator(); virtual ~LogAgregator();
virtual void logFile( const std::string& f, bool truncate = false ) override; virtual void logFile( const std::string& f, bool truncate = false ) override;
void add( std::shared_ptr<DebugStream> log ); void add( std::shared_ptr<LogAgregator> log, const std::string& lname="" );
void add( std::shared_ptr<DebugStream> log, const std::string& lname="" );
std::shared_ptr<DebugStream> create( const std::string& logname ); std::shared_ptr<DebugStream> create( const std::string& logname );
// Управление "подчинёнными" логами // Управление "подчинёнными" логами
...@@ -28,13 +129,21 @@ class LogAgregator: ...@@ -28,13 +129,21 @@ class LogAgregator:
void delLevel( const std::string& logname, Debug::type t ); void delLevel( const std::string& logname, Debug::type t );
void level( const std::string& logname, Debug::type t ); void level( const std::string& logname, Debug::type t );
struct LogInfo struct LogInfo
{ {
LogInfo(): log(0), logfile("") {} LogInfo(): log(0), logfile(""),logname("") {}
LogInfo( std::shared_ptr<DebugStream>& l ): log(l), logfile(l->getLogFile()) {} LogInfo( std::shared_ptr<DebugStream>& l, const std::string& lname="" ):
log(l), logfile(l->getLogFile()),logname(lname.empty()?l->getLogName():lname) {}
std::shared_ptr<DebugStream> log; std::shared_ptr<DebugStream> log;
std::string logfile; std::string logfile;
std::string logname;
// для сортировки "по алфавиту"
inline bool operator < ( const LogInfo& r ) const
{
return logname < r.logname;
}
}; };
std::shared_ptr<DebugStream> getLog( const std::string& logname ); std::shared_ptr<DebugStream> getLog( const std::string& logname );
...@@ -45,6 +154,8 @@ class LogAgregator: ...@@ -45,6 +154,8 @@ class LogAgregator:
protected: protected:
void logOnEvent( const std::string& s ); void logOnEvent( const std::string& s );
void addLog( std::shared_ptr<DebugStream> l, const std::string& lname );
void addLogAgregator( std::shared_ptr<LogAgregator> la, const std::string& lname );
private: private:
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
namespace LogServerTypes namespace LogServerTypes
{ {
const unsigned int MAGICNUM = 0x20140904; const unsigned int MAGICNUM = 0x20150531;
enum Command enum Command
{ {
cmdNOP, /*!< отсутствие команды */ cmdNOP, /*!< отсутствие команды */
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <mutex> #include <mutex>
#include "Mutex.h" #include "Mutex.h"
#include "DebugStream.h" #include "DebugStream.h"
#include "LogAgregator.h"
#include "PassiveTimer.h" #include "PassiveTimer.h"
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
/*! Реализация "сессии" для клиентов LogServer. */ /*! Реализация "сессии" для клиентов LogServer. */
...@@ -66,6 +67,7 @@ class LogSession: ...@@ -66,6 +67,7 @@ class LogSession:
std::string peername; std::string peername;
std::string caddr; std::string caddr;
std::shared_ptr<DebugStream> log; std::shared_ptr<DebugStream> log;
std::shared_ptr<LogAgregator> alog;
// PassiveTimer ptSessionTimeout; // PassiveTimer ptSessionTimeout;
FinalSlot slFin; FinalSlot slFin;
......
#include <memory> #include <memory>
#include <regex> #include <regex>
#include <sstream>
#include "DebugExtBuf.h" #include "DebugExtBuf.h"
#include "LogAgregator.h" #include "LogAgregator.h"
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
LogAgregator::LogAgregator( const std::string& name ):
LogAgregator(name,Debug::NONE)
{
}
// ------------------------------------------------------------------------
#if 0
LogAgregator::LogAgregator( char const* f, Debug::type t ): LogAgregator::LogAgregator( char const* f, Debug::type t ):
DebugStream(f, t) DebugStream(f, t)
{ {
delete rdbuf(new teebuf(&internal->fbuf, &internal->sbuf)); delete rdbuf(new teebuf(&internal->fbuf, &internal->sbuf));
} }
#endif
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
LogAgregator::LogAgregator( Debug::type t ): LogAgregator::LogAgregator( const std::string& name, Debug::type t ):
DebugStream(t) DebugStream(t)
{ {
setLogName(name);
delete rdbuf(new teebuf(&internal->nbuf, &internal->sbuf)); delete rdbuf(new teebuf(&internal->nbuf, &internal->sbuf));
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
...@@ -48,17 +57,73 @@ std::shared_ptr<DebugStream> LogAgregator::create( const std::string& logname ) ...@@ -48,17 +57,73 @@ std::shared_ptr<DebugStream> LogAgregator::create( const std::string& logname )
return l; return l;
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
void LogAgregator::add( std::shared_ptr<DebugStream> l ) void LogAgregator::add( std::shared_ptr<DebugStream> l, const std::string& lname )
{
auto lag = std::dynamic_pointer_cast<LogAgregator>(l);
if( lag )
addLogAgregator(lag, (lname.empty() ? l->getLogName(): lname) );
else
addLog(l,(lname.empty() ? l->getLogName(): lname));
}
// ------------------------------------------------------------------------
void LogAgregator::add( std::shared_ptr<LogAgregator> loga, const std::string& lname )
{
addLogAgregator(loga, (lname.empty() ? loga->getLogName(): lname) );
}
// -------------------------------------------------------------------------
void LogAgregator::addLogAgregator( std::shared_ptr<LogAgregator> la, const std::string& lname )
{
auto i = lmap.find(lname);
if( i != lmap.end() )
return;
auto lst = la->getLogList();
for( auto&& l: lst )
{
auto lag = std::dynamic_pointer_cast<LogAgregator>(l.log);
if( lag )
{
std::ostringstream s;
s << lname << sep << lag->getLogName();
addLogAgregator(lag,s.str()); // рекурсия..
}
else
{
std::ostringstream s;
s << lname << sep << l.log->getLogName();
addLog(l.log,s.str());
}
}
}
// ------------------------------------------------------------------------
void LogAgregator::addLog( std::shared_ptr<DebugStream> l, const std::string& lname )
{ {
auto i = lmap.find(l->getLogName()); auto i = lmap.find(lname);
if( i != lmap.end() ) if( i != lmap.end() )
return; return;
bool have = false;
// пока делаем "не оптимальный поиск" / пробегаем по всему списку, зато не храним дополнительный map /
// на то, чтобы не подключаться к одному логу дважды,
// иначе будет дублироваие при выводе потом (на экран)
for( const auto& i : lmap )
{
if( i.second.log == l )
{
have = true;
break;
}
}
if( !have )
l->signal_stream_event().connect( sigc::mem_fun(this, &LogAgregator::logOnEvent) ); l->signal_stream_event().connect( sigc::mem_fun(this, &LogAgregator::logOnEvent) );
lmap[l->getLogName()] = l;
LogInfo li(l,lname);
lmap[lname] = li;
} }
// ------------------------------------------------------------------------- // ------------------------------------------------------------------------
void LogAgregator::addLevel( const std::string& logname, Debug::type t ) void LogAgregator::addLevel( const std::string& logname, Debug::type t )
{ {
auto i = lmap.find(logname); auto i = lmap.find(logname);
...@@ -129,7 +194,8 @@ std::list<LogAgregator::LogInfo> LogAgregator::getLogList( const std::string& re ...@@ -129,7 +194,8 @@ std::list<LogAgregator::LogInfo> LogAgregator::getLogList( const std::string& re
for( auto && i : lmap ) for( auto && i : lmap )
{ {
if( std::regex_match(i.second.log->getLogName(), rule) ) //if( std::regex_match(i.second.log->getLogName(), rule) )
if( std::regex_match(i.first, rule) )
l.push_back(i.second); l.push_back(i.second);
} }
} }
......
...@@ -202,6 +202,7 @@ void LogReader::readlogs( const std::string& _addr, ost::tpport_t _port, LogServ ...@@ -202,6 +202,7 @@ void LogReader::readlogs( const std::string& _addr, ost::tpport_t _port, LogServ
{ {
tcp->read(buf, n); tcp->read(buf, n);
buf[n] = '\0'; buf[n] = '\0';
log << buf; log << buf;
if( msg.cmd == LogServerTypes::cmdList ) if( msg.cmd == LogServerTypes::cmdList )
......
...@@ -49,6 +49,10 @@ LogSession::LogSession( ost::TCPSocket& server, std::shared_ptr<DebugStream>& _l ...@@ -49,6 +49,10 @@ LogSession::LogSession( ost::TCPSocket& server, std::shared_ptr<DebugStream>& _l
log->signal_stream_event().connect( sigc::mem_fun(this, &LogSession::logOnEvent) ); log->signal_stream_event().connect( sigc::mem_fun(this, &LogSession::logOnEvent) );
else else
slog.crit() << "LOG NULL!!" << endl; slog.crit() << "LOG NULL!!" << endl;
auto ag = dynamic_pointer_cast<LogAgregator>(log);
if( ag )
alog = ag;
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
void LogSession::logOnEvent( const std::string& s ) void LogSession::logOnEvent( const std::string& s )
...@@ -109,14 +113,12 @@ void LogSession::run() ...@@ -109,14 +113,12 @@ void LogSession::run()
if( !cmdLogName.empty () ) if( !cmdLogName.empty () )
{ {
auto lag = dynamic_pointer_cast<LogAgregator>(log); if( alog ) // если у нас "агрегатор", то работаем с его списком потоков
if( lag )
{ {
if( cmdLogName == "ALL" ) if( cmdLogName == "ALL" )
loglist = lag->getLogList(); loglist = alog->getLogList();
else else
loglist = lag->getLogList(cmdLogName); loglist = alog->getLogList(cmdLogName);
} }
else else
{ {
...@@ -134,21 +136,25 @@ void LogSession::run() ...@@ -134,21 +136,25 @@ void LogSession::run()
ostringstream s; ostringstream s;
s << "List of managed logs:" << endl; s << "List of managed logs:" << endl;
s << "=====================" << endl; s << "=====================" << endl;
auto lag = dynamic_pointer_cast<LogAgregator>(log); if( !alog )
if( !lag )
{ {
s << log->getLogName() << endl; s << log->getLogName() << endl;
} }
else else
{ {
auto lst = lag->getLogList(); std::list<LogAgregator::LogInfo> lst;
if( cmdLogName.empty() || cmdLogName == "ALL" )
lst = alog->getLogList();
else
lst = alog->getLogList(cmdLogName);
// красиво отсортируем сперва..
lst.sort([](const LogAgregator::LogInfo & a, const LogAgregator::LogInfo & b) { return a.logname < b.logname; });
for( const auto& i : lst ) for( const auto& i : lst )
s << i.log->getLogName() << endl; s << i.logname << endl;
} }
s << "=====================" << endl << endl;
s << "=====================" << endl;
if( isPending(Socket::pendingOutput, cmdTimeout) ) if( isPending(Socket::pendingOutput, cmdTimeout) )
{ {
...@@ -158,7 +164,7 @@ void LogSession::run() ...@@ -158,7 +164,7 @@ void LogSession::run()
} }
} }
// обрабатываем команды только если нашли log // обрабатываем команды только если нашли подходящие логи
for( auto && li : loglist ) for( auto && li : loglist )
{ {
// Обработка команд.. // Обработка команд..
......
...@@ -243,3 +243,25 @@ TEST_CASE("MaxSessions", "[LogServer]" ) ...@@ -243,3 +243,25 @@ TEST_CASE("MaxSessions", "[LogServer]" )
r2_thr->join(); r2_thr->join();
} }
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
TEST_CASE("Logagregator regexp", "[LogAgregator]" )
{
auto la = make_shared<LogAgregator>();
auto log1 = la->create("log1");
auto log2 = la->create("log2");
auto log3 = la->create("a3/log1");
auto log4 = la->create("a3/log2");
auto log5 = la->create("a3/log3");
auto log6 = la->create("a3/a4/log1");
auto log7 = la->create("a3/a4/log2");
auto lst = la->getLogList(".*/a4/.*");
REQUIRE( lst.size() == 2 );
lst = la->getLogList("a3/.*");
REQUIRE( lst.size() == 5 );
lst = la->getLogList(".*log1.*");
REQUIRE( lst.size() == 3 );
}
// --------------------------------------------------------------------------
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