diff --git a/trunk/src/app/srs_app_http_api.cpp b/trunk/src/app/srs_app_http_api.cpp index d9bf9f4a4..86b1caf2e 100644 --- a/trunk/src/app/srs_app_http_api.cpp +++ b/trunk/src/app/srs_app_http_api.cpp @@ -120,6 +120,7 @@ SrsApiV1::SrsApiV1() handlers.push_back(new SrsApiRusages()); handlers.push_back(new SrsApiSelfProcStats()); handlers.push_back(new SrsApiSystemProcStats()); + handlers.push_back(new SrsApiMemInfos()); handlers.push_back(new SrsApiAuthors()); } @@ -144,6 +145,7 @@ int SrsApiV1::do_process_request(SrsSocket* skt, SrsHttpMessage* req) << JFIELD_STR("rusages", "the rusage of SRS") << JFIELD_CONT << JFIELD_STR("self_proc_stats", "the self process stats") << JFIELD_CONT << JFIELD_STR("system_proc_stats", "the system process stats") << JFIELD_CONT + << JFIELD_STR("meminfos", "the meminfo of system") << JFIELD_CONT << JFIELD_STR("authors", "the primary authors and contributors") << JOBJECT_END << JOBJECT_END; @@ -202,23 +204,39 @@ int SrsApiSummaries::do_process_request(SrsSocket* skt, SrsHttpMessage* req) SrsProcSelfStat* u = srs_get_self_proc_stat(); SrsProcSystemStat* s = srs_get_system_proc_stat(); SrsCpuInfo* c = srs_get_cpuinfo(); + SrsMemInfo* m = srs_get_meminfo(); + + float self_mem_percent = 0; + if (m->MemTotal > 0) { + self_mem_percent = (float)(r->r.ru_maxrss / (double)m->MemTotal); + } ss << JOBJECT_START << JFIELD_ERROR(ERROR_SUCCESS) << JFIELD_CONT << JFIELD_ORG("data", JOBJECT_START) - << JFIELD_ORG("pid", getpid()) << JFIELD_CONT - << JFIELD_STR("argv", _srs_config->get_argv()) << JFIELD_CONT - << JFIELD_STR("cwd", _srs_config->get_cwd()) << JFIELD_CONT << JFIELD_ORG("rusage_ok", (r->ok? "true":"false")) << JFIELD_CONT << JFIELD_ORG("self_cpu_stat_ok", (u->ok? "true":"false")) << JFIELD_CONT << JFIELD_ORG("system_cpu_stat_ok", (s->ok? "true":"false")) << JFIELD_CONT << JFIELD_ORG("cpuinfo_ok", (c->ok? "true":"false")) << JFIELD_CONT - << JFIELD_ORG("mem_kbyte", r->r.ru_maxrss) << JFIELD_CONT - << JFIELD_ORG("system_cpu", s->percent) << JFIELD_CONT - << JFIELD_ORG("self_cpu", u->percent) << JFIELD_CONT - << JFIELD_ORG("nb_processors", c->nb_processors) << JFIELD_CONT - << JFIELD_ORG("nb_processors_online", c->nb_processors_online) << JFIELD_CONT - << JFIELD_ORG("ppid", u->ppid) + << JFIELD_ORG("meminfo_ok", (m->ok? "true":"false")) << JFIELD_CONT + << JFIELD_ORG("self", JOBJECT_START) + << JFIELD_ORG("pid", getpid()) << JFIELD_CONT + << JFIELD_ORG("ppid", u->ppid) << JFIELD_CONT + << JFIELD_STR("argv", _srs_config->get_argv()) << JFIELD_CONT + << JFIELD_STR("cwd", _srs_config->get_cwd()) << JFIELD_CONT + << JFIELD_ORG("mem_kbyte", r->r.ru_maxrss) << JFIELD_CONT + << JFIELD_ORG("mem_percent", self_mem_percent) << JFIELD_CONT + << JFIELD_ORG("cpu_percent", u->percent) + << JOBJECT_END << JFIELD_CONT + << JFIELD_ORG("system", JOBJECT_START) + << JFIELD_ORG("cpu_percent", s->percent) << JFIELD_CONT + << JFIELD_ORG("mem_ram_kbyte", m->MemTotal) << JFIELD_CONT + << JFIELD_ORG("mem_ram_percent", m->percent_ram) << JFIELD_CONT + << JFIELD_ORG("mem_swap_kbyte", m->SwapTotal) << JFIELD_CONT + << JFIELD_ORG("mem_swap_percent", m->percent_swap) << JFIELD_CONT + << JFIELD_ORG("nb_processors", c->nb_processors) << JFIELD_CONT + << JFIELD_ORG("nb_processors_online", c->nb_processors_online) + << JOBJECT_END << JOBJECT_END << JOBJECT_END; @@ -386,6 +404,47 @@ int SrsApiSystemProcStats::do_process_request(SrsSocket* skt, SrsHttpMessage* re return res_json(skt, req, ss.str()); } +SrsApiMemInfos::SrsApiMemInfos() +{ +} + +SrsApiMemInfos::~SrsApiMemInfos() +{ +} + +bool SrsApiMemInfos::can_handle(const char* path, int length, const char** /*pchild*/) +{ + return srs_path_equals("/meminfos", path, length); +} + +int SrsApiMemInfos::do_process_request(SrsSocket* skt, SrsHttpMessage* req) +{ + std::stringstream ss; + + SrsMemInfo* m = srs_get_meminfo(); + + ss << JOBJECT_START + << JFIELD_ERROR(ERROR_SUCCESS) << JFIELD_CONT + << JFIELD_ORG("data", JOBJECT_START) + << JFIELD_ORG("ok", (m->ok? "true":"false")) << JFIELD_CONT + << JFIELD_ORG("sample_time", m->sample_time) << JFIELD_CONT + << JFIELD_ORG("percent_ram", m->percent_ram) << JFIELD_CONT + << JFIELD_ORG("percent_swap", m->percent_swap) << JFIELD_CONT + << JFIELD_ORG("MemActive", m->MemActive) << JFIELD_CONT + << JFIELD_ORG("RealInUse", m->RealInUse) << JFIELD_CONT + << JFIELD_ORG("NotInUse", m->NotInUse) << JFIELD_CONT + << JFIELD_ORG("MemTotal", m->MemTotal) << JFIELD_CONT + << JFIELD_ORG("MemFree", m->MemFree) << JFIELD_CONT + << JFIELD_ORG("Buffers", m->Buffers) << JFIELD_CONT + << JFIELD_ORG("Cached", m->Cached) << JFIELD_CONT + << JFIELD_ORG("SwapTotal", m->SwapTotal) << JFIELD_CONT + << JFIELD_ORG("SwapFree", m->SwapFree) + << JOBJECT_END + << JOBJECT_END; + + return res_json(skt, req, ss.str()); +} + SrsApiAuthors::SrsApiAuthors() { } diff --git a/trunk/src/app/srs_app_http_api.hpp b/trunk/src/app/srs_app_http_api.hpp index 850e1bf79..760534267 100644 --- a/trunk/src/app/srs_app_http_api.hpp +++ b/trunk/src/app/srs_app_http_api.hpp @@ -131,6 +131,17 @@ protected: virtual int do_process_request(SrsSocket* skt, SrsHttpMessage* req); }; +class SrsApiMemInfos : public SrsHttpHandler +{ +public: + SrsApiMemInfos(); + virtual ~SrsApiMemInfos(); +public: + virtual bool can_handle(const char* path, int length, const char** pchild); +protected: + virtual int do_process_request(SrsSocket* skt, SrsHttpMessage* req); +}; + class SrsApiAuthors : public SrsHttpHandler { public: diff --git a/trunk/src/app/srs_app_server.cpp b/trunk/src/app/srs_app_server.cpp index 11af202bd..cc080e7f0 100644 --- a/trunk/src/app/srs_app_server.cpp +++ b/trunk/src/app/srs_app_server.cpp @@ -48,6 +48,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define SERVER_LISTEN_BACKLOG 512 // system interval +// all resolution times should be times togother, +// for example, system-time is 3(300ms), +// then rusage can be 3*x, for instance, 3*10=30(3s), +// the meminfo canbe 30*x, for instance, 30*2=60(6s) #define SRS_SYS_CYCLE_INTERVAL 100 // update time interval: @@ -62,6 +66,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // SRS_SYS_CYCLE_INTERVAL * SRS_SYS_CPU_STAT_RESOLUTION_TIMES #define SRS_SYS_CPU_STAT_RESOLUTION_TIMES 30 +// update rusage interval: +// SRS_SYS_CYCLE_INTERVAL * SRS_SYS_MEMINFO_RESOLUTION_TIMES +#define SRS_SYS_MEMINFO_RESOLUTION_TIMES 60 + SrsListener::SrsListener(SrsServer* server, SrsListenerType type) { fd = -1; @@ -411,6 +419,7 @@ int SrsServer::cycle() int max = srs_max(0, SRS_SYS_TIME_RESOLUTION_MS_TIMES); max = srs_max(max, SRS_SYS_RUSAGE_RESOLUTION_TIMES); max = srs_max(max, SRS_SYS_CPU_STAT_RESOLUTION_TIMES); + max = srs_max(max, SRS_SYS_MEMINFO_RESOLUTION_TIMES); // the deamon thread, update the time cache while (true) { @@ -440,15 +449,18 @@ int SrsServer::cycle() } // update the cache time or rusage. - if (i == SRS_SYS_TIME_RESOLUTION_MS_TIMES) { + if ((i % SRS_SYS_TIME_RESOLUTION_MS_TIMES) == 0) { srs_update_system_time_ms(); } - if (i == SRS_SYS_RUSAGE_RESOLUTION_TIMES) { + if ((i % SRS_SYS_RUSAGE_RESOLUTION_TIMES) == 0) { srs_update_system_rusage(); } - if (i == SRS_SYS_CPU_STAT_RESOLUTION_TIMES) { + if ((i % SRS_SYS_CPU_STAT_RESOLUTION_TIMES) == 0) { srs_update_proc_stat(); } + if ((i % SRS_SYS_MEMINFO_RESOLUTION_TIMES) == 0) { + srs_update_meminfo(); + } } } diff --git a/trunk/src/kernel/srs_kernel_utility.cpp b/trunk/src/kernel/srs_kernel_utility.cpp index 1bc06ee90..f48dd279b 100644 --- a/trunk/src/kernel/srs_kernel_utility.cpp +++ b/trunk/src/kernel/srs_kernel_utility.cpp @@ -286,6 +286,84 @@ void srs_update_proc_stat() } } +SrsMemInfo::SrsMemInfo() +{ + ok = false; + sample_time = 0; + + percent_ram = 0; + percent_swap = 0; + + MemActive = 0; + RealInUse = 0; + NotInUse = 0; + MemTotal = 0; + MemFree = 0; + Buffers = 0; + Cached = 0; + SwapTotal = 0; + SwapFree = 0; +} + +static SrsMemInfo _srs_system_meminfo; + +SrsMemInfo* srs_get_meminfo() +{ + return &_srs_system_meminfo; +} + +void srs_update_meminfo() +{ + FILE* f = fopen("/proc/meminfo", "r"); + if (f == NULL) { + srs_warn("open meminfo failed, ignore"); + return; + } + + SrsMemInfo& r = _srs_system_meminfo; + r.ok = false; + + for (;;) { + static char label[64]; + static unsigned long value; + static char postfix[64]; + int ret = fscanf(f, "%64s %lu %64s\n", label, &value, postfix); + + if (ret == EOF) { + break; + } + + if (strcmp("MemTotal:", label) == 0) { + r.MemTotal = value; + } else if (strcmp("MemFree:", label) == 0) { + r.MemFree = value; + } else if (strcmp("Buffers:", label) == 0) { + r.Buffers = value; + } else if (strcmp("Cached:", label) == 0) { + r.Cached = value; + } else if (strcmp("SwapTotal:", label) == 0) { + r.SwapTotal = value; + } else if (strcmp("SwapFree:", label) == 0) { + r.SwapFree = value; + } + } + + r.sample_time = srs_get_system_time_ms(); + r.MemActive = r.MemTotal - r.MemFree; + r.RealInUse = r.MemActive - r.Buffers - r.Cached; + r.NotInUse = r.MemTotal - r.RealInUse; + + r.ok = true; + if (r.MemTotal > 0) { + r.percent_ram = (float)(r.RealInUse / (double)r.MemTotal); + } + if (r.SwapTotal > 0) { + r.percent_swap = (float)((r.SwapTotal - r.SwapFree) / (double)r.SwapTotal); + } + + fclose(f); +} + SrsCpuInfo::SrsCpuInfo() { ok = false; diff --git a/trunk/src/kernel/srs_kernel_utility.hpp b/trunk/src/kernel/srs_kernel_utility.hpp index 04b2885a2..5bda02646 100644 --- a/trunk/src/kernel/srs_kernel_utility.hpp +++ b/trunk/src/kernel/srs_kernel_utility.hpp @@ -260,6 +260,42 @@ extern SrsProcSystemStat* srs_get_system_proc_stat(); // the deamon st-thread will update it. extern void srs_update_proc_stat(); +// @see: cat /proc/meminfo +struct SrsMemInfo +{ + // whether the data is ok. + bool ok; + // the time in ms when sample. + int64_t sample_time; + // the percent of usage. 0.153 is 15.3%. + float percent_ram; + float percent_swap; + + // MemActive = MemTotal - MemFree + int64_t MemActive; + // RealInUse = MemActive - Buffers - Cached + int64_t RealInUse; + // NotInUse = MemTotal - RealInUse + // = MemTotal - MemActive + Buffers + Cached + // = MemTotal - MemTotal + MemFree + Buffers + Cached + // = MemFree + Buffers + Cached + int64_t NotInUse; + + int64_t MemTotal; + int64_t MemFree; + int64_t Buffers; + int64_t Cached; + int64_t SwapTotal; + int64_t SwapFree; + + SrsMemInfo(); +}; + +// get system meminfo, use cache to avoid performance problem. +extern SrsMemInfo* srs_get_meminfo(); +// the deamon st-thread will update it. +extern void srs_update_meminfo(); + // @see: cat /proc/cpuinfo struct SrsCpuInfo {