Commit 2f34b787 authored by Pavel Vainerman's avatar Pavel Vainerman

(IOC): рефакторинг функции getInfo(), добавил возможность получения

статистики по конкретному заказчику
parent 604c1732
...@@ -588,6 +588,12 @@ uniset::SimpleInfo* <xsl:value-of select="$CLASSNAME"/>_SK::getInfo( const char* ...@@ -588,6 +588,12 @@ uniset::SimpleInfo* <xsl:value-of select="$CLASSNAME"/>_SK::getInfo( const char*
inf &lt;&lt; "LogServer: NONE" &lt;&lt; endl; inf &lt;&lt; "LogServer: NONE" &lt;&lt; endl;
<xsl:if test="normalize-space($STAT)='1'"> <xsl:if test="normalize-space($STAT)='1'">
size_t smCount = 0;
for( const auto&amp; s: smStat )
smCount += s.second;
inf &lt;&lt; "smCount=" &lt;&lt; smCount &lt;&lt; endl;
inf &lt;&lt; "statistics: " &lt;&lt; endl inf &lt;&lt; "statistics: " &lt;&lt; endl
&lt;&lt; " processingMessageCatchCount: " &lt;&lt; processingMessageCatchCount &lt;&lt; endl; &lt;&lt; " processingMessageCatchCount: " &lt;&lt; processingMessageCatchCount &lt;&lt; endl;
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
ВСЕ ВАШИ ИЗМЕНЕНИЯ БУДУТ ПОТЕРЯНЫ. ВСЕ ВАШИ ИЗМЕНЕНИЯ БУДУТ ПОТЕРЯНЫ.
*/ */
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// generate timestamp: 2017-04-29+03:00 // generate timestamp: 2017-04-30+03:00
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
#ifndef UObject_SK_H_ #ifndef UObject_SK_H_
#define UObject_SK_H_ #define UObject_SK_H_
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
ВСЕ ВАШИ ИЗМЕНЕНИЯ БУДУТ ПОТЕРЯНЫ. ВСЕ ВАШИ ИЗМЕНЕНИЯ БУДУТ ПОТЕРЯНЫ.
*/ */
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// generate timestamp: 2017-04-29+03:00 // generate timestamp: 2017-04-30+03:00
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
#include <memory> #include <memory>
#include <iomanip> #include <iomanip>
...@@ -525,6 +525,12 @@ uniset::SimpleInfo* UObject_SK::getInfo( const char* userparam ) ...@@ -525,6 +525,12 @@ uniset::SimpleInfo* UObject_SK::getInfo( const char* userparam )
inf << "LogServer: NONE" << endl; inf << "LogServer: NONE" << endl;
size_t smCount = 0;
for( const auto& s: smStat )
smCount += s.second;
inf << "smCount=" << smCount << endl;
inf << "statistics: " << endl inf << "statistics: " << endl
<< " processingMessageCatchCount: " << processingMessageCatchCount << endl; << " processingMessageCatchCount: " << processingMessageCatchCount << endl;
......
...@@ -293,7 +293,11 @@ namespace uniset ...@@ -293,7 +293,11 @@ namespace uniset
virtual void checkThreshold(IOController::IOStateList::iterator& li, const uniset::ObjectId sid, bool send_msg = true ); virtual void checkThreshold(IOController::IOStateList::iterator& li, const uniset::ObjectId sid, bool send_msg = true );
//! поиск информации о пороговом датчике //! поиск информации о пороговом датчике
ThresholdExtList::iterator findThreshold( const uniset::ObjectId sid, const uniset::ThresholdId tid ); ThresholdInfoExt* findThreshold( AskThresholdMap& tmap, const uniset::ObjectId sid, const uniset::ThresholdId tid );
// обновление статистики
bool updateThresholdStat( AskThresholdMap& tmap, uniset::ObjectId sid, uniset::ThresholdId tid, const uniset::ConsumerInfo& ci, size_t stat_smCount );
bool updateSensorStat( IOController::IOStateList::iterator& it, const uniset::ConsumerInfo& ci, size_t stat_smCount );
/*! сохранение списка заказчиков /*! сохранение списка заказчиков
По умолчанию делает dump, если объявлен dumper. По умолчанию делает dump, если объявлен dumper.
...@@ -331,6 +335,12 @@ namespace uniset ...@@ -331,6 +335,12 @@ namespace uniset
Poco::JSON::Object::Ptr getConsumers(uniset::ObjectId sid, ConsumerListInfo& clist, bool ifNotEmpty = true ); Poco::JSON::Object::Ptr getConsumers(uniset::ObjectId sid, ConsumerListInfo& clist, bool ifNotEmpty = true );
#endif #endif
// статистика
void showStatisticsForConsumer( std::ostringstream& inf, const std::string& consumer );
void showStatisticsForLostConsumers( std::ostringstream& inf );
void showStatisticsForConsusmers( std::ostringstream& inf );
void showStatisticsForConsumersWithLostEvent( std::ostringstream& inf );
private: private:
friend class NCRestorer; friend class NCRestorer;
......
...@@ -76,118 +76,272 @@ IONotifyController::~IONotifyController() ...@@ -76,118 +76,272 @@ IONotifyController::~IONotifyController()
conInit.disconnect(); conInit.disconnect();
} }
// ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------
SimpleInfo* IONotifyController::getInfo( const char* userparam ) void IONotifyController::showStatisticsForConsumer( ostringstream& inf, const std::string& consumer )
{ {
uniset::SimpleInfo_var i = IOController::getInfo(userparam); ObjectId consumer_id = uniset_conf()->getObjectID(consumer);
if( consumer_id == DefaultObjectId )
{
inf << "not found consumer '" << consumer << "'" << endl;
return;
}
ostringstream inf; // Формируем статистику по каждому датчику..
struct StatInfo
{
StatInfo( ObjectId id, const ConsumerInfoExt& c ):inf(c),sid(id){}
inf << i->info << endl; const ConsumerInfoExt inf;
ObjectId sid;
};
auto oind = uniset_conf()->oind; std::list<StatInfo> stat;
{ // общее количество SensorMessage полученное этим заказчиком
std::lock_guard<std::mutex> lock(lostConsumersMutex); size_t smCount = 0;
{ // lock askIOMutex
if( lostConsumers.size() > 0 ) // выводим информацию по конкретному объекту
uniset_rwmutex_rlock lock(askIOMutex);
for( auto&& a : askIOList )
{ {
inf << "-------------------------- lost consumers list [maxAttemtps=" << maxAttemtps << "] ------------------" << endl; auto& i = a.second;
uniset_rwmutex_rlock lock(i.mut);
for( const auto& l : lostConsumers ) if( i.clst.empty() )
continue;
// ищем среди заказчиков
for( const auto& c : i.clst )
{ {
inf << " " << "(" << setw(6) << l.first << ")" if( c.id == consumer_id )
<< setw(35) << std::left << ORepHelpers::getShortName(oind->getMapName(l.first)) {
<< " lostCount=" << l.second.count stat.emplace_back(a.first,c);
<< endl; smCount += c.smCount;
break;
}
} }
} }
} // unlock askIOMutex
inf << "----------------------------------------------------------------------------------" << endl; {
// выводим информацию по конкретному объекту
uniset_rwmutex_rlock lock(trshMutex);
for( auto&& a: askTMap )
{
uniset_rwmutex_rlock lock2(a.second.mut);
for( auto&& t: a.second.list )
{
uniset_rwmutex_rlock lock3(t.clst.mut);
for( const auto& c: t.clst.clst )
{
if( c.id == consumer_id )
{
if( t.sid != DefaultObjectId )
stat.emplace_back(t.sid,c);
else
stat.emplace_back(a.first,c);
smCount += c.smCount;
break;
}
}
}
}
} }
//! \todo Назвать параметры нормально // печатаем отчёт
std::string param(userparam); inf << "Statisctic for consumer '" << consumer << "'(smCount=" << smCount << "):"
<< endl
<< "--------------------------------------------"
<< endl;
if( param == "1" || param == "2" ) if( stat.empty() )
{ {
inf << "------------------------------- consumers list ------------------------------" << endl; inf << "NOT FOUND STATISTIC FOR '" << consumer << "'" << endl;
inf << "[userparam=" << userparam << "]" << endl; }
else
{
inf << std::right;
auto oind = uniset_conf()->oind;
for( const auto& s: stat )
{ {
uniset_rwmutex_rlock lock(askIOMutex); inf << " " << "(" << setw(6) << s.sid << ") "
<< setw(35) << ORepHelpers::getShortName(oind->getMapName(s.sid))
<< " ["
<< " lostEvents: " << setw(3) << s.inf.lostEvents
<< " attempt: " << setw(3) << s.inf.attempt
<< " smCount: " << setw(5) << s.inf.smCount
<< " ]"
<< endl;
}
}
for( auto && a : askIOList ) inf << "--------------------------------------------" << endl;
{
auto& i = a.second; }
// ------------------------------------------------------------------------------------------
void IONotifyController::showStatisticsForLostConsumers( ostringstream& inf )
{
std::lock_guard<std::mutex> lock(lostConsumersMutex);
uniset_rwmutex_rlock lock(i.mut); if( lostConsumers.empty() )
{
inf << "..empty lost consumers list..." << endl;
return;
}
// отображаем только датчики с "не пустым" списком заказчиков auto oind = uniset_conf()->oind;
if( i.clst.empty() ) for( const auto& l : lostConsumers )
continue; {
inf << " " << "(" << setw(6) << l.first << ") "
<< setw(35) << std::left << ORepHelpers::getShortName(oind->getMapName(l.first))
<< " lostCount=" << l.second.count
<< endl;
}
}
// ------------------------------------------------------------------------------------------
void IONotifyController::showStatisticsForConsusmers( ostringstream& inf )
{
uniset_rwmutex_rlock lock(askIOMutex);
// Т.к. сперва выводится имя датчика, а только потом его заказчики auto oind = uniset_conf()->oind;
// то если надо выводить только тех, у кого есть "потери"(lostEvent>0)
// предварительно смотрим список есть ли там хоть один с "потерями", а потом уже выводим
if( param == "2" )
{
bool lost = false;
for( const auto& c : i.clst ) for( auto&& a : askIOList )
{ {
if( c.lostEvents > 0 ) auto& i = a.second;
{
lost = true;
break;
}
}
if( !lost ) uniset_rwmutex_rlock lock(i.mut);
continue;
// выводим тех у кого lostEvent>0 // отображаем только датчики с "не пустым" списком заказчиков
inf << "(" << setw(6) << a.first << ")[" << oind->getMapName(a.first) << "]" << endl; if( i.clst.empty() )
continue;
for( const auto& c : i.clst ) inf << "(" << setw(6) << a.first << ")[" << oind->getMapName(a.first) << "]" << endl;
{ for( const auto& c : i.clst )
if( c.lostEvents > 0 ) {
{ inf << " " << "(" << setw(6) << c.id << ")"
inf << " " << "(" << setw(6) << c.id << ")" << setw(35) << ORepHelpers::getShortName(oind->getMapName(c.id))
<< setw(35) << ORepHelpers::getShortName(oind->getMapName(c.id)) << " ["
<< " [" << " lostEvents=" << c.lostEvents
<< " lostEvents=" << c.lostEvents << " attempt=" << c.attempt
<< " attempt=" << c.attempt << " smCount=" << c.smCount
<< " smCount=" << c.smCount << "]"
<< "]" << endl;
<< endl; }
} }
} }
} // ------------------------------------------------------------------------------------------
else // просто выводим всех void IONotifyController::showStatisticsForConsumersWithLostEvent( ostringstream& inf )
{ {
inf << "(" << setw(6) << a.first << ")[" << oind->getMapName(a.first) << "]" << endl; uniset_rwmutex_rlock lock(askIOMutex);
for( const auto& c : i.clst ) auto oind = uniset_conf()->oind;
{ bool empty = true;
inf << " " << "(" << setw(6) << c.id << ")"
<< setw(35) << ORepHelpers::getShortName(oind->getMapName(c.id)) for( auto&& a : askIOList )
<< " [" {
<< " lostEvents=" << c.lostEvents auto& i = a.second;
<< " attempt=" << c.attempt
<< " smCount=" << c.smCount uniset_rwmutex_rlock lock(i.mut);
<< "]"
<< endl; // отображаем только датчики с "не пустым" списком заказчиков
} if( i.clst.empty() )
} continue;
// Т.к. сперва выводится имя датчика, а только потом его заказчики
// то если надо выводить только тех, у кого есть "потери"(lostEvent>0)
// для предварительно смотрим список есть ли там хоть один с "потерями", а потом уже выводим
bool lost = false;
for( const auto& c : i.clst )
{
if( c.lostEvents > 0 )
{
lost = true;
break;
} }
} }
inf << "-----------------------------------------------------------------------------" << endl << endl;
if( !lost )
continue;
empty = false;
// выводим тех у кого lostEvent>0
inf << "(" << setw(6) << a.first << ")[" << oind->getMapName(a.first) << "]" << endl;
for( const auto& c : i.clst )
{
if( c.lostEvents > 0 )
{
inf << " " << "(" << setw(6) << c.id << ")"
<< setw(35) << ORepHelpers::getShortName(oind->getMapName(c.id))
<< " ["
<< " lostEvents=" << c.lostEvents
<< " attempt=" << c.attempt
<< " smCount=" << c.smCount
<< "]"
<< endl;
}
}
}
if( empty )
inf << "...not found consumers with lost event..." << endl;
}
// ------------------------------------------------------------------------------------------
SimpleInfo* IONotifyController::getInfo( const char* userparam )
{
uniset::SimpleInfo_var i = IOController::getInfo(userparam);
//! \todo Назвать параметры нормально
//!
std::string param(userparam);
ostringstream inf;
inf << i->info << endl;
auto oind = uniset_conf()->oind;
if( param.empty() )
{
inf << "-------------------------- lost consumers list [maxAttemtps=" << maxAttemtps << "] ------------------" << endl;
showStatisticsForLostConsumers(inf);
inf << "----------------------------------------------------------------------------------" << endl;
} }
inf << "IONotifyController::UserParam help: " << endl if( param == "consumers" )
<< " 0. Common info" << endl {
<< " 1. Consumers list " << endl inf << "------------------------------- consumers list ------------------------------" << endl;
<< " 2. Consumers list with lostEvent > 0" << endl; showStatisticsForConsusmers(inf);
inf << "-----------------------------------------------------------------------------" << endl << endl;
}
else if( param == "lost" )
{
inf << "------------------------------- consumers list (lost event)------------------" << endl;
showStatisticsForConsumersWithLostEvent(inf);
inf << "-----------------------------------------------------------------------------" << endl << endl;
}
else if( !param.empty() )
{
showStatisticsForConsumer(inf, param);
}
else
{
inf << "IONotifyController::UserParam help: " << endl
<< " Default - Common info" << endl
<< " consumers - Consumers list " << endl
<< " lost - Consumers list with lostEvent > 0" << endl
<< " name - Statistic for consumer 'name'"
<< endl;
}
i->info = inf.str().c_str(); i->info = inf.str().c_str();
...@@ -302,6 +456,7 @@ void IONotifyController::askSensor(const uniset::ObjectId sid, ...@@ -302,6 +456,7 @@ void IONotifyController::askSensor(const uniset::ObjectId sid,
try try
{ {
ui->send(ci.id, std::move(smsg.transport_msg()), ci.node); ui->send(ci.id, std::move(smsg.transport_msg()), ci.node);
updateSensorStat(li,ci,1);
} }
catch( const uniset::Exception& ex ) catch( const uniset::Exception& ex )
{ {
...@@ -751,7 +906,12 @@ void IONotifyController::askThreshold(uniset::ObjectId sid, const uniset::Consum ...@@ -751,7 +906,12 @@ void IONotifyController::askThreshold(uniset::ObjectId sid, const uniset::Consum
UniSetObject_i_var ref = UniSetObject_i::_narrow(op); UniSetObject_i_var ref = UniSetObject_i::_narrow(op);
if(!CORBA::is_nil(ref)) if(!CORBA::is_nil(ref))
{
ref->push( std::move(sm.transport_msg()) ); ref->push( std::move(sm.transport_msg()) );
// askTMap уже залочен trshMutex
updateThresholdStat(askTMap, sid, tid, ci, 1);
}
} }
// Проверка верхнего предела // Проверка верхнего предела
else if( val >= hiLimit ) else if( val >= hiLimit )
...@@ -761,7 +921,12 @@ void IONotifyController::askThreshold(uniset::ObjectId sid, const uniset::Consum ...@@ -761,7 +921,12 @@ void IONotifyController::askThreshold(uniset::ObjectId sid, const uniset::Consum
UniSetObject_i_var ref = UniSetObject_i::_narrow(op); UniSetObject_i_var ref = UniSetObject_i::_narrow(op);
if(!CORBA::is_nil(ref)) if(!CORBA::is_nil(ref))
{
ref->push( std::move(sm.transport_msg()) ); ref->push( std::move(sm.transport_msg()) );
// askTMap уже залочен trshMutex
updateThresholdStat(askTMap, sid, tid, ci, 1);
}
} }
} }
catch( const uniset::Exception& ex ) catch( const uniset::Exception& ex )
...@@ -799,6 +964,7 @@ void IONotifyController::askThreshold(uniset::ObjectId sid, const uniset::Consum ...@@ -799,6 +964,7 @@ void IONotifyController::askThreshold(uniset::ObjectId sid, const uniset::Consum
break; break;
} }
// askTMap уже залочен trshMutex
it = askTMap.find(sid); it = askTMap.find(sid);
if( li != myioEnd() ) if( li != myioEnd() )
...@@ -813,6 +979,60 @@ void IONotifyController::askThreshold(uniset::ObjectId sid, const uniset::Consum ...@@ -813,6 +979,60 @@ void IONotifyController::askThreshold(uniset::ObjectId sid, const uniset::Consum
} // unlock } // unlock
} }
// -------------------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------------------
bool IONotifyController::updateThresholdStat( AskThresholdMap& tmap, uniset::ObjectId sid, uniset::ThresholdId tid, const uniset::ConsumerInfo& ci, size_t smCount )
{
auto ti = findThreshold(tmap, sid, tid);
if( !ti )
return false;
uniset::uniset_rwmutex_rlock lock(ti->clst.mut);
for( auto&& c: ti->clst.clst )
{
if( c.id == ci.id && c.node == ci.node )
{
c.smCount += smCount;
return true;
}
}
return false;
}
// --------------------------------------------------------------------------------------------------------------
bool IONotifyController::updateSensorStat( IOController::IOStateList::iterator& it, const ConsumerInfo& ci, size_t smCount )
{
if( it == myioEnd() )
return false;
ConsumerListInfo* clist = nullptr;
if( it->second->userdata[udataConsumerList] )
clist = static_cast<ConsumerListInfo*>(it->second->userdata[udataConsumerList]);
if( !clist )
{
uniset_rwmutex_wrlock lock(askIOMutex);
auto i = askIOList.find(it->second->si.id);
if( i == askIOList.end() )
return false;
}
if( !clist )
return false;
uniset_rwmutex_wrlock lock(clist->mut);
for( auto&& c: clist->clst )
{
if( c.id == ci.id && c.node == ci.node )
{
c.smCount += smCount;
return true;
}
}
return false;
}
// --------------------------------------------------------------------------------------------------------------
bool IONotifyController::addThreshold( ThresholdExtList& lst, ThresholdInfoExt&& ti, const uniset::ConsumerInfo& ci ) bool IONotifyController::addThreshold( ThresholdExtList& lst, ThresholdInfoExt&& ti, const uniset::ConsumerInfo& ci )
{ {
for( auto it = lst.begin(); it != lst.end(); ++it) for( auto it = lst.begin(); it != lst.end(); ++it)
...@@ -959,27 +1179,24 @@ void IONotifyController::checkThreshold( std::shared_ptr<IOController::USensorIn ...@@ -959,27 +1179,24 @@ void IONotifyController::checkThreshold( std::shared_ptr<IOController::USensorIn
} }
} }
// -------------------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------------------
IONotifyController::ThresholdExtList::iterator IONotifyController::findThreshold( const uniset::ObjectId sid, const uniset::ThresholdId tid ) IONotifyController::ThresholdInfoExt* IONotifyController::findThreshold( AskThresholdMap& tmap, const uniset::ObjectId sid, const uniset::ThresholdId tid )
{ {
{ // поиск списка порогов
// lock auto lst = tmap.find(sid);
uniset_rwmutex_rlock lock(trshMutex);
// поиск списка порогов
auto lst = askTMap.find(sid);
if( lst != askTMap.end() ) if( lst != tmap.end() )
{
for( auto it = lst->second.list.begin(); it != lst->second.list.end(); ++it)
{ {
for( auto it = lst->second.list.begin(); it != lst->second.list.end(); ++it) if( it->id == tid )
{ return &(*it);
if( it->id == tid )
return it;
}
} }
} }
return ThresholdExtList::iterator(); return nullptr;
} }
// -------------------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------------------
IONotifyController_i::ThresholdInfo IONotifyController::getThresholdInfo( uniset::ObjectId sid, uniset::ThresholdId tid ) IONotifyController_i::ThresholdInfo IONotifyController::getThresholdInfo( uniset::ObjectId sid, uniset::ThresholdId tid )
{ {
uniset_rwmutex_rlock lock(trshMutex); uniset_rwmutex_rlock lock(trshMutex);
......
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