winlin

add meminfo

@@ -120,6 +120,7 @@ SrsApiV1::SrsApiV1() @@ -120,6 +120,7 @@ SrsApiV1::SrsApiV1()
120 handlers.push_back(new SrsApiRusages()); 120 handlers.push_back(new SrsApiRusages());
121 handlers.push_back(new SrsApiSelfProcStats()); 121 handlers.push_back(new SrsApiSelfProcStats());
122 handlers.push_back(new SrsApiSystemProcStats()); 122 handlers.push_back(new SrsApiSystemProcStats());
  123 + handlers.push_back(new SrsApiMemInfos());
123 handlers.push_back(new SrsApiAuthors()); 124 handlers.push_back(new SrsApiAuthors());
124 } 125 }
125 126
@@ -144,6 +145,7 @@ int SrsApiV1::do_process_request(SrsSocket* skt, SrsHttpMessage* req) @@ -144,6 +145,7 @@ int SrsApiV1::do_process_request(SrsSocket* skt, SrsHttpMessage* req)
144 << JFIELD_STR("rusages", "the rusage of SRS") << JFIELD_CONT 145 << JFIELD_STR("rusages", "the rusage of SRS") << JFIELD_CONT
145 << JFIELD_STR("self_proc_stats", "the self process stats") << JFIELD_CONT 146 << JFIELD_STR("self_proc_stats", "the self process stats") << JFIELD_CONT
146 << JFIELD_STR("system_proc_stats", "the system process stats") << JFIELD_CONT 147 << JFIELD_STR("system_proc_stats", "the system process stats") << JFIELD_CONT
  148 + << JFIELD_STR("meminfos", "the meminfo of system") << JFIELD_CONT
147 << JFIELD_STR("authors", "the primary authors and contributors") 149 << JFIELD_STR("authors", "the primary authors and contributors")
148 << JOBJECT_END 150 << JOBJECT_END
149 << JOBJECT_END; 151 << JOBJECT_END;
@@ -202,23 +204,39 @@ int SrsApiSummaries::do_process_request(SrsSocket* skt, SrsHttpMessage* req) @@ -202,23 +204,39 @@ int SrsApiSummaries::do_process_request(SrsSocket* skt, SrsHttpMessage* req)
202 SrsProcSelfStat* u = srs_get_self_proc_stat(); 204 SrsProcSelfStat* u = srs_get_self_proc_stat();
203 SrsProcSystemStat* s = srs_get_system_proc_stat(); 205 SrsProcSystemStat* s = srs_get_system_proc_stat();
204 SrsCpuInfo* c = srs_get_cpuinfo(); 206 SrsCpuInfo* c = srs_get_cpuinfo();
  207 + SrsMemInfo* m = srs_get_meminfo();
  208 +
  209 + float self_mem_percent = 0;
  210 + if (m->MemTotal > 0) {
  211 + self_mem_percent = (float)(r->r.ru_maxrss / (double)m->MemTotal);
  212 + }
205 213
206 ss << JOBJECT_START 214 ss << JOBJECT_START
207 << JFIELD_ERROR(ERROR_SUCCESS) << JFIELD_CONT 215 << JFIELD_ERROR(ERROR_SUCCESS) << JFIELD_CONT
208 << JFIELD_ORG("data", JOBJECT_START) 216 << JFIELD_ORG("data", JOBJECT_START)
209 - << JFIELD_ORG("pid", getpid()) << JFIELD_CONT  
210 - << JFIELD_STR("argv", _srs_config->get_argv()) << JFIELD_CONT  
211 - << JFIELD_STR("cwd", _srs_config->get_cwd()) << JFIELD_CONT  
212 << JFIELD_ORG("rusage_ok", (r->ok? "true":"false")) << JFIELD_CONT 217 << JFIELD_ORG("rusage_ok", (r->ok? "true":"false")) << JFIELD_CONT
213 << JFIELD_ORG("self_cpu_stat_ok", (u->ok? "true":"false")) << JFIELD_CONT 218 << JFIELD_ORG("self_cpu_stat_ok", (u->ok? "true":"false")) << JFIELD_CONT
214 << JFIELD_ORG("system_cpu_stat_ok", (s->ok? "true":"false")) << JFIELD_CONT 219 << JFIELD_ORG("system_cpu_stat_ok", (s->ok? "true":"false")) << JFIELD_CONT
215 << JFIELD_ORG("cpuinfo_ok", (c->ok? "true":"false")) << JFIELD_CONT 220 << JFIELD_ORG("cpuinfo_ok", (c->ok? "true":"false")) << 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  
221 - << JFIELD_ORG("ppid", u->ppid) 221 + << JFIELD_ORG("meminfo_ok", (m->ok? "true":"false")) << JFIELD_CONT
  222 + << JFIELD_ORG("self", JOBJECT_START)
  223 + << JFIELD_ORG("pid", getpid()) << JFIELD_CONT
  224 + << JFIELD_ORG("ppid", u->ppid) << JFIELD_CONT
  225 + << JFIELD_STR("argv", _srs_config->get_argv()) << JFIELD_CONT
  226 + << JFIELD_STR("cwd", _srs_config->get_cwd()) << JFIELD_CONT
  227 + << JFIELD_ORG("mem_kbyte", r->r.ru_maxrss) << JFIELD_CONT
  228 + << JFIELD_ORG("mem_percent", self_mem_percent) << JFIELD_CONT
  229 + << JFIELD_ORG("cpu_percent", u->percent)
  230 + << JOBJECT_END << JFIELD_CONT
  231 + << JFIELD_ORG("system", JOBJECT_START)
  232 + << JFIELD_ORG("cpu_percent", s->percent) << JFIELD_CONT
  233 + << JFIELD_ORG("mem_ram_kbyte", m->MemTotal) << JFIELD_CONT
  234 + << JFIELD_ORG("mem_ram_percent", m->percent_ram) << JFIELD_CONT
  235 + << JFIELD_ORG("mem_swap_kbyte", m->SwapTotal) << JFIELD_CONT
  236 + << JFIELD_ORG("mem_swap_percent", m->percent_swap) << JFIELD_CONT
  237 + << JFIELD_ORG("nb_processors", c->nb_processors) << JFIELD_CONT
  238 + << JFIELD_ORG("nb_processors_online", c->nb_processors_online)
  239 + << JOBJECT_END
222 << JOBJECT_END 240 << JOBJECT_END
223 << JOBJECT_END; 241 << JOBJECT_END;
224 242
@@ -386,6 +404,47 @@ int SrsApiSystemProcStats::do_process_request(SrsSocket* skt, SrsHttpMessage* re @@ -386,6 +404,47 @@ int SrsApiSystemProcStats::do_process_request(SrsSocket* skt, SrsHttpMessage* re
386 return res_json(skt, req, ss.str()); 404 return res_json(skt, req, ss.str());
387 } 405 }
388 406
  407 +SrsApiMemInfos::SrsApiMemInfos()
  408 +{
  409 +}
  410 +
  411 +SrsApiMemInfos::~SrsApiMemInfos()
  412 +{
  413 +}
  414 +
  415 +bool SrsApiMemInfos::can_handle(const char* path, int length, const char** /*pchild*/)
  416 +{
  417 + return srs_path_equals("/meminfos", path, length);
  418 +}
  419 +
  420 +int SrsApiMemInfos::do_process_request(SrsSocket* skt, SrsHttpMessage* req)
  421 +{
  422 + std::stringstream ss;
  423 +
  424 + SrsMemInfo* m = srs_get_meminfo();
  425 +
  426 + ss << JOBJECT_START
  427 + << JFIELD_ERROR(ERROR_SUCCESS) << JFIELD_CONT
  428 + << JFIELD_ORG("data", JOBJECT_START)
  429 + << JFIELD_ORG("ok", (m->ok? "true":"false")) << JFIELD_CONT
  430 + << JFIELD_ORG("sample_time", m->sample_time) << JFIELD_CONT
  431 + << JFIELD_ORG("percent_ram", m->percent_ram) << JFIELD_CONT
  432 + << JFIELD_ORG("percent_swap", m->percent_swap) << JFIELD_CONT
  433 + << JFIELD_ORG("MemActive", m->MemActive) << JFIELD_CONT
  434 + << JFIELD_ORG("RealInUse", m->RealInUse) << JFIELD_CONT
  435 + << JFIELD_ORG("NotInUse", m->NotInUse) << JFIELD_CONT
  436 + << JFIELD_ORG("MemTotal", m->MemTotal) << JFIELD_CONT
  437 + << JFIELD_ORG("MemFree", m->MemFree) << JFIELD_CONT
  438 + << JFIELD_ORG("Buffers", m->Buffers) << JFIELD_CONT
  439 + << JFIELD_ORG("Cached", m->Cached) << JFIELD_CONT
  440 + << JFIELD_ORG("SwapTotal", m->SwapTotal) << JFIELD_CONT
  441 + << JFIELD_ORG("SwapFree", m->SwapFree)
  442 + << JOBJECT_END
  443 + << JOBJECT_END;
  444 +
  445 + return res_json(skt, req, ss.str());
  446 +}
  447 +
389 SrsApiAuthors::SrsApiAuthors() 448 SrsApiAuthors::SrsApiAuthors()
390 { 449 {
391 } 450 }
@@ -131,6 +131,17 @@ protected: @@ -131,6 +131,17 @@ protected:
131 virtual int do_process_request(SrsSocket* skt, SrsHttpMessage* req); 131 virtual int do_process_request(SrsSocket* skt, SrsHttpMessage* req);
132 }; 132 };
133 133
  134 +class SrsApiMemInfos : public SrsHttpHandler
  135 +{
  136 +public:
  137 + SrsApiMemInfos();
  138 + virtual ~SrsApiMemInfos();
  139 +public:
  140 + virtual bool can_handle(const char* path, int length, const char** pchild);
  141 +protected:
  142 + virtual int do_process_request(SrsSocket* skt, SrsHttpMessage* req);
  143 +};
  144 +
134 class SrsApiAuthors : public SrsHttpHandler 145 class SrsApiAuthors : public SrsHttpHandler
135 { 146 {
136 public: 147 public:
@@ -48,6 +48,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -48,6 +48,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
48 #define SERVER_LISTEN_BACKLOG 512 48 #define SERVER_LISTEN_BACKLOG 512
49 49
50 // system interval 50 // system interval
  51 +// all resolution times should be times togother,
  52 +// for example, system-time is 3(300ms),
  53 +// then rusage can be 3*x, for instance, 3*10=30(3s),
  54 +// the meminfo canbe 30*x, for instance, 30*2=60(6s)
51 #define SRS_SYS_CYCLE_INTERVAL 100 55 #define SRS_SYS_CYCLE_INTERVAL 100
52 56
53 // update time interval: 57 // update time interval:
@@ -62,6 +66,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -62,6 +66,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
62 // SRS_SYS_CYCLE_INTERVAL * SRS_SYS_CPU_STAT_RESOLUTION_TIMES 66 // SRS_SYS_CYCLE_INTERVAL * SRS_SYS_CPU_STAT_RESOLUTION_TIMES
63 #define SRS_SYS_CPU_STAT_RESOLUTION_TIMES 30 67 #define SRS_SYS_CPU_STAT_RESOLUTION_TIMES 30
64 68
  69 +// update rusage interval:
  70 +// SRS_SYS_CYCLE_INTERVAL * SRS_SYS_MEMINFO_RESOLUTION_TIMES
  71 +#define SRS_SYS_MEMINFO_RESOLUTION_TIMES 60
  72 +
65 SrsListener::SrsListener(SrsServer* server, SrsListenerType type) 73 SrsListener::SrsListener(SrsServer* server, SrsListenerType type)
66 { 74 {
67 fd = -1; 75 fd = -1;
@@ -411,6 +419,7 @@ int SrsServer::cycle() @@ -411,6 +419,7 @@ int SrsServer::cycle()
411 int max = srs_max(0, SRS_SYS_TIME_RESOLUTION_MS_TIMES); 419 int max = srs_max(0, SRS_SYS_TIME_RESOLUTION_MS_TIMES);
412 max = srs_max(max, SRS_SYS_RUSAGE_RESOLUTION_TIMES); 420 max = srs_max(max, SRS_SYS_RUSAGE_RESOLUTION_TIMES);
413 max = srs_max(max, SRS_SYS_CPU_STAT_RESOLUTION_TIMES); 421 max = srs_max(max, SRS_SYS_CPU_STAT_RESOLUTION_TIMES);
  422 + max = srs_max(max, SRS_SYS_MEMINFO_RESOLUTION_TIMES);
414 423
415 // the deamon thread, update the time cache 424 // the deamon thread, update the time cache
416 while (true) { 425 while (true) {
@@ -440,15 +449,18 @@ int SrsServer::cycle() @@ -440,15 +449,18 @@ int SrsServer::cycle()
440 } 449 }
441 450
442 // update the cache time or rusage. 451 // update the cache time or rusage.
443 - if (i == SRS_SYS_TIME_RESOLUTION_MS_TIMES) { 452 + if ((i % SRS_SYS_TIME_RESOLUTION_MS_TIMES) == 0) {
444 srs_update_system_time_ms(); 453 srs_update_system_time_ms();
445 } 454 }
446 - if (i == SRS_SYS_RUSAGE_RESOLUTION_TIMES) { 455 + if ((i % SRS_SYS_RUSAGE_RESOLUTION_TIMES) == 0) {
447 srs_update_system_rusage(); 456 srs_update_system_rusage();
448 } 457 }
449 - if (i == SRS_SYS_CPU_STAT_RESOLUTION_TIMES) { 458 + if ((i % SRS_SYS_CPU_STAT_RESOLUTION_TIMES) == 0) {
450 srs_update_proc_stat(); 459 srs_update_proc_stat();
451 } 460 }
  461 + if ((i % SRS_SYS_MEMINFO_RESOLUTION_TIMES) == 0) {
  462 + srs_update_meminfo();
  463 + }
452 } 464 }
453 } 465 }
454 466
@@ -286,6 +286,84 @@ void srs_update_proc_stat() @@ -286,6 +286,84 @@ void srs_update_proc_stat()
286 } 286 }
287 } 287 }
288 288
  289 +SrsMemInfo::SrsMemInfo()
  290 +{
  291 + ok = false;
  292 + sample_time = 0;
  293 +
  294 + percent_ram = 0;
  295 + percent_swap = 0;
  296 +
  297 + MemActive = 0;
  298 + RealInUse = 0;
  299 + NotInUse = 0;
  300 + MemTotal = 0;
  301 + MemFree = 0;
  302 + Buffers = 0;
  303 + Cached = 0;
  304 + SwapTotal = 0;
  305 + SwapFree = 0;
  306 +}
  307 +
  308 +static SrsMemInfo _srs_system_meminfo;
  309 +
  310 +SrsMemInfo* srs_get_meminfo()
  311 +{
  312 + return &_srs_system_meminfo;
  313 +}
  314 +
  315 +void srs_update_meminfo()
  316 +{
  317 + FILE* f = fopen("/proc/meminfo", "r");
  318 + if (f == NULL) {
  319 + srs_warn("open meminfo failed, ignore");
  320 + return;
  321 + }
  322 +
  323 + SrsMemInfo& r = _srs_system_meminfo;
  324 + r.ok = false;
  325 +
  326 + for (;;) {
  327 + static char label[64];
  328 + static unsigned long value;
  329 + static char postfix[64];
  330 + int ret = fscanf(f, "%64s %lu %64s\n", label, &value, postfix);
  331 +
  332 + if (ret == EOF) {
  333 + break;
  334 + }
  335 +
  336 + if (strcmp("MemTotal:", label) == 0) {
  337 + r.MemTotal = value;
  338 + } else if (strcmp("MemFree:", label) == 0) {
  339 + r.MemFree = value;
  340 + } else if (strcmp("Buffers:", label) == 0) {
  341 + r.Buffers = value;
  342 + } else if (strcmp("Cached:", label) == 0) {
  343 + r.Cached = value;
  344 + } else if (strcmp("SwapTotal:", label) == 0) {
  345 + r.SwapTotal = value;
  346 + } else if (strcmp("SwapFree:", label) == 0) {
  347 + r.SwapFree = value;
  348 + }
  349 + }
  350 +
  351 + r.sample_time = srs_get_system_time_ms();
  352 + r.MemActive = r.MemTotal - r.MemFree;
  353 + r.RealInUse = r.MemActive - r.Buffers - r.Cached;
  354 + r.NotInUse = r.MemTotal - r.RealInUse;
  355 +
  356 + r.ok = true;
  357 + if (r.MemTotal > 0) {
  358 + r.percent_ram = (float)(r.RealInUse / (double)r.MemTotal);
  359 + }
  360 + if (r.SwapTotal > 0) {
  361 + r.percent_swap = (float)((r.SwapTotal - r.SwapFree) / (double)r.SwapTotal);
  362 + }
  363 +
  364 + fclose(f);
  365 +}
  366 +
289 SrsCpuInfo::SrsCpuInfo() 367 SrsCpuInfo::SrsCpuInfo()
290 { 368 {
291 ok = false; 369 ok = false;
@@ -260,6 +260,42 @@ extern SrsProcSystemStat* srs_get_system_proc_stat(); @@ -260,6 +260,42 @@ extern SrsProcSystemStat* srs_get_system_proc_stat();
260 // the deamon st-thread will update it. 260 // the deamon st-thread will update it.
261 extern void srs_update_proc_stat(); 261 extern void srs_update_proc_stat();
262 262
  263 +// @see: cat /proc/meminfo
  264 +struct SrsMemInfo
  265 +{
  266 + // whether the data is ok.
  267 + bool ok;
  268 + // the time in ms when sample.
  269 + int64_t sample_time;
  270 + // the percent of usage. 0.153 is 15.3%.
  271 + float percent_ram;
  272 + float percent_swap;
  273 +
  274 + // MemActive = MemTotal - MemFree
  275 + int64_t MemActive;
  276 + // RealInUse = MemActive - Buffers - Cached
  277 + int64_t RealInUse;
  278 + // NotInUse = MemTotal - RealInUse
  279 + // = MemTotal - MemActive + Buffers + Cached
  280 + // = MemTotal - MemTotal + MemFree + Buffers + Cached
  281 + // = MemFree + Buffers + Cached
  282 + int64_t NotInUse;
  283 +
  284 + int64_t MemTotal;
  285 + int64_t MemFree;
  286 + int64_t Buffers;
  287 + int64_t Cached;
  288 + int64_t SwapTotal;
  289 + int64_t SwapFree;
  290 +
  291 + SrsMemInfo();
  292 +};
  293 +
  294 +// get system meminfo, use cache to avoid performance problem.
  295 +extern SrsMemInfo* srs_get_meminfo();
  296 +// the deamon st-thread will update it.
  297 +extern void srs_update_meminfo();
  298 +
263 // @see: cat /proc/cpuinfo 299 // @see: cat /proc/cpuinfo
264 struct SrsCpuInfo 300 struct SrsCpuInfo
265 { 301 {