Commit 5b906cdc authored by Pavel Vainerman's avatar Pavel Vainerman

(VMonitor): добавлена реализация механизма (удалённого) отслеживания внутреннего…

(VMonitor): добавлена реализация механизма (удалённого) отслеживания внутреннего состояния переменных
parent 085e4d60
...@@ -51,6 +51,7 @@ SQL: ...@@ -51,6 +51,7 @@ SQL:
Debug: Debug:
- в codegen встроить получение состояния всех переменных (dumpIO() + UniSetObject::getInfo()), - в codegen встроить получение состояния всех переменных (dumpIO() + UniSetObject::getInfo()),
возможно написать на python утилиту "монитор". возможно написать на python утилиту "монитор".
- Сделать макрос с простым названием например NOTE(variable)(snap?)... пишуший в map var=value, а потом показывающий в getInfo() (и может dumpIO())
- дописать в codegen документацию по запуску и управлению логами через LogServer - дописать в codegen документацию по запуску и управлению логами через LogServer
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
# This file is part of the UniSet library # # This file is part of the UniSet library #
############################################################################ ############################################################################
bin_SCRIPTS = @PACKAGE@-vmonit
bin_PROGRAMS = @PACKAGE@-admin bin_PROGRAMS = @PACKAGE@-admin
@PACKAGE@_admin_SOURCES = admin.cc @PACKAGE@_admin_SOURCES = admin.cc
@PACKAGE@_admin_LDADD = $(top_builddir)/lib/libUniSet2.la @PACKAGE@_admin_LDADD = $(top_builddir)/lib/libUniSet2.la
......
...@@ -106,14 +106,14 @@ static void usage() ...@@ -106,14 +106,14 @@ static void usage()
cout << endl; cout << endl;
print_help(36, "-r|--configure [FullObjName] ", "Посылка SystemMessage::ReConfiguration всем объектам (процессам) или заданному по имени (FullObjName).\n"); print_help(36, "-r|--configure [FullObjName] ", "Посылка SystemMessage::ReConfiguration всем объектам (процессам) или заданному по имени (FullObjName).\n");
print_help(36, "-l|--logrotate [FullObjName] ", "Посылка SystemMessage::LogRotate всем объектам (процессам) или заданному по имени (FullObjName).\n"); print_help(36, "-l|--logrotate [FullObjName] ", "Посылка SystemMessage::LogRotate всем объектам (процессам) или заданному по имени (FullObjName).\n");
print_help(36, "-p|--oinfo OID ", "Получить информацию об объекте (SimpleInfo).\n"); print_help(36, "-p|--oinfo id1@node1,id2@node2,id3,...", "Получить информацию об объектах (SimpleInfo).\n");
cout << endl; cout << endl;
print_help(48, "-x|--setValue id1@node1=val,id2@node2=val2,id3=val3,.. ", "Выставить значения датчиков\n"); print_help(48, "-x|--setValue id1@node1=val,id2@node2=val2,id3=val3,.. ", "Выставить значения датчиков\n");
print_help(36, "-g|--getValue id1@node1,id2@node2,id3,id4 ", "Получить значения датчиков.\n"); print_help(36, "-g|--getValue id1@node1,id2@node2,id3,id4 ", "Получить значения датчиков.\n");
cout << endl; cout << endl;
print_help(36, "-w|--getRawValue id1@node1=val,id2@node2=val2,id3=val3,.. ", "Получить 'сырое' значение.\n"); print_help(36, "-w|--getRawValue id1@node1,id2@node2,id3,.. ", "Получить 'сырое' значение.\n");
print_help(36, "-y|--getCalibrate id1@node1=val,id2@node2=val2,id3=val3,.. ", "Получить параметры калибровки.\n"); print_help(36, "-y|--getCalibrate id1@node1,id2@node2,id3,.. ", "Получить параметры калибровки.\n");
print_help(36, "-t|--getChangedTime id1@node1=val,id2@node2=val2,id3=val3,.. ", "Получить время последнего изменения.\n"); print_help(36, "-t|--getChangedTime id1@node1,id2@node2,id3,.. ", "Получить время последнего изменения.\n");
print_help(36, "-v|--verbose", "Подробный вывод логов.\n"); print_help(36, "-v|--verbose", "Подробный вывод логов.\n");
print_help(36, "-q|--quiet", "Выводит только результат.\n"); print_help(36, "-q|--quiet", "Выводит только результат.\n");
cout << endl; cout << endl;
...@@ -442,9 +442,9 @@ static bool commandToAll(const string& section, std::shared_ptr<ObjectRepository ...@@ -442,9 +442,9 @@ static bool commandToAll(const string& section, std::shared_ptr<ObjectRepository
case Exist: case Exist:
{ {
if( obj->exist() ) if( obj->exist() )
cout << setw(55) << ob << " <--- exist ok\n"; cout << "(" << setw(6) << obj->getId() << ")" << setw(55) << ob << " <--- exist ok\n";
else else
cout << setw(55) << ob << " <--- exist NOT OK\n"; cout << "(" << setw(6) << obj->getId() << ")" << setw(55) << ob << " <--- exist NOT OK\n";
} }
break; break;
...@@ -840,30 +840,38 @@ int configure( const string& arg, UInterface& ui ) ...@@ -840,30 +840,38 @@ int configure( const string& arg, UInterface& ui )
} }
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
int oinfo( const string& arg, UInterface& ui ) int oinfo( const string& args, UInterface& ui )
{ {
UniSetTypes::ObjectId oid(uni_atoi(arg)); auto conf = uniset_conf();
auto sl = UniSetTypes::getSInfoList( args, conf );
if( oid == 0 ) for( auto&& it : sl )
{ {
if( !quiet ) if( it.si.node == DefaultObjectId )
cout << "(oinfo): Не задан OID!" << endl; it.si.node = conf->getLocalNode();
return 1; try
} {
UniSetTypes::ObjectVar o = ui.resolve(it.si.id,it.si.node);
UniSetObject_i_var obj = UniSetObject_i::_narrow(o);
UniSetTypes::ObjectVar o = ui.resolve(oid); if(CORBA::is_nil(obj))
UniSetObject_i_var obj = UniSetObject_i::_narrow(o); {
if( !quiet )
cout << "(oinfo): объект '" << it.si.id << "' недоступен" << endl;
}
else
{
SimpleInfo_var inf = obj->getInfo();
cout << inf->info << endl;
}
}
catch( const Exception& ex )
{
cout << "ID='" << it.si.id << "' ERROR: " << ex << endl;
}
if(CORBA::is_nil(obj)) cout << endl << endl;
{
if( !quiet )
cout << "(oinfo): объект " << oid << " недоступен" << endl;
}
else
{
SimpleInfo_var inf = obj->getInfo();
cout << inf->info << endl;
} }
return 0; return 0;
......
#!/bin/sh
WATCH=/usr/bin/watch
[ -z $WATCH_SEC ] && WATCH_SEC=5
if [ ! -e $WATCH ]; then
echo "SORRY: $WATCH not found!!"
exit 1
fi
print_usage()
{
[ "$1" = 0 ] || exec >&2
echo "Usage: ${0##*/} [-s watch_sec] ObjectID1[@node],ObjectID2,.."
# echo ""
# uniset2-admin --help
[ -n "$1" ] && exit "$1" || exit
}
[ -z "$1" ] && print_usage 1
#parse command line options
case "$1" in
-h|--help) print_usage 0;;
-s|--sec) shift; WATCH_SEC=$1; shift;;
esac
OID=$1
shift
$WATCH -n $WATCH_SEC uniset2-admin --oinfo ${OID} $*
\ No newline at end of file
...@@ -218,10 +218,13 @@ ...@@ -218,10 +218,13 @@
#ifndef mylogany #ifndef mylogany
#define mylogany log()->any() #define mylogany log()->any()
#endif #endif
#ifndef vmonit
#define vmonit( var ) vmon.add( #var, var )
#endif
// Вспомогательные функции для удобства логирования // Вспомогательные функции для удобства логирования
// ------------------------------------------------------------ // ------------------------------------------------------------
/*!&lt; вывод в строку значение всех входов и выходов в формате /*! вывод в строку значение всех входов и выходов в формате
ObjectName: ObjectName:
in_xxx = val in_xxx = val
in_xxx2 = val in_xxx2 = val
...@@ -230,17 +233,20 @@ ...@@ -230,17 +233,20 @@
*/ */
std::string dumpIO(); std::string dumpIO();
/*!&lt; Вывод в строку названия входа/выхода в формате: in_xxx(SensorName) /*! Вывод в строку названия входа/выхода в формате: in_xxx(SensorName)
\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 );
/*!&lt; Вывод значения входа/выхода в формате: 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 );
/*! Вывод состояния внутренних переменных */
inline std::string dumpVars(){ return std::move(vmon.pretty_str()); }
// ------------------------------------------------------------ // ------------------------------------------------------------
</xsl:template> </xsl:template>
...@@ -313,6 +319,11 @@ ...@@ -313,6 +319,11 @@
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};
// snap
bool no_snap = {false};
VMonitor vmon;
</xsl:template> </xsl:template>
<xsl:template name="COMMON-HEAD-PRIVATE"> <xsl:template name="COMMON-HEAD-PRIVATE">
...@@ -420,6 +431,7 @@ UniSetTypes::SimpleInfo* <xsl:value-of select="$CLASSNAME"/>_SK::getInfo() ...@@ -420,6 +431,7 @@ UniSetTypes::SimpleInfo* <xsl:value-of select="$CLASSNAME"/>_SK::getInfo()
inf &lt;&lt; i->info &lt;&lt; endl; inf &lt;&lt; i->info &lt;&lt; endl;
inf &lt;&lt; dumpIO() &lt;&lt; endl; inf &lt;&lt; dumpIO() &lt;&lt; endl;
inf &lt;&lt; vmon.pretty_str() &lt;&lt; endl;
i->info = inf.str().c_str(); i->info = inf.str().c_str();
...@@ -997,6 +1009,7 @@ std::string <xsl:value-of select="$CLASSNAME"/>_SK::dumpIO() ...@@ -997,6 +1009,7 @@ std::string <xsl:value-of select="$CLASSNAME"/>_SK::dumpIO()
&lt;&lt; std::right &lt;&lt; " = " &lt;&lt; setw(6) &lt;&lt; <xsl:call-template name="setprefix"/><xsl:value-of select="@name"/> &lt;&lt; std::right &lt;&lt; " = " &lt;&lt; setw(6) &lt;&lt; <xsl:call-template name="setprefix"/><xsl:value-of select="@name"/>
&lt;&lt; endl; &lt;&lt; endl;
</xsl:for-each> </xsl:for-each>
return s.str(); return s.str();
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
......
...@@ -38,6 +38,9 @@ ...@@ -38,6 +38,9 @@
#define <xsl:value-of select="$CLASSNAME"/>_SK_H_ #define <xsl:value-of select="$CLASSNAME"/>_SK_H_
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
#include &lt;memory&gt; #include &lt;memory&gt;
#include &lt;string&gt;
#include &lt;sstream&gt;
#include &lt;unordered_map&gt;
<xsl:if test="normalize-space($BASECLASS)!=''">#include <xsl:call-template name="preinclude"/><xsl:value-of select="normalize-space($BASECLASS)"/>.h<xsl:call-template name="postinclude"/></xsl:if> <xsl:if test="normalize-space($BASECLASS)!=''">#include <xsl:call-template name="preinclude"/><xsl:value-of select="normalize-space($BASECLASS)"/>.h<xsl:call-template name="postinclude"/></xsl:if>
<xsl:if test="normalize-space($BASECLASS)=''">#include <xsl:call-template name="preinclude"/>UniSetObject.h<xsl:call-template name="postinclude"/></xsl:if> <xsl:if test="normalize-space($BASECLASS)=''">#include <xsl:call-template name="preinclude"/>UniSetObject.h<xsl:call-template name="postinclude"/></xsl:if>
#include <xsl:call-template name="preinclude"/>LT_Object.h<xsl:call-template name="postinclude"/> #include <xsl:call-template name="preinclude"/>LT_Object.h<xsl:call-template name="postinclude"/>
...@@ -47,6 +50,7 @@ ...@@ -47,6 +50,7 @@
#include <xsl:call-template name="preinclude"/>LogServer.h<xsl:call-template name="postinclude"/> #include <xsl:call-template name="preinclude"/>LogServer.h<xsl:call-template name="postinclude"/>
#include <xsl:call-template name="preinclude"/>DebugStream.h<xsl:call-template name="postinclude"/> #include <xsl:call-template name="preinclude"/>DebugStream.h<xsl:call-template name="postinclude"/>
#include <xsl:call-template name="preinclude"/>LogAgregator.h<xsl:call-template name="postinclude"/> #include <xsl:call-template name="preinclude"/>LogAgregator.h<xsl:call-template name="postinclude"/>
#include <xsl:call-template name="preinclude"/>VMonitor.h<xsl:call-template name="postinclude"/>
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
class <xsl:value-of select="$CLASSNAME"/>_SK: class <xsl:value-of select="$CLASSNAME"/>_SK:
<xsl:if test="normalize-space($BASECLASS)!=''">public <xsl:value-of select="normalize-space($BASECLASS)"/>,</xsl:if> <xsl:if test="normalize-space($BASECLASS)!=''">public <xsl:value-of select="normalize-space($BASECLASS)"/>,</xsl:if>
......
...@@ -39,6 +39,8 @@ ...@@ -39,6 +39,8 @@
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
#include &lt;memory&gt; #include &lt;memory&gt;
#include &lt;string&gt; #include &lt;string&gt;
#include &lt;unordered_map&gt;
#include &lt;sstream&gt;
<xsl:if test="normalize-space($BASECLASS)!=''">#include <xsl:call-template name="preinclude"/><xsl:value-of select="normalize-space($BASECLASS)"/>.h<xsl:call-template name="postinclude"/></xsl:if> <xsl:if test="normalize-space($BASECLASS)!=''">#include <xsl:call-template name="preinclude"/><xsl:value-of select="normalize-space($BASECLASS)"/>.h<xsl:call-template name="postinclude"/></xsl:if>
<xsl:if test="normalize-space($BASECLASS)=''">#include <xsl:call-template name="preinclude"/>UniSetObject.h<xsl:call-template name="postinclude"/></xsl:if> <xsl:if test="normalize-space($BASECLASS)=''">#include <xsl:call-template name="preinclude"/>UniSetObject.h<xsl:call-template name="postinclude"/></xsl:if>
#include <xsl:call-template name="preinclude"/>LT_Object.h<xsl:call-template name="postinclude"/> #include <xsl:call-template name="preinclude"/>LT_Object.h<xsl:call-template name="postinclude"/>
...@@ -47,6 +49,7 @@ ...@@ -47,6 +49,7 @@
#include <xsl:call-template name="preinclude"/>DebugStream.h<xsl:call-template name="postinclude"/> #include <xsl:call-template name="preinclude"/>DebugStream.h<xsl:call-template name="postinclude"/>
#include <xsl:call-template name="preinclude"/>LogServer.h<xsl:call-template name="postinclude"/> #include <xsl:call-template name="preinclude"/>LogServer.h<xsl:call-template name="postinclude"/>
#include <xsl:call-template name="preinclude"/>LogAgregator.h<xsl:call-template name="postinclude"/> #include <xsl:call-template name="preinclude"/>LogAgregator.h<xsl:call-template name="postinclude"/>
#include <xsl:call-template name="preinclude"/>VMonitor.h<xsl:call-template name="postinclude"/>
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
class <xsl:value-of select="$CLASSNAME"/>_SK: class <xsl:value-of select="$CLASSNAME"/>_SK:
<xsl:if test="normalize-space($BASECLASS)!=''">public <xsl:value-of select="normalize-space($BASECLASS)"/>,</xsl:if> <xsl:if test="normalize-space($BASECLASS)!=''">public <xsl:value-of select="normalize-space($BASECLASS)"/>,</xsl:if>
......
...@@ -7,6 +7,8 @@ using namespace UniSetTypes; ...@@ -7,6 +7,8 @@ using namespace UniSetTypes;
TestGen::TestGen( UniSetTypes::ObjectId id, xmlNode* confnode ): TestGen::TestGen( UniSetTypes::ObjectId id, xmlNode* confnode ):
TestGen_SK( id, confnode ) TestGen_SK( id, confnode )
{ {
vmonit(int_var);
vmonit(bool_var);
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
TestGen::~TestGen() TestGen::~TestGen()
...@@ -28,6 +30,12 @@ void TestGen::step() ...@@ -28,6 +30,12 @@ void TestGen::step()
myinfo << str(input2_s) << endl; myinfo << str(input2_s) << endl;
ulog()->info() << "ulog: " << str(input2_s) << endl; ulog()->info() << "ulog: " << str(input2_s) << endl;
int_var++;
bool_var^=true;
cout << vmon << endl;
// cout << vmon.pretty_str() << endl;
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void TestGen::sensorInfo( const SensorMessage* sm ) void TestGen::sensorInfo( const SensorMessage* sm )
......
...@@ -21,6 +21,8 @@ class TestGen: ...@@ -21,6 +21,8 @@ class TestGen:
virtual void sigterm( int signo ) override; virtual void sigterm( int signo ) override;
private: private:
bool bool_var = { false };
int int_var = {0};
}; };
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
#endif // TestGen_H_ #endif // TestGen_H_
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
Name: libuniset2 Name: libuniset2
Version: 2.1 Version: 2.1
Release: alt7 Release: alt7.1
Summary: UniSet - library for building distributed industrial control systems Summary: UniSet - library for building distributed industrial control systems
...@@ -288,6 +288,7 @@ mv -f %buildroot%python_sitelibdir_noarch/* %buildroot%python_sitelibdir/%oname ...@@ -288,6 +288,7 @@ mv -f %buildroot%python_sitelibdir_noarch/* %buildroot%python_sitelibdir/%oname
%_bindir/%oname-nullController %_bindir/%oname-nullController
%_bindir/%oname-sviewer-text %_bindir/%oname-sviewer-text
%_bindir/%oname-smonit %_bindir/%oname-smonit
%_bindir/%oname-vmonit
%_bindir/%oname-simitator %_bindir/%oname-simitator
%_bindir/%oname-log %_bindir/%oname-log
%_bindir/%oname-logserver-wrap %_bindir/%oname-logserver-wrap
...@@ -455,12 +456,16 @@ mv -f %buildroot%python_sitelibdir_noarch/* %buildroot%python_sitelibdir/%oname ...@@ -455,12 +456,16 @@ mv -f %buildroot%python_sitelibdir_noarch/* %buildroot%python_sitelibdir/%oname
# .. # ..
%changelog %changelog
* Sat Jun 06 2015 Pavel Vainerman <pv@altlinux.ru> 2.1-alt7.1
- (vmonit): new utilities (variables monitor)
* Fri Jun 05 2015 Pavel Vainerman <pv@altlinux.ru> 2.1-alt7 * Fri Jun 05 2015 Pavel Vainerman <pv@altlinux.ru> 2.1-alt7
- (ModbusSlave): fixed bug in read0x function (for float and precision) - (ModbusSlave): fixed bug in read0x function (for float and precision)
* Thu Jun 04 2015 Pavel Vainerman <pv@altlinux.ru> 2.1-alt6 * Thu Jun 04 2015 Pavel Vainerman <pv@altlinux.ru> 2.1-alt6
- (smonit): print supplier, change print format - (smonit): print supplier, change print format
- (admin): add getChangedTime function - (admin): add getChangedTime function
- (codegen): reuse getInfo() function (internal variables monitor)
* Tue Jun 02 2015 Pavel Vainerman <pv@altlinux.ru> 2.1-alt5 * Tue Jun 02 2015 Pavel Vainerman <pv@altlinux.ru> 2.1-alt5
- (LogServer): refactoring - (LogServer): refactoring
......
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
- \ref pg_Codegen_Templ_Alone - \ref pg_Codegen_Templ_Alone
- \ref pg_Codegen_log - \ref pg_Codegen_log
- \ref pg_Codegen_loglevel - \ref pg_Codegen_loglevel
- \ref pg_Codegen_logserver
- \ref pg_Codegen_vmonitor
\section pg_Codegen_Common Общее описание утилиты uniset-codegen \section pg_Codegen_Common Общее описание утилиты uniset-codegen
Утилита uniset-codegen предназначена для генерирования "скелета" процесса управления на основе Утилита uniset-codegen предназначена для генерирования "скелета" процесса управления на основе
...@@ -400,4 +402,88 @@ MyClass_SK.cc: myclass.src.xml ...@@ -400,4 +402,88 @@ MyClass_SK.cc: myclass.src.xml
4117 4117
\endcode \endcode
Т.е. для того, чтобы включить указанные логи в датчик нужно записать число \b 4117 Т.е. для того, чтобы включить указанные логи в датчик нужно записать число \b 4117
\section pg_Codegen_logserver Удалённое управление логами
Для возможности удалённого управления логами (включением, отключением, просмотром, и т.п.) в каждом объекте
предусмотрена возможность запуска LogServer, который \b запускается на порту \b равном \b ID-объекта.
По умолчанию LogServer не запускается (выключен). Для его запуска необходимо указать:
\code
--argprefix-run-logserver
\endcode
Дополнительно доступны следующие аргументы:
\code
--argprefix-logserver-host - по умолчанию localhost
--argprefix-logserver-port - по умолчанию ID-объекта
\endcode
Непосредственно управление логами производиться при помощи утилиты \b uniset2-log
\code
-h, --help - this message
-v, --verbose - Print all messages to stdout
[-i|--iaddr] addr - LogServer ip or hostname.
[-p|--port] port - LogServer port.
[-c|--command-only] - Send command and break. (No read logs).
[-w|--timeout] msec - Timeout for wait data. Default: 0 - endless waiting
[-x|--reconnect-delay] msec - Pause for repeat connect to LogServer. Default: 5000 msec.
Commands:
[--add | -a] info,warn,crit,... [logfilter] - Add log levels.
[--del | -d] info,warn,crit,... [logfilter] - Delete log levels.
[--set | -s] info,warn,crit,... [logfilter] - Set log levels.
--off, -o [logfilter] - Off the write log file (if enabled).
--on, -e [logfilter] - On(enable) the write log file (if before disabled).
--rotate, -r [logfilter] - rotate log file.
--list, -l [logfilter] - List of managed logs.
--filter, -f logfilter - ('filter mode'). View log only from 'logfilter'(regexp)
Note: 'logfilter' - regexp for name of log. Default: ALL logs.
\endcode
\section pg_Codegen_vmonitor Мониторинг состояния внутренних переменных
В генерируемом коде встроена поддержка удалённого просмотра (монторинга) внутреннего состояния \b ВСЕХ in_xx и out_xxx переменных,
а также переменных определённых пользователем. Для этого достаточно использовать утилиту uniset2-vmonit
\code
Usage: uniset2-vmonit [-s watch_sec] OBJECT_ID[@node] [uniset-admin-options]
\endcode
Где можно указать (-s sec) как часто обновлять информацию и собственно указать ID (или name) объекта (процесса).
Утилита требует наличия в системе утилиты watch и на самом деле является обёрткой над утилитой uniset2-admin.
Например для отслеживания процесса 12000 утилита запускается так:
\code
uniset2-vmonit 12000
\endcode
\note При локальной наладке обычно запуск производиться так: uniset2-start.sh -f uniset2-vmonit ObjectID
\subsection pg_Codegen_vmonitor_myvar Добавление своих переменных в "мониторинг".
Для добавления своей переменной в "мониторинг" достаточно \b один \b раз (например в конструкторе своего класса)
вызвать функцию (на самом деле макрос) \b vmonit(var);
Пример:
\code
class MyClass:
public MyClass_SK:
{
public:
MyClass(...)
{
vmonit(my_bool);
vmonit(my_int);
vmonit(my_long);
vmonit(my_double);
vmonit(my_float);
}
private:
bool my_bool;
int my_int;
long my_long;
double my_double;
float my_float;
...
}
\endcode
После этого они появяться в выводе утилиты uniset2-vmonit
\warning На данный момент поддерживаются только простые типы переменных (bool,short,int,long,double,float см. VMonitor)
*/ */
...@@ -34,6 +34,7 @@ TestProc::TestProc(): ...@@ -34,6 +34,7 @@ TestProc::TestProc():
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void TestProc::step() void TestProc::step()
{ {
snap(undef);
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void TestProc::sysCommand( const UniSetTypes::SystemMessage* sm ) void TestProc::sysCommand( const UniSetTypes::SystemMessage* sm )
......
...@@ -183,7 +183,7 @@ class LogAgregator: ...@@ -183,7 +183,7 @@ class LogAgregator:
typedef std::unordered_map<std::string, std::shared_ptr<DebugStream>> LogMap; typedef std::unordered_map<std::string, std::shared_ptr<DebugStream>> LogMap;
LogMap lmap; LogMap lmap;
typedef std::unordered_map<std::shared_ptr<DebugStream>,sigc::connection> ConnectionMap; typedef std::unordered_map<std::shared_ptr<DebugStream>, sigc::connection> ConnectionMap;
ConnectionMap conmap; ConnectionMap conmap;
}; };
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
......
...@@ -106,6 +106,9 @@ namespace UniSetTypes ...@@ -106,6 +106,9 @@ namespace UniSetTypes
class IDList class IDList
{ {
public: public:
IDList( std::vector<std::string>& v );
IDList( std::vector<std::string>&& v );
IDList(); IDList();
~IDList(); ~IDList();
......
/* File: This file is part of the UniSet project
* Copyright (C) 2002 Vitaly Lipatov, Pavel Vainerman
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// --------------------------------------------------------------------------
/*! \file
* \author Pavel Vainerman
*/
// --------------------------------------------------------------------------
#ifndef VMonitor_H_
#define VMonitor_H_
// --------------------------------------------------------------------------
#include <string>
#include <ostream>
#include <unordered_map>
// --------------------------------------------------------------------------
#ifndef VMON_DEF_FUNC
#define VMON_DEF_FUNC(T) void add( const std::string& name, const T& v )
#endif
#ifndef VMON_DEF_FUNC2
#define VMON_DEF_FUNC2(T) \
void add( const std::string& name, const T& v );\
void add( const std::string& name, const unsigned T& v )
#endif
#ifndef VMON_DEF_MAP
#define VMON_DEF_MAP(T) std::unordered_map<const T*,const std::string> m_##T
#endif
#ifndef VMON_DEF_MAP2
#define VMON_DEF_MAP2(T) \
std::unordered_map<const T*,const std::string> m_##T; \
std::unordered_map<const unsigned T*,const std::string> m_unsigned_##T
#endif
// --------------------------------------------------------------------------
/* EXAMPLE HELPER MACROS
#ifndef vmonit
#define vmonit( var ) add( #var, var )
#endif
*/
// --------------------------------------------------------------------------
/*! Вспомогательный класс для реализации "мониторинга" состояния переменных стандартных(!) типов.
* Необходимые переменные добавляются при помощи функции add() (специально перегруженной под разные типы).
* Для удобства использования должен быть определён макрос примерно следующего вида
\code
#define vmonit( var ) vmon.add( #var, var )
\endcode
* При условии, что в классе создан объект VMonitor с именем vmon.
\code
class MyClass
{
public:
MyClass()
{
// сделать один раз для нужных переменных
vmonit(myvar1);
vmonit(myvar2)
vmonit(myvar3);
}
...
void printState()
{
cout << vmon.get_pretty_str() << endl;
// или
cout << vmon.str() << endl;
// или
cout << vmon << endl;
}
private:
int myvar1;
bool myvar2;
logn myvar3;
...
VMonitor vmon;
}
\endcode
*
*
* \todo Нужно добавить поддержку "пользователских типов" (возможно нужно использовать variadic templates)
*/
class VMonitor
{
public:
VMonitor(){}
friend std::ostream& operator<<(std::ostream& os, VMonitor& m );
std::string str();
std::string pretty_str();
// функции добавления..
VMON_DEF_FUNC2(int);
VMON_DEF_FUNC2(long);
VMON_DEF_FUNC2(short);
VMON_DEF_FUNC(bool);
VMON_DEF_FUNC(float);
VMON_DEF_FUNC(double);
protected:
private:
VMON_DEF_MAP2(int);
VMON_DEF_MAP2(long);
VMON_DEF_MAP2(short);
VMON_DEF_MAP(bool);
VMON_DEF_MAP(float);
VMON_DEF_MAP(double);
};
// --------------------------------------------------------------------------
#endif
...@@ -156,6 +156,8 @@ std::ostream& LogAgregator::printLogList( std::ostream& os, const std::string& r ...@@ -156,6 +156,8 @@ std::ostream& LogAgregator::printLogList( std::ostream& os, const std::string& r
lst = getLogList(); lst = getLogList();
else else
lst = getLogList(regexp_str); lst = getLogList(regexp_str);
return printLogList(os,lst);
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
std::ostream& LogAgregator::printLogList( std::ostream& os, std::list<iLog>& lst ) std::ostream& LogAgregator::printLogList( std::ostream& os, std::list<iLog>& lst )
......
...@@ -116,8 +116,22 @@ long UniSetTypes::setoutregion(long ret, long calMin, long calMax) ...@@ -116,8 +116,22 @@ long UniSetTypes::setoutregion(long ret, long calMin, long calMax)
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
UniSetTypes::IDList::IDList( std::vector<std::string>&& svec ):
UniSetTypes::IDList::IDList()
{
for( const auto& s: svec )
add( uni_atoi(s) );
}
// ------------------------------------------------------------------
UniSetTypes::IDList::IDList( std::vector<std::string>& svec ):
UniSetTypes::IDList::IDList()
{
for( const auto& s: svec )
add( uni_atoi(s) );
}
// -------------------------------------------------------------------------
UniSetTypes::IDList::IDList(): UniSetTypes::IDList::IDList():
node(UniSetTypes::uniset_conf()->getLocalNode()) node( (UniSetTypes::uniset_conf() ? UniSetTypes::uniset_conf()->getLocalNode() : DefaultObjectId) )
{ {
} }
...@@ -195,24 +209,7 @@ bool UniSetTypes::file_exist( const std::string& filename ) ...@@ -195,24 +209,7 @@ bool UniSetTypes::file_exist( const std::string& filename )
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
UniSetTypes::IDList UniSetTypes::explode( const string& str, char sep ) UniSetTypes::IDList UniSetTypes::explode( const string& str, char sep )
{ {
UniSetTypes::IDList l; UniSetTypes::IDList l( explode_str(str,sep) );
string::size_type prev = 0;
string::size_type pos = 0;
do
{
pos = str.find(sep, prev);
string s(str.substr(prev, pos - prev));
if( !s.empty() )
{
l.add( uni_atoi(s) );
prev = pos + 1;
}
}
while( pos != string::npos );
return std::move(l); return std::move(l);
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
...@@ -222,10 +219,29 @@ std::vector<std::string> UniSetTypes::explode_str( const string& str, char sep ) ...@@ -222,10 +219,29 @@ std::vector<std::string> UniSetTypes::explode_str( const string& str, char sep )
string::size_type prev = 0; string::size_type prev = 0;
string::size_type pos = 0; string::size_type pos = 0;
string::size_type sz = str.size();
do do
{ {
if( prev >= sz )
break;
pos = str.find(sep, prev); pos = str.find(sep, prev);
if( pos == string::npos )
{
string s(str.substr(prev, sz-prev));
if( !s.empty() )
v.emplace_back(s);
break;
}
if( pos == 0 )
{
prev = 1;
continue;
}
string s(str.substr(prev, pos - prev)); string s(str.substr(prev, pos - prev));
if( !s.empty() ) if( !s.empty() )
...@@ -260,7 +276,7 @@ std::list<UniSetTypes::ParamSInfo> UniSetTypes::getSInfoList( const string& str, ...@@ -260,7 +276,7 @@ std::list<UniSetTypes::ParamSInfo> UniSetTypes::getSInfoList( const string& str,
auto lst = UniSetTypes::explode_str(str, ','); auto lst = UniSetTypes::explode_str(str, ',');
for( auto it : lst ) for( const auto& it : lst )
{ {
UniSetTypes::ParamSInfo item; UniSetTypes::ParamSInfo item;
......
...@@ -6,7 +6,7 @@ noinst_LTLIBRARIES = libVarious.la ...@@ -6,7 +6,7 @@ noinst_LTLIBRARIES = libVarious.la
libVarious_la_CPPFLAGS = $(SIGC_CFLAGS) $(COMCPP_CFLAGS) libVarious_la_CPPFLAGS = $(SIGC_CFLAGS) $(COMCPP_CFLAGS)
libVarious_la_LIBADD = $(SIGC_LIBS) $(COMCPP_LIBS) libVarious_la_LIBADD = $(SIGC_LIBS) $(COMCPP_LIBS)
libVarious_la_SOURCES = UniXML.cc MessageType.cc Configuration.cc \ libVarious_la_SOURCES = UniXML.cc MessageType.cc Configuration.cc \
Restorer_XML.cc RunLock.cc Mutex.cc SViewer.cc SMonitor.cc LT_Object.cc WDTInterface.cc Restorer_XML.cc RunLock.cc Mutex.cc SViewer.cc SMonitor.cc LT_Object.cc WDTInterface.cc VMonitor.cc
local-clean: local-clean:
rm -rf *iSK.cc rm -rf *iSK.cc
......
// --------------------------------------------------------------------------
#include <string>
#include <sstream>
#include <iomanip>
#include "VMonitor.h"
// --------------------------------------------------------------------------
#define VMON_IMPL_ADD(T) void VMonitor::add( const std::string& name, const T& v ) \
{\
m_##T.emplace(&v,name); \
}
// --------------------------------------------------------------------------
#define VMON_IMPL_ADD2(T) \
void VMonitor::add( const std::string& name, const T& v ) \
{\
m_##T.emplace(&v,name); \
} \
void VMonitor::add( const std::string& name, const unsigned T& v ) \
{\
m_unsigned_##T.emplace(&v,name); \
}
// --------------------------------------------------------------------------
#define VMON_IMPL_PRN(M,T) \
{\
for( const auto& e: M.m_##T ) \
os << e.second << "=" << *(e.first) << std::endl;\
}
// --------------------------------------------------------------------------
#define VMON_IMPL_PRN2(M,T) \
{\
for( const auto& e: M.m_##T ) \
os << e.second << "=" << *(e.first) << std::endl;\
\
for( const auto& e: M.m_unsigned_##T ) \
os << e.second << "=" << *(e.first) << std::endl;\
}
// --------------------------------------------------------------------------
#define VMON_IMPL_PRET(T) \
{\
for( const auto& e: m_##T ) \
os << std::right << std::setw(15) << e.second << std::left << " = " << std::right << std::setw(6) << *(e.first) << std::endl;\
}
// --------------------------------------------------------------------------
#define VMON_IMPL_PRET2(T) \
{\
for( const auto& e: m_##T ) \
os << std::right << std::setw(15) << e.second << std::left << " = " << std::right << std::setw(6) << *(e.first) << std::endl;\
\
for( const auto& e: m_unsigned_##T ) \
os << std::right << std::setw(15) << e.second << std::left << " = " << std::right << std::setw(6) << *(e.first) << std::endl;\
}
// --------------------------------------------------------------------------
VMON_IMPL_ADD2(int)
VMON_IMPL_ADD2(long)
VMON_IMPL_ADD2(short)
VMON_IMPL_ADD(bool)
VMON_IMPL_ADD(float)
VMON_IMPL_ADD(double)
// --------------------------------------------------------------------------
std::ostream& operator<<(std::ostream& os, VMonitor& m )
{
VMON_IMPL_PRN2(m,int);
VMON_IMPL_PRN2(m,long);
VMON_IMPL_PRN2(m,short);
VMON_IMPL_PRN(m,bool);
VMON_IMPL_PRN(m,float);
VMON_IMPL_PRN(m,double);
return os;
}
// --------------------------------------------------------------------------
std::string VMonitor::str()
{
std::ostringstream s;
s << (*this);
return std::move(s.str());
}
// --------------------------------------------------------------------------
std::string VMonitor::pretty_str()
{
std::ostringstream os;
VMON_IMPL_PRET2(int);
VMON_IMPL_PRET2(long);
VMON_IMPL_PRET2(short);
VMON_IMPL_PRET(bool);
VMON_IMPL_PRET(float);
VMON_IMPL_PRET(double);
return std::move(os.str());
}
// --------------------------------------------------------------------------
...@@ -4,7 +4,7 @@ if HAVE_TESTS ...@@ -4,7 +4,7 @@ if HAVE_TESTS
############################################################################ ############################################################################
#check_PROGRAMS = tests tests_with_conf #check_PROGRAMS = tests tests_with_conf
noinst_PROGRAMS = tests tests_with_conf noinst_PROGRAMS = tests tests_with_conf develop
#umutex threadtst dlog #umutex threadtst dlog
tests_LDADD = $(top_builddir)/lib/libUniSet2.la $(SIGC_LIBS) $(COMCPP_LIBS) tests_LDADD = $(top_builddir)/lib/libUniSet2.la $(SIGC_LIBS) $(COMCPP_LIBS)
...@@ -23,7 +23,6 @@ test_triggerAND.cc \ ...@@ -23,7 +23,6 @@ test_triggerAND.cc \
test_triggerOUT.cc \ test_triggerOUT.cc \
test_pulse.cc \ test_pulse.cc \
test_modbustypes.cc \ test_modbustypes.cc \
test_utypes.cc \
test_mutex.cc \ test_mutex.cc \
test_logserver.cc \ test_logserver.cc \
test_tcpcheck.cc test_tcpcheck.cc
...@@ -34,12 +33,21 @@ tests_with_conf_SOURCES = tests_with_conf.cc \ ...@@ -34,12 +33,21 @@ tests_with_conf_SOURCES = tests_with_conf.cc \
test_conftest.cc \ test_conftest.cc \
test_ui.cc \ test_ui.cc \
test_iorfile.cc \ test_iorfile.cc \
test_messagetype.cc test_messagetype.cc \
test_utypes.cc
# threadtst_SOURCES = threadtst.cc # threadtst_SOURCES = threadtst.cc
# threadtst_LDADD = $(top_builddir)/lib/libUniSet2.la ${SIGC_LIBS} $(COMCPP_LIBS) # threadtst_LDADD = $(top_builddir)/lib/libUniSet2.la ${SIGC_LIBS} $(COMCPP_LIBS)
# threadtst_CPPFLAGS = -I$(top_builddir)/include ${SIGC_CFLAGS} $(COMCPP_CFLAGS) # threadtst_CPPFLAGS = -I$(top_builddir)/include ${SIGC_CFLAGS} $(COMCPP_CFLAGS)
# #
develop_LDADD = $(top_builddir)/lib/libUniSet2.la
develop_CPPFLAGS = -I$(top_builddir)/include
develop_SOURCES = develop.cc
include $(top_builddir)/testsuite/testsuite-common.mk include $(top_builddir)/testsuite/testsuite-common.mk
check-local: atconfig package.m4 $(TESTSUITE) check-local: atconfig package.m4 $(TESTSUITE)
......
#include <string>
#include <sstream>
#include <iostream>
#include <vector>
#include <unordered_map>
#include <type_traits>
#include <tuple>
template<typename... Args>
class VMon
{
public:
std::tuple<std::unordered_map<const Args*,const std::string>...> m_tuple;
};
// ------------------------------------------------------------------------------
using namespace std;
int main( int argc, const char** argv )
{
// VMon<int,double,char> vmon;
// cout << std::get<0>(vmon.m_tuple).size() << endl;
return 0;
}
...@@ -74,3 +74,41 @@ TEST_CASE("UniSetTypes: uni_strdup", "[utypes][uni_strdup]" ) ...@@ -74,3 +74,41 @@ TEST_CASE("UniSetTypes: uni_strdup", "[utypes][uni_strdup]" )
} }
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
TEST_CASE("UniSetTypes: explode", "[utypes][explode]" )
{
const std::string str1("id1/wed/wedwed/");
auto t1 = UniSetTypes::explode_str(str1,'/');
CHECK( t1.size() == 3 );
auto t2 = UniSetTypes::explode_str(str1,'.');
CHECK( t2.size() == 1 );
const std::string str2("id1/wed/wedwed/f");
auto t3 = UniSetTypes::explode_str(str2,'/');
CHECK( t3.size() == 4 );
const std::string str3("/id1/wed/wedwed/");
auto t4 = UniSetTypes::explode_str(str3,'/');
CHECK( t4.size() == 3 );
const std::string str4("");
auto t5 = UniSetTypes::explode_str(str4,'/');
CHECK( t5.size() == 0 );
const std::string str5("/");
auto t6 = UniSetTypes::explode_str(str5,'/');
CHECK( t6.size() == 0 );
}
// -----------------------------------------------------------------------------
TEST_CASE("UniSetTypes: getSInfoList", "[utypes][getsinfo]" )
{
const std::string str1("id1@node1,id2,234,234@node5,45@245");
auto t1 = UniSetTypes::getSInfoList(str1);
CHECK( t1.size() == 5 );
}
// -----------------------------------------------------------------------------
...@@ -204,6 +204,7 @@ extensions/tests/tests_with_sm.h ...@@ -204,6 +204,7 @@ extensions/tests/tests_with_sm.h
extensions/tests/tests_with_sm.xml extensions/tests/tests_with_sm.xml
extensions/tests/u.xml extensions/tests/u.xml
extensions/tests/sm_perf_test.cc extensions/tests/sm_perf_test.cc
extensions/tests/develop.cc
extensions/UNetUDP/tests/Makefile.am extensions/UNetUDP/tests/Makefile.am
extensions/UNetUDP/tests/test_unetudp.cc extensions/UNetUDP/tests/test_unetudp.cc
extensions/UNetUDP/tests/tests_individual_process.cc extensions/UNetUDP/tests/tests_individual_process.cc
...@@ -287,6 +288,7 @@ include/Pulse.h ...@@ -287,6 +288,7 @@ include/Pulse.h
include/Restorer.h include/Restorer.h
include/RunLock.h include/RunLock.h
include/SMonitor.h include/SMonitor.h
include/VMonitor.h
include/SViewer.h include/SViewer.h
include/TCPCheck.h include/TCPCheck.h
include/ThreadCreator.h include/ThreadCreator.h
...@@ -394,6 +396,7 @@ src/Various/Mutex.cc ...@@ -394,6 +396,7 @@ src/Various/Mutex.cc
src/Various/Restorer_XML.cc src/Various/Restorer_XML.cc
src/Various/RunLock.cc src/Various/RunLock.cc
src/Various/SMonitor.cc src/Various/SMonitor.cc
src/Various/VMonitor.cc
src/Various/SViewer.cc src/Various/SViewer.cc
src/Various/UniXML.cc src/Various/UniXML.cc
src/Various/WDTInterface.cc src/Various/WDTInterface.cc
......
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