Line data Source code
1 :
2 : #include <wfc/iinterface.hpp>
3 : #include <wfc/statistics/meters.hpp>
4 : #include "system_statistics_domain.hpp"
5 : #include "impl/get_procstat.hpp"
6 : namespace wfc{ namespace core{
7 :
8 0 : struct protostat
9 : {
10 : typedef ::wfc::value_meter meter_type;
11 : meter_type utime; /** user mode jiffies **/
12 : meter_type stime; /** kernel mode jiffies **/
13 : meter_type vsize; /** Virtual memory size **/
14 : meter_type rss; /** Resident Set Size **/
15 : int pid = 0;
16 : procstat ps;
17 : };
18 :
19 : class procmeter
20 : {
21 : typedef protostat::meter_type meter_type;
22 : typedef std::mutex mutex_type;
23 : public:
24 : procmeter(std::weak_ptr<wfc::statistics::statistics> stat, const std::string& prefix)
25 : : _prefix(prefix)
26 : , _wstat(stat)
27 : , _procstat()
28 : {
29 : }
30 :
31 : void initialize( )
32 : {
33 : std::lock_guard<mutex_type> lk(_mutext);
34 : _threads.clear();
35 : _procstat = this->create_protostat_("", -1);
36 : _procstat.pid = ::getpid();
37 : }
38 :
39 : void add_threads( std::string name, std::vector<pid_t> ids )
40 : {
41 : std::lock_guard<mutex_type> lk(_mutext);
42 : for (size_t i=0; i < ids.size(); ++i)
43 : {
44 : _threads.push_back( this->create_protostat_( name, static_cast<int>(i) ) );
45 : _threads.back().pid = ids[i];
46 : }
47 : }
48 :
49 : void perform()
50 : {
51 : std::lock_guard<mutex_type> lk(_mutext);
52 : this->perform_( &_procstat );
53 : for ( auto& t : _threads )
54 : this->perform_( &t );
55 : }
56 :
57 :
58 : private:
59 : void perform_( protostat* proto )
60 : {
61 : if ( auto stat = _wstat.lock() )
62 : {
63 : procstat ps;
64 : if ( 0==get_procstat(proto->pid, &ps) )
65 : {
66 : if ( proto->ps.utime != 0 || true)
67 : proto->utime.create( static_cast<wrtstat::value_type>(0), static_cast<wrtstat::size_type>(ps.utime - proto->ps.utime) );
68 : if ( proto->ps.stime != 0 )
69 : proto->stime.create( static_cast<wrtstat::value_type>(0), static_cast<wrtstat::size_type>(ps.stime - proto->ps.stime) );
70 : proto->vsize.create(
71 : static_cast<wrtstat::value_type>( static_cast<int>(ps.vsize)*getpagesize()),
72 : static_cast<wrtstat::size_type>(0)
73 : );
74 : proto->rss.create(
75 : static_cast<wrtstat::value_type>( static_cast<int>(ps.rss)*getpagesize()),
76 : static_cast<wrtstat::size_type>(0)
77 : );
78 : proto->ps = ps;
79 : }
80 : }
81 : }
82 :
83 : protostat create_protostat_(std::string name, int pid)
84 : {
85 : protostat proto;
86 : proto.utime = this->create_meter_(pid, name, "utime");
87 : proto.stime = this->create_meter_(pid, name, "stime");
88 : proto.vsize = this->create_meter_(pid, name, "vsize");
89 : proto.rss= this->create_meter_(pid, name, "rss");
90 : return proto;
91 : }
92 :
93 : value_meter create_meter_( int id, const std::string& group, const std::string& name)
94 : {
95 : if ( auto stat = _wstat.lock() )
96 : {
97 : std::stringstream ss;
98 : ss << _prefix << group;
99 : if ( id != -1 )
100 : ss << "thread" << id << ".";
101 : ss << name;
102 : return stat->create_value_meter(ss.str());
103 : }
104 : return value_meter();
105 : }
106 : private:
107 : std::string _prefix;
108 : std::weak_ptr<wfc::statistics::statistics> _wstat;
109 : protostat _procstat;
110 : std::vector<protostat> _threads;
111 : mutex_type _mutext;
112 : };
113 :
114 0 : void system_statistics_domain::configure()
115 : {
116 :
117 0 : }
118 :
119 0 : void system_statistics_domain::stop()
120 : {
121 0 : this->get_workflow()->release_timer(_timer_id);
122 0 : }
123 :
124 :
125 :
126 0 : void system_statistics_domain::restart()
127 : {
128 0 : this->get_workflow()->release_timer(_timer_id);
129 0 : _timer_id = -1;
130 :
131 0 : auto stat = this->get_statistics();
132 0 : if ( stat == nullptr )
133 0 : return;
134 :
135 0 : auto prefix = this->statistics_options().prefix;
136 0 : auto proto = std::make_shared<protostat>();
137 0 : proto->utime = stat->create_value_meter(prefix + "utime");
138 0 : proto->stime = stat->create_value_meter(prefix + "stime");
139 0 : proto->vsize = stat->create_value_meter(prefix + "vsize");
140 0 : proto->rss= stat->create_value_meter(prefix + "rss");
141 :
142 0 : _timer_id = this->get_workflow()->create_timer(
143 0 : std::chrono::milliseconds( this->statistics_options().interval_ms ),
144 0 : [stat, proto]()->bool
145 : {
146 : procstat ps;
147 0 : if ( 0==get_procstat(&ps) )
148 : {
149 0 : if ( proto->ps.utime != 0 )
150 0 : proto->utime.create(
151 : static_cast<wrtstat::value_type>(0),
152 0 : static_cast<wrtstat::size_type>(ps.utime - proto->ps.utime) );
153 0 : if ( proto->ps.stime != 0 )
154 0 : proto->stime.create(
155 : static_cast<wrtstat::value_type>(0),
156 0 : static_cast<wrtstat::size_type>(ps.stime - proto->ps.stime) );
157 0 : proto->vsize.create(
158 0 : static_cast<wrtstat::value_type>( static_cast<int>(ps.vsize)*getpagesize()/(1024*1024)),
159 : static_cast<wrtstat::size_type>(0)
160 0 : );
161 0 : proto->rss.create(
162 0 : static_cast<wrtstat::value_type>( static_cast<int>(ps.rss)*getpagesize()/(1024*1024)),
163 : static_cast<wrtstat::size_type>(0)
164 0 : );
165 0 : proto->ps = ps;
166 : }
167 0 : return true;
168 : }
169 0 : );
170 :
171 :
172 : }
173 :
174 3 : }}
|