winlin

add cpuinfo

@@ -201,6 +201,7 @@ int SrsApiSummaries::do_process_request(SrsSocket* skt, SrsHttpMessage* req) @@ -201,6 +201,7 @@ int SrsApiSummaries::do_process_request(SrsSocket* skt, SrsHttpMessage* req)
201 SrsRusage* r = srs_get_system_rusage(); 201 SrsRusage* r = srs_get_system_rusage();
202 SrsProcSelfStat* u = srs_get_self_proc_stat(); 202 SrsProcSelfStat* u = srs_get_self_proc_stat();
203 SrsProcSystemStat* s = srs_get_system_proc_stat(); 203 SrsProcSystemStat* s = srs_get_system_proc_stat();
  204 + SrsCpuInfo* c = srs_get_cpuinfo();
204 205
205 ss << JOBJECT_START 206 ss << JOBJECT_START
206 << JFIELD_ERROR(ERROR_SUCCESS) << JFIELD_CONT 207 << JFIELD_ERROR(ERROR_SUCCESS) << JFIELD_CONT
@@ -211,7 +212,12 @@ int SrsApiSummaries::do_process_request(SrsSocket* skt, SrsHttpMessage* req) @@ -211,7 +212,12 @@ int SrsApiSummaries::do_process_request(SrsSocket* skt, SrsHttpMessage* req)
211 << JFIELD_ORG("rusage_ok", (r->ok? "true":"false")) << JFIELD_CONT 212 << JFIELD_ORG("rusage_ok", (r->ok? "true":"false")) << JFIELD_CONT
212 << JFIELD_ORG("self_cpu_stat_ok", (u->ok? "true":"false")) << JFIELD_CONT 213 << JFIELD_ORG("self_cpu_stat_ok", (u->ok? "true":"false")) << JFIELD_CONT
213 << JFIELD_ORG("system_cpu_stat_ok", (s->ok? "true":"false")) << JFIELD_CONT 214 << JFIELD_ORG("system_cpu_stat_ok", (s->ok? "true":"false")) << JFIELD_CONT
  215 + << JFIELD_ORG("cpuinfo_ok", (c->ok? "true":"false")) << JFIELD_CONT
214 << JFIELD_ORG("mem_kbyte", r->r.ru_maxrss) << JFIELD_CONT 216 << JFIELD_ORG("mem_kbyte", r->r.ru_maxrss) << JFIELD_CONT
  217 + << JFIELD_ORG("system_cpu", s->percent) << JFIELD_CONT
  218 + << JFIELD_ORG("self_cpu", u->percent) << JFIELD_CONT
  219 + << JFIELD_ORG("nb_processors", c->nb_processors) << JFIELD_CONT
  220 + << JFIELD_ORG("nb_processors_online", c->nb_processors_online) << JFIELD_CONT
215 << JFIELD_ORG("ppid", u->ppid) 221 << JFIELD_ORG("ppid", u->ppid)
216 << JOBJECT_END 222 << JOBJECT_END
217 << JOBJECT_END; 223 << JOBJECT_END;
@@ -241,7 +247,8 @@ int SrsApiRusages::do_process_request(SrsSocket* skt, SrsHttpMessage* req) @@ -241,7 +247,8 @@ int SrsApiRusages::do_process_request(SrsSocket* skt, SrsHttpMessage* req)
241 ss << JOBJECT_START 247 ss << JOBJECT_START
242 << JFIELD_ERROR(ERROR_SUCCESS) << JFIELD_CONT 248 << JFIELD_ERROR(ERROR_SUCCESS) << JFIELD_CONT
243 << JFIELD_ORG("data", JOBJECT_START) 249 << JFIELD_ORG("data", JOBJECT_START)
244 - << JFIELD_ORG("rusage_ok", (r->ok? "true":"false")) << JFIELD_CONT 250 + << JFIELD_ORG("ok", (r->ok? "true":"false")) << JFIELD_CONT
  251 + << JFIELD_ORG("sample_time", r->sample_time) << JFIELD_CONT
245 << JFIELD_ORG("ru_utime", r->r.ru_utime.tv_sec) << JFIELD_CONT 252 << JFIELD_ORG("ru_utime", r->r.ru_utime.tv_sec) << JFIELD_CONT
246 << JFIELD_ORG("ru_stime", r->r.ru_stime.tv_sec) << JFIELD_CONT 253 << JFIELD_ORG("ru_stime", r->r.ru_stime.tv_sec) << JFIELD_CONT
247 << JFIELD_ORG("ru_maxrss", r->r.ru_maxrss) << JFIELD_CONT 254 << JFIELD_ORG("ru_maxrss", r->r.ru_maxrss) << JFIELD_CONT
@@ -286,7 +293,9 @@ int SrsApiSelfProcStats::do_process_request(SrsSocket* skt, SrsHttpMessage* req) @@ -286,7 +293,9 @@ int SrsApiSelfProcStats::do_process_request(SrsSocket* skt, SrsHttpMessage* req)
286 ss << JOBJECT_START 293 ss << JOBJECT_START
287 << JFIELD_ERROR(ERROR_SUCCESS) << JFIELD_CONT 294 << JFIELD_ERROR(ERROR_SUCCESS) << JFIELD_CONT
288 << JFIELD_ORG("data", JOBJECT_START) 295 << JFIELD_ORG("data", JOBJECT_START)
289 - << JFIELD_ORG("self_cpu_stat_ok", (u->ok? "true":"false")) << JFIELD_CONT 296 + << JFIELD_ORG("ok", (u->ok? "true":"false")) << JFIELD_CONT
  297 + << JFIELD_ORG("sample_time", u->sample_time) << JFIELD_CONT
  298 + << JFIELD_ORG("percent", u->percent) << JFIELD_CONT
290 << JFIELD_ORG("pid", u->pid) << JFIELD_CONT 299 << JFIELD_ORG("pid", u->pid) << JFIELD_CONT
291 << JFIELD_STR("comm", u->comm) << JFIELD_CONT 300 << JFIELD_STR("comm", u->comm) << JFIELD_CONT
292 << JFIELD_STR("state", u->state) << JFIELD_CONT 301 << JFIELD_STR("state", u->state) << JFIELD_CONT
@@ -359,7 +368,9 @@ int SrsApiSystemProcStats::do_process_request(SrsSocket* skt, SrsHttpMessage* re @@ -359,7 +368,9 @@ int SrsApiSystemProcStats::do_process_request(SrsSocket* skt, SrsHttpMessage* re
359 ss << JOBJECT_START 368 ss << JOBJECT_START
360 << JFIELD_ERROR(ERROR_SUCCESS) << JFIELD_CONT 369 << JFIELD_ERROR(ERROR_SUCCESS) << JFIELD_CONT
361 << JFIELD_ORG("data", JOBJECT_START) 370 << JFIELD_ORG("data", JOBJECT_START)
362 - << JFIELD_ORG("system_cpu_stat_ok", (s->ok? "true":"false")) << JFIELD_CONT 371 + << JFIELD_ORG("ok", (s->ok? "true":"false")) << JFIELD_CONT
  372 + << JFIELD_ORG("sample_time", s->sample_time) << JFIELD_CONT
  373 + << JFIELD_ORG("percent", s->percent) << JFIELD_CONT
363 << JFIELD_ORG("user", s->user) << JFIELD_CONT 374 << JFIELD_ORG("user", s->user) << JFIELD_CONT
364 << JFIELD_ORG("nice", s->nice) << JFIELD_CONT 375 << JFIELD_ORG("nice", s->nice) << JFIELD_CONT
365 << JFIELD_ORG("sys", s->sys) << JFIELD_CONT 376 << JFIELD_ORG("sys", s->sys) << JFIELD_CONT
@@ -56,11 +56,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -56,11 +56,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
56 56
57 // update rusage interval: 57 // update rusage interval:
58 // SRS_SYS_CYCLE_INTERVAL * SRS_SYS_RUSAGE_RESOLUTION_TIMES 58 // SRS_SYS_CYCLE_INTERVAL * SRS_SYS_RUSAGE_RESOLUTION_TIMES
59 -#define SRS_SYS_RUSAGE_RESOLUTION_TIMES 15 59 +#define SRS_SYS_RUSAGE_RESOLUTION_TIMES 30
60 60
61 // update rusage interval: 61 // update rusage interval:
62 // SRS_SYS_CYCLE_INTERVAL * SRS_SYS_CPU_STAT_RESOLUTION_TIMES 62 // SRS_SYS_CYCLE_INTERVAL * SRS_SYS_CPU_STAT_RESOLUTION_TIMES
63 -#define SRS_SYS_CPU_STAT_RESOLUTION_TIMES 15 63 +#define SRS_SYS_CPU_STAT_RESOLUTION_TIMES 30
64 64
65 SrsListener::SrsListener(SrsServer* server, SrsListenerType type) 65 SrsListener::SrsListener(SrsServer* server, SrsListenerType type)
66 { 66 {
@@ -63,6 +63,7 @@ static SrsRusage _srs_system_rusage; @@ -63,6 +63,7 @@ static SrsRusage _srs_system_rusage;
63 SrsRusage::SrsRusage() 63 SrsRusage::SrsRusage()
64 { 64 {
65 ok = false; 65 ok = false;
  66 + sample_time = 0;
66 memset(&r, 0, sizeof(rusage)); 67 memset(&r, 0, sizeof(rusage));
67 } 68 }
68 69
@@ -77,6 +78,9 @@ void srs_update_system_rusage() @@ -77,6 +78,9 @@ void srs_update_system_rusage()
77 srs_warn("getrusage failed, ignore"); 78 srs_warn("getrusage failed, ignore");
78 return; 79 return;
79 } 80 }
  81 +
  82 + srs_update_system_time_ms();
  83 + _srs_system_rusage.sample_time = srs_get_system_time_ms();
80 84
81 _srs_system_rusage.ok = true; 85 _srs_system_rusage.ok = true;
82 } 86 }
@@ -87,11 +91,70 @@ static SrsProcSystemStat _srs_system_cpu_system_stat; @@ -87,11 +91,70 @@ static SrsProcSystemStat _srs_system_cpu_system_stat;
87 SrsProcSelfStat::SrsProcSelfStat() 91 SrsProcSelfStat::SrsProcSelfStat()
88 { 92 {
89 ok = false; 93 ok = false;
  94 + sample_time = 0;
  95 + percent = 0;
  96 +
  97 + pid = 0;
  98 + memset(comm, 0, sizeof(comm));
  99 + state = 0;
  100 + ppid = 0;
  101 + pgrp = 0;
  102 + session = 0;
  103 + tty_nr = 0;
  104 + tpgid = 0;
  105 + flags = 0;
  106 + minflt = 0;
  107 + cminflt = 0;
  108 + majflt = 0;
  109 + cmajflt = 0;
  110 + utime = 0;
  111 + stime = 0;
  112 + cutime = 0;
  113 + cstime = 0;
  114 + priority = 0;
  115 + nice = 0;
  116 + num_threads = 0;
  117 + itrealvalue = 0;
  118 + starttime = 0;
  119 + vsize = 0;
  120 + rss = 0;
  121 + rsslim = 0;
  122 + startcode = 0;
  123 + endcode = 0;
  124 + startstack = 0;
  125 + kstkesp = 0;
  126 + kstkeip = 0;
  127 + signal = 0;
  128 + blocked = 0;
  129 + sigignore = 0;
  130 + sigcatch = 0;
  131 + wchan = 0;
  132 + nswap = 0;
  133 + cnswap = 0;
  134 + exit_signal = 0;
  135 + processor = 0;
  136 + rt_priority = 0;
  137 + policy = 0;
  138 + delayacct_blkio_ticks = 0;
  139 + guest_time = 0;
  140 + cguest_time = 0;
90 } 141 }
91 142
92 SrsProcSystemStat::SrsProcSystemStat() 143 SrsProcSystemStat::SrsProcSystemStat()
93 { 144 {
94 ok = false; 145 ok = false;
  146 + sample_time = 0;
  147 + percent = 0;
  148 + memset(label, 0, sizeof(label));
  149 + user = 0;
  150 + nice = 0;
  151 + sys = 0;
  152 + idle = 0;
  153 + iowait = 0;
  154 + irq = 0;
  155 + softirq = 0;
  156 + steal = 0;
  157 + guest = 0;
95 } 158 }
96 159
97 SrsProcSelfStat* srs_get_self_proc_stat() 160 SrsProcSelfStat* srs_get_self_proc_stat()
@@ -104,69 +167,145 @@ SrsProcSystemStat* srs_get_system_proc_stat() @@ -104,69 +167,145 @@ SrsProcSystemStat* srs_get_system_proc_stat()
104 return &_srs_system_cpu_system_stat; 167 return &_srs_system_cpu_system_stat;
105 } 168 }
106 169
  170 +bool get_proc_system_stat(SrsProcSystemStat& r)
  171 +{
  172 + FILE* f = fopen("/proc/stat", "r");
  173 + if (f == NULL) {
  174 + srs_warn("open system cpu stat failed, ignore");
  175 + return false;
  176 + }
  177 +
  178 + for (;;) {
  179 + int ret = fscanf(f, "%4s %lu %lu %lu %lu %lu "
  180 + "%lu %lu %lu %lu\n",
  181 + r.label, &r.user, &r.nice, &r.sys, &r.idle, &r.iowait,
  182 + &r.irq, &r.softirq, &r.steal, &r.guest);
  183 + r.ok = false;
  184 +
  185 + if (ret == EOF) {
  186 + break;
  187 + }
  188 +
  189 + if (strcmp("cpu", r.label) == 0) {
  190 + r.ok = true;
  191 + break;
  192 + }
  193 + }
  194 +
  195 + fclose(f);
  196 +
  197 + return r.ok;
  198 +}
  199 +
  200 +bool get_proc_self_stat(SrsProcSelfStat& r)
  201 +{
  202 + FILE* f = fopen("/proc/self/stat", "r");
  203 + if (f == NULL) {
  204 + srs_warn("open self cpu stat failed, ignore");
  205 + return false;
  206 + }
  207 +
  208 + int ret = fscanf(f, "%d %32s %c %d %d %d %d "
  209 + "%d %u %lu %lu %lu %lu "
  210 + "%lu %lu %ld %ld %ld %ld "
  211 + "%ld %ld %llu %lu %ld "
  212 + "%lu %lu %lu %lu %lu "
  213 + "%lu %lu %lu %lu %lu "
  214 + "%lu %lu %lu %d %d "
  215 + "%u %u %llu "
  216 + "%lu %ld",
  217 + &r.pid, r.comm, &r.state, &r.ppid, &r.pgrp, &r.session, &r.tty_nr,
  218 + &r.tpgid, &r.flags, &r.minflt, &r.cminflt, &r.majflt, &r.cmajflt,
  219 + &r.utime, &r.stime, &r.cutime, &r.cstime, &r.priority, &r.nice,
  220 + &r.num_threads, &r.itrealvalue, &r.starttime, &r.vsize, &r.rss,
  221 + &r.rsslim, &r.startcode, &r.endcode, &r.startstack, &r.kstkesp,
  222 + &r.kstkeip, &r.signal, &r.blocked, &r.sigignore, &r.sigcatch,
  223 + &r.wchan, &r.nswap, &r.cnswap, &r.exit_signal, &r.processor,
  224 + &r.rt_priority, &r.policy, &r.delayacct_blkio_ticks,
  225 + &r.guest_time, &r.cguest_time);
  226 +
  227 + if (ret >= 0) {
  228 + r.ok = true;
  229 + }
  230 +
  231 + fclose(f);
  232 +
  233 + return r.ok;
  234 +}
  235 +
107 void srs_update_proc_stat() 236 void srs_update_proc_stat()
108 { 237 {
  238 + srs_update_system_time_ms();
  239 +
109 // system cpu stat 240 // system cpu stat
110 if (true) { 241 if (true) {
111 - FILE* f = fopen("/proc/stat", "r");  
112 - if (f == NULL) {  
113 - srs_warn("open system cpu stat failed, ignore"); 242 + SrsProcSystemStat r;
  243 + if (!get_proc_system_stat(r)) {
114 return; 244 return;
115 } 245 }
116 246
117 - SrsProcSystemStat& r = _srs_system_cpu_system_stat;  
118 - for (;;) {  
119 - int ret = fscanf(f, "%4s %lu %lu %lu %lu %lu "  
120 - "%lu %lu %lu %lu\n",  
121 - r.label, &r.user, &r.nice, &r.sys, &r.idle, &r.iowait,  
122 - &r.irq, &r.softirq, &r.steal, &r.guest);  
123 - r.ok = false;  
124 -  
125 - if (ret == EOF) {  
126 - break;  
127 - }  
128 -  
129 - if (strcmp("cpu", r.label) == 0) {  
130 - r.ok = true;  
131 - break;  
132 - } 247 + r.sample_time = srs_get_system_time_ms();
  248 +
  249 + // calc usage in percent
  250 + SrsProcSystemStat& o = _srs_system_cpu_system_stat;
  251 +
  252 + // @see: http://blog.csdn.net/nineday/article/details/1928847
  253 + int64_t total = (r.user + r.nice + r.sys + r.idle + r.iowait + r.irq + r.softirq + r.steal + r.guest)
  254 + - (o.user + o.nice + o.sys + o.idle + o.iowait + o.irq + o.softirq + o.steal + o.guest);
  255 + int64_t idle = r.idle - o.idle;
  256 + if (total > 0) {
  257 + r.percent = (float)(1 - idle / (double)total);
133 } 258 }
134 259
135 - fclose(f); 260 + // upate cache.
  261 + _srs_system_cpu_system_stat = r;
136 } 262 }
137 263
138 // self cpu stat 264 // self cpu stat
139 if (true) { 265 if (true) {
140 - FILE* f = fopen("/proc/self/stat", "r");  
141 - if (f == NULL) {  
142 - srs_warn("open self cpu stat failed, ignore"); 266 + SrsProcSelfStat r;
  267 + if (!get_proc_self_stat(r)) {
143 return; 268 return;
144 } 269 }
145 270
146 - SrsProcSelfStat& r = _srs_system_cpu_self_stat;  
147 - int ret = fscanf(f, "%d %32s %c %d %d %d %d "  
148 - "%d %u %lu %lu %lu %lu "  
149 - "%lu %lu %ld %ld %ld %ld "  
150 - "%ld %ld %llu %lu %ld "  
151 - "%lu %lu %lu %lu %lu "  
152 - "%lu %lu %lu %lu %lu "  
153 - "%lu %lu %lu %d %d "  
154 - "%u %u %llu "  
155 - "%lu %ld",  
156 - &r.pid, r.comm, &r.state, &r.ppid, &r.pgrp, &r.session, &r.tty_nr,  
157 - &r.tpgid, &r.flags, &r.minflt, &r.cminflt, &r.majflt, &r.cmajflt,  
158 - &r.utime, &r.stime, &r.cutime, &r.cstime, &r.priority, &r.nice,  
159 - &r.num_threads, &r.itrealvalue, &r.starttime, &r.vsize, &r.rss,  
160 - &r.rsslim, &r.startcode, &r.endcode, &r.startstack, &r.kstkesp,  
161 - &r.kstkeip, &r.signal, &r.blocked, &r.sigignore, &r.sigcatch,  
162 - &r.wchan, &r.nswap, &r.cnswap, &r.exit_signal, &r.processor,  
163 - &r.rt_priority, &r.policy, &r.delayacct_blkio_ticks,  
164 - &r.guest_time, &r.cguest_time);  
165 -  
166 - if (ret >= 0) {  
167 - r.ok = true; 271 + srs_update_system_time_ms();
  272 + r.sample_time = srs_get_system_time_ms();
  273 +
  274 + // calc usage in percent
  275 + SrsProcSelfStat& o = _srs_system_cpu_self_stat;
  276 +
  277 + // @see: http://stackoverflow.com/questions/16011677/calculating-cpu-usage-using-proc-files
  278 + int64_t total = r.sample_time - o.sample_time;
  279 + int64_t usage = (r.utime + r.stime) - (o.utime + o.stime);
  280 + if (total > 0) {
  281 + r.percent = (float)(usage * 1000 / (double)total / 100);
168 } 282 }
169 283
170 - fclose(f); 284 + // upate cache.
  285 + _srs_system_cpu_self_stat = r;
171 } 286 }
172 } 287 }
  288 +
  289 +SrsCpuInfo::SrsCpuInfo()
  290 +{
  291 + ok = false;
  292 +
  293 + nb_processors = 0;
  294 + nb_processors_online = 0;
  295 +}
  296 +
  297 +SrsCpuInfo* srs_get_cpuinfo()
  298 +{
  299 + static SrsCpuInfo* cpu = NULL;
  300 + if (cpu != NULL) {
  301 + return cpu;
  302 + }
  303 +
  304 + // initialize cpu info.
  305 + cpu = new SrsCpuInfo();
  306 + cpu->ok = true;
  307 + cpu->nb_processors = sysconf(_SC_NPROCESSORS_CONF);
  308 + cpu->nb_processors_online = sysconf(_SC_NPROCESSORS_ONLN);
  309 +
  310 + return cpu;
  311 +}
@@ -40,7 +40,11 @@ extern void srs_update_system_time_ms(); @@ -40,7 +40,11 @@ extern void srs_update_system_time_ms();
40 // @see: man getrusage 40 // @see: man getrusage
41 struct SrsRusage 41 struct SrsRusage
42 { 42 {
  43 + // whether the data is ok.
43 bool ok; 44 bool ok;
  45 + // the time in ms when sample.
  46 + int64_t sample_time;
  47 +
44 rusage r; 48 rusage r;
45 49
46 SrsRusage(); 50 SrsRusage();
@@ -56,6 +60,10 @@ struct SrsProcSelfStat @@ -56,6 +60,10 @@ struct SrsProcSelfStat
56 { 60 {
57 // whether the data is ok. 61 // whether the data is ok.
58 bool ok; 62 bool ok;
  63 + // the time in ms when sample.
  64 + int64_t sample_time;
  65 + // the percent of usage. 0.153 is 15.3%.
  66 + float percent;
59 67
60 // pid %d The process ID. 68 // pid %d The process ID.
61 int pid; 69 int pid;
@@ -203,6 +211,10 @@ struct SrsProcSystemStat @@ -203,6 +211,10 @@ struct SrsProcSystemStat
203 { 211 {
204 // whether the data is ok. 212 // whether the data is ok.
205 bool ok; 213 bool ok;
  214 + // the time in ms when sample.
  215 + int64_t sample_time;
  216 + // the percent of usage. 0.153 is 15.3%.
  217 + float percent;
206 218
207 // always be cpu 219 // always be cpu
208 char label[32]; 220 char label[32];
@@ -248,4 +260,21 @@ extern SrsProcSystemStat* srs_get_system_proc_stat(); @@ -248,4 +260,21 @@ extern SrsProcSystemStat* srs_get_system_proc_stat();
248 // the deamon st-thread will update it. 260 // the deamon st-thread will update it.
249 extern void srs_update_proc_stat(); 261 extern void srs_update_proc_stat();
250 262
  263 +// @see: cat /proc/cpuinfo
  264 +struct SrsCpuInfo
  265 +{
  266 + // whether the data is ok.
  267 + bool ok;
  268 +
  269 + // The number of processors configured.
  270 + int nb_processors;
  271 + // The number of processors currently online (available).
  272 + int nb_processors_online;
  273 +
  274 + SrsCpuInfo();
  275 +};
  276 +
  277 +// get system cpu info, use cache to avoid performance problem.
  278 +extern SrsCpuInfo* srs_get_cpuinfo();
  279 +
251 #endif 280 #endif