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

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

(VMonitor): добавлена реализация механизма (удалённого) отслеживания внутреннего состояния переменных
parent 085e4d60
......@@ -51,6 +51,7 @@ SQL:
Debug:
- в codegen встроить получение состояния всех переменных (dumpIO() + UniSetObject::getInfo()),
возможно написать на python утилиту "монитор".
- Сделать макрос с простым названием например NOTE(variable)(snap?)... пишуший в map var=value, а потом показывающий в getInfo() (и может dumpIO())
- дописать в codegen документацию по запуску и управлению логами через LogServer
......
......@@ -2,6 +2,8 @@
# This file is part of the UniSet library #
############################################################################
bin_SCRIPTS = @PACKAGE@-vmonit
bin_PROGRAMS = @PACKAGE@-admin
@PACKAGE@_admin_SOURCES = admin.cc
@PACKAGE@_admin_LDADD = $(top_builddir)/lib/libUniSet2.la
......
......@@ -106,14 +106,14 @@ static void usage()
cout << endl;
print_help(36, "-r|--configure [FullObjName] ", "Посылка SystemMessage::ReConfiguration всем объектам (процессам) или заданному по имени (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;
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");
cout << endl;
print_help(36, "-w|--getRawValue id1@node1=val,id2@node2=val2,id3=val3,.. ", "Получить 'сырое' значение.\n");
print_help(36, "-y|--getCalibrate id1@node1=val,id2@node2=val2,id3=val3,.. ", "Получить параметры калибровки.\n");
print_help(36, "-t|--getChangedTime 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,id2@node2,id3,.. ", "Получить параметры калибровки.\n");
print_help(36, "-t|--getChangedTime id1@node1,id2@node2,id3,.. ", "Получить время последнего изменения.\n");
print_help(36, "-v|--verbose", "Подробный вывод логов.\n");
print_help(36, "-q|--quiet", "Выводит только результат.\n");
cout << endl;
......@@ -442,9 +442,9 @@ static bool commandToAll(const string& section, std::shared_ptr<ObjectRepository
case Exist:
{
if( obj->exist() )
cout << setw(55) << ob << " <--- exist ok\n";
cout << "(" << setw(6) << obj->getId() << ")" << setw(55) << ob << " <--- exist ok\n";
else
cout << setw(55) << ob << " <--- exist NOT OK\n";
cout << "(" << setw(6) << obj->getId() << ")" << setw(55) << ob << " <--- exist NOT OK\n";
}
break;
......@@ -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 )
cout << "(oinfo): Не задан OID!" << endl;
if( it.si.node == DefaultObjectId )
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);
UniSetObject_i_var obj = UniSetObject_i::_narrow(o);
if(CORBA::is_nil(obj))
{
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))
{
if( !quiet )
cout << "(oinfo): объект " << oid << " недоступен" << endl;
}
else
{
SimpleInfo_var inf = obj->getInfo();
cout << inf->info << endl;
cout << endl << endl;
}
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 @@
#ifndef mylogany
#define mylogany log()->any()
#endif
#ifndef vmonit
#define vmonit( var ) vmon.add( #var, var )
#endif
// Вспомогательные функции для удобства логирования
// ------------------------------------------------------------
/*!&lt; вывод в строку значение всех входов и выходов в формате
/*! вывод в строку значение всех входов и выходов в формате
ObjectName:
in_xxx = val
in_xxx2 = val
......@@ -230,17 +233,20 @@
*/
std::string dumpIO();
/*!&lt; Вывод в строку названия входа/выхода в формате: in_xxx(SensorName)
/*! Вывод в строку названия входа/выхода в формате: in_xxx(SensorName)
\param id - идентификатор датчика
\param showLinkName - TRUE - выводить SensorName, FALSE - не выводить
*/
std::string str( UniSetTypes::ObjectId id, bool showLinkName=true );
/*!&lt; Вывод значения входа/выхода в формате: in_xxx(SensorName)=val
/*! Вывод значения входа/выхода в формате: in_xxx(SensorName)=val
\param id - идентификатор датчика
\param showLinkName - TRUE - выводить SensorName, FALSE - не выводить
*/
std::string strval( UniSetTypes::ObjectId id, bool showLinkName=true );
/*! Вывод состояния внутренних переменных */
inline std::string dumpVars(){ return std::move(vmon.pretty_str()); }
// ------------------------------------------------------------
</xsl:template>
......@@ -313,6 +319,11 @@
std::shared_ptr&lt;LogServer&gt; logserv;
std::string logserv_host = {""};
int logserv_port = {0};
// snap
bool no_snap = {false};
VMonitor vmon;
</xsl:template>
<xsl:template name="COMMON-HEAD-PRIVATE">
......@@ -420,6 +431,7 @@ UniSetTypes::SimpleInfo* <xsl:value-of select="$CLASSNAME"/>_SK::getInfo()
inf &lt;&lt; i->info &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();
......@@ -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; endl;
</xsl:for-each>
return s.str();
}
// ----------------------------------------------------------------------------
......
......@@ -38,6 +38,9 @@
#define <xsl:value-of select="$CLASSNAME"/>_SK_H_
// -----------------------------------------------------------------------------
#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"/>UniSetObject.h<xsl:call-template name="postinclude"/></xsl:if>
#include <xsl:call-template name="preinclude"/>LT_Object.h<xsl:call-template name="postinclude"/>
......@@ -47,6 +50,7 @@
#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"/>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:
<xsl:if test="normalize-space($BASECLASS)!=''">public <xsl:value-of select="normalize-space($BASECLASS)"/>,</xsl:if>
......
......@@ -39,6 +39,8 @@
// -----------------------------------------------------------------------------
#include &lt;memory&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"/>UniSetObject.h<xsl:call-template name="postinclude"/></xsl:if>
#include <xsl:call-template name="preinclude"/>LT_Object.h<xsl:call-template name="postinclude"/>
......@@ -47,6 +49,7 @@
#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"/>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:
<xsl:if test="normalize-space($BASECLASS)!=''">public <xsl:value-of select="normalize-space($BASECLASS)"/>,</xsl:if>
......
......@@ -7,6 +7,8 @@ using namespace UniSetTypes;
TestGen::TestGen( UniSetTypes::ObjectId id, xmlNode* confnode ):
TestGen_SK( id, confnode )
{
vmonit(int_var);
vmonit(bool_var);
}
// -----------------------------------------------------------------------------
TestGen::~TestGen()
......@@ -28,6 +30,12 @@ void TestGen::step()
myinfo << 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 )
......
......@@ -21,6 +21,8 @@ class TestGen:
virtual void sigterm( int signo ) override;
private:
bool bool_var = { false };
int int_var = {0};
};
// -----------------------------------------------------------------------------
#endif // TestGen_H_
......
......@@ -13,7 +13,7 @@
Name: libuniset2
Version: 2.1
Release: alt7
Release: alt7.1
Summary: UniSet - library for building distributed industrial control systems
......@@ -288,6 +288,7 @@ mv -f %buildroot%python_sitelibdir_noarch/* %buildroot%python_sitelibdir/%oname
%_bindir/%oname-nullController
%_bindir/%oname-sviewer-text
%_bindir/%oname-smonit
%_bindir/%oname-vmonit
%_bindir/%oname-simitator
%_bindir/%oname-log
%_bindir/%oname-logserver-wrap
......@@ -455,12 +456,16 @@ mv -f %buildroot%python_sitelibdir_noarch/* %buildroot%python_sitelibdir/%oname
# ..
%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
- (ModbusSlave): fixed bug in read0x function (for float and precision)
* Thu Jun 04 2015 Pavel Vainerman <pv@altlinux.ru> 2.1-alt6
- (smonit): print supplier, change print format
- (admin): add getChangedTime function
- (codegen): reuse getInfo() function (internal variables monitor)
* Tue Jun 02 2015 Pavel Vainerman <pv@altlinux.ru> 2.1-alt5
- (LogServer): refactoring
......
......@@ -14,6 +14,8 @@
- \ref pg_Codegen_Templ_Alone
- \ref pg_Codegen_log
- \ref pg_Codegen_loglevel
- \ref pg_Codegen_logserver
- \ref pg_Codegen_vmonitor
\section pg_Codegen_Common Общее описание утилиты uniset-codegen
Утилита uniset-codegen предназначена для генерирования "скелета" процесса управления на основе
......@@ -400,4 +402,88 @@ MyClass_SK.cc: myclass.src.xml
4117
\endcode
Т.е. для того, чтобы включить указанные логи в датчик нужно записать число \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():
// -----------------------------------------------------------------------------
void TestProc::step()
{
snap(undef);
}
// -----------------------------------------------------------------------------
void TestProc::sysCommand( const UniSetTypes::SystemMessage* sm )
......
......@@ -183,7 +183,7 @@ class LogAgregator:
typedef std::unordered_map<std::string, std::shared_ptr<DebugStream>> LogMap;
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;
};
// -------------------------------------------------------------------------
......
......@@ -106,6 +106,9 @@ namespace UniSetTypes
class IDList
{
public:
IDList( std::vector<std::string>& v );
IDList( std::vector<std::string>&& v );
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
lst = getLogList();
else
lst = getLogList(regexp_str);
return printLogList(os,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)
}
// -------------------------------------------------------------------------
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():
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 )
// -------------------------------------------------------------------------
UniSetTypes::IDList UniSetTypes::explode( const string& str, char sep )
{
UniSetTypes::IDList l;
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 );
UniSetTypes::IDList l( explode_str(str,sep) );
return std::move(l);
}
// -------------------------------------------------------------------------
......@@ -222,10 +219,29 @@ std::vector<std::string> UniSetTypes::explode_str( const string& str, char sep )
string::size_type prev = 0;
string::size_type pos = 0;
string::size_type sz = str.size();
do
{
if( prev >= sz )
break;
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));
if( !s.empty() )
......@@ -260,7 +276,7 @@ std::list<UniSetTypes::ParamSInfo> UniSetTypes::getSInfoList( const string& str,
auto lst = UniSetTypes::explode_str(str, ',');
for( auto it : lst )
for( const auto& it : lst )
{
UniSetTypes::ParamSInfo item;
......
......@@ -6,7 +6,7 @@ noinst_LTLIBRARIES = libVarious.la
libVarious_la_CPPFLAGS = $(SIGC_CFLAGS) $(COMCPP_CFLAGS)
libVarious_la_LIBADD = $(SIGC_LIBS) $(COMCPP_LIBS)
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:
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
############################################################################
#check_PROGRAMS = tests tests_with_conf
noinst_PROGRAMS = tests tests_with_conf
noinst_PROGRAMS = tests tests_with_conf develop
#umutex threadtst dlog
tests_LDADD = $(top_builddir)/lib/libUniSet2.la $(SIGC_LIBS) $(COMCPP_LIBS)
......@@ -23,7 +23,6 @@ test_triggerAND.cc \
test_triggerOUT.cc \
test_pulse.cc \
test_modbustypes.cc \
test_utypes.cc \
test_mutex.cc \
test_logserver.cc \
test_tcpcheck.cc
......@@ -34,12 +33,21 @@ tests_with_conf_SOURCES = tests_with_conf.cc \
test_conftest.cc \
test_ui.cc \
test_iorfile.cc \
test_messagetype.cc
test_messagetype.cc \
test_utypes.cc
# threadtst_SOURCES = threadtst.cc
# threadtst_LDADD = $(top_builddir)/lib/libUniSet2.la ${SIGC_LIBS} $(COMCPP_LIBS)
# 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
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]" )
}
}
// -----------------------------------------------------------------------------
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
extensions/tests/tests_with_sm.xml
extensions/tests/u.xml
extensions/tests/sm_perf_test.cc
extensions/tests/develop.cc
extensions/UNetUDP/tests/Makefile.am
extensions/UNetUDP/tests/test_unetudp.cc
extensions/UNetUDP/tests/tests_individual_process.cc
......@@ -287,6 +288,7 @@ include/Pulse.h
include/Restorer.h
include/RunLock.h
include/SMonitor.h
include/VMonitor.h
include/SViewer.h
include/TCPCheck.h
include/ThreadCreator.h
......@@ -394,6 +396,7 @@ src/Various/Mutex.cc
src/Various/Restorer_XML.cc
src/Various/RunLock.cc
src/Various/SMonitor.cc
src/Various/VMonitor.cc
src/Various/SViewer.cc
src/Various/UniXML.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