diff --git a/trunk/src/app/srs_app_server.cpp b/trunk/src/app/srs_app_server.cpp index 3b06bedcf..4b5c072bc 100644 --- a/trunk/src/app/srs_app_server.cpp +++ b/trunk/src/app/srs_app_server.cpp @@ -72,6 +72,13 @@ 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 the disk iops interval: +// SRS_SYS_CYCLE_INTERVAL * SRS_SYS_DISK_STAT_RESOLUTION_TIMES +// @remark, depends on SRS_SYS_CPU_STAT_RESOLUTION_TIMES, for the disk util +// depends on cpu time, so the disk stat times must be times of cpu stat time. +// for example, when cpu is 30, disk must be 30*1 or 30*2 ..., 30*N is ok. +#define SRS_SYS_DISK_STAT_RESOLUTION_TIMES 60 + // update rusage interval: // SRS_SYS_CYCLE_INTERVAL * SRS_SYS_MEMINFO_RESOLUTION_TIMES #define SRS_SYS_MEMINFO_RESOLUTION_TIMES 60 @@ -669,6 +676,7 @@ int SrsServer::do_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_DISK_STAT_RESOLUTION_TIMES); max = srs_max(max, SRS_SYS_MEMINFO_RESOLUTION_TIMES); max = srs_max(max, SRS_SYS_PLATFORM_INFO_RESOLUTION_TIMES); max = srs_max(max, SRS_SYS_NETWORK_DEVICE_RESOLUTION_TIMES); @@ -719,9 +727,13 @@ int SrsServer::do_cycle() srs_update_system_rusage(); } if ((i % SRS_SYS_CPU_STAT_RESOLUTION_TIMES) == 0) { - srs_info("update cpu info, usage."); + srs_info("update cpu info, cpu usage."); srs_update_proc_stat(); } + if ((i % SRS_SYS_DISK_STAT_RESOLUTION_TIMES) == 0) { + srs_info("update disk info, disk iops."); + srs_update_disk_stat(); + } if ((i % SRS_SYS_MEMINFO_RESOLUTION_TIMES) == 0) { srs_info("update memory info, usage/free."); srs_update_meminfo(); diff --git a/trunk/src/app/srs_app_utility.cpp b/trunk/src/app/srs_app_utility.cpp index 8b2244a21..0e1a7d391 100644 --- a/trunk/src/app/srs_app_utility.cpp +++ b/trunk/src/app/srs_app_utility.cpp @@ -350,6 +350,82 @@ void srs_update_proc_stat() } } +SrsDiskStat::SrsDiskStat() +{ + ok = false; + sample_time = 0; + in_KBps = out_KBps = 0; + + pgpgin = 0; + pgpgout = 0; +} + +static SrsDiskStat _srs_disk_stat; + +SrsDiskStat* srs_get_disk_stat() +{ + return &_srs_disk_stat; +} + +bool srs_get_disk_stat(SrsDiskStat& r) +{ + FILE* f = fopen("/proc/vmstat", "r"); + if (f == NULL) { + srs_warn("open vmstat failed, ignore"); + return false; + } + + r.ok = false; + r.sample_time = srs_get_system_time_ms(); + + for (;;) { + static char label[64]; + static unsigned long value; + int ret = fscanf(f, "%64s %lu\n", label, &value); + + if (ret == EOF) { + break; + } + + if (strcmp("pgpgin", label) == 0) { + r.pgpgin = value; + } else if (strcmp("pgpgout", label) == 0) { + r.pgpgout = value; + } + } + + fclose(f); + + r.ok = true; + + return true; +} + +void srs_update_disk_stat() +{ + SrsDiskStat r; + if (!srs_get_disk_stat(r)) { + return; + } + + SrsDiskStat& o = _srs_disk_stat; + if (o.ok) { + int64_t duration_ms = r.sample_time - o.sample_time; + + if (o.pgpgin > 0 && r.pgpgin > o.pgpgin && duration_ms > 0) { + // KBps = KB * 1000 / ms = KB/s + r.in_KBps = (r.pgpgin - o.pgpgin) * 1000 / duration_ms; + } + + if (o.pgpgout > 0 && r.pgpgout > o.pgpgout && duration_ms > 0) { + // KBps = KB * 1000 / ms = KB/s + r.out_KBps = (r.pgpgout - o.pgpgout) * 1000 / duration_ms; + } + } + + _srs_disk_stat = r; +} + SrsMemInfo::SrsMemInfo() { ok = false; @@ -610,19 +686,19 @@ SrsNetworkRtmpServer* srs_get_network_rtmp_server() // @see: http://stackoverflow.com/questions/5992211/list-of-possible-internal-socket-statuses-from-proc enum { - SYS_TCP_ESTABLISHED = 1, - SYS_TCP_SYN_SENT, - SYS_TCP_SYN_RECV, - SYS_TCP_FIN_WAIT1, - SYS_TCP_FIN_WAIT2, - SYS_TCP_TIME_WAIT, - SYS_TCP_CLOSE, - SYS_TCP_CLOSE_WAIT, - SYS_TCP_LAST_ACK, - SYS_TCP_LISTEN, - SYS_TCP_CLOSING, /* Now a valid state */ - - SYS_TCP_MAX_STATES /* Leave at the end! */ + SYS_TCP_ESTABLISHED = 0x01, + SYS_TCP_SYN_SENT, // 0x02 + SYS_TCP_SYN_RECV, // 0x03 + SYS_TCP_FIN_WAIT1, // 0x04 + SYS_TCP_FIN_WAIT2, // 0x05 + SYS_TCP_TIME_WAIT, // 0x06 + SYS_TCP_CLOSE, // 0x07 + SYS_TCP_CLOSE_WAIT, // 0x08 + SYS_TCP_LAST_ACK, // 0x09 + SYS_TCP_LISTEN, // 0x0A + SYS_TCP_CLOSING, // 0x0B /* Now a valid state */ + + SYS_TCP_MAX_STATES // 0x0C /* Leave at the end! */ }; void srs_update_rtmp_server(int nb_conn, SrsKbps* kbps) @@ -811,6 +887,7 @@ void srs_api_dump_summaries(std::stringstream& ss) SrsPlatformInfo* p = srs_get_platform_info(); SrsNetworkDevices* n = srs_get_network_devices(); SrsNetworkRtmpServer* nrs = srs_get_network_rtmp_server(); + SrsDiskStat* d = srs_get_disk_stat(); float self_mem_percent = 0; if (m->MemTotal > 0) { @@ -847,6 +924,7 @@ void srs_api_dump_summaries(std::stringstream& ss) << __SRS_JFIELD_ORG("self_cpu_stat_ok", (u->ok? "true":"false")) << __SRS_JFIELD_CONT << __SRS_JFIELD_ORG("system_cpu_stat_ok", (s->ok? "true":"false")) << __SRS_JFIELD_CONT << __SRS_JFIELD_ORG("cpuinfo_ok", (c->ok? "true":"false")) << __SRS_JFIELD_CONT + << __SRS_JFIELD_ORG("disk_ok", (d->ok? "true":"false")) << __SRS_JFIELD_CONT << __SRS_JFIELD_ORG("meminfo_ok", (m->ok? "true":"false")) << __SRS_JFIELD_CONT << __SRS_JFIELD_ORG("platform_ok", (p->ok? "true":"false")) << __SRS_JFIELD_CONT << __SRS_JFIELD_ORG("network_ok", (n_ok? "true":"false")) << __SRS_JFIELD_CONT @@ -865,6 +943,8 @@ void srs_api_dump_summaries(std::stringstream& ss) << __SRS_JOBJECT_END << __SRS_JFIELD_CONT << __SRS_JFIELD_ORG("system", __SRS_JOBJECT_START) << __SRS_JFIELD_ORG("cpu_percent", s->percent) << __SRS_JFIELD_CONT + << __SRS_JFIELD_ORG("disk_in_KBps", d->in_KBps) << __SRS_JFIELD_CONT + << __SRS_JFIELD_ORG("disk_out_KBps", d->out_KBps) << __SRS_JFIELD_CONT << __SRS_JFIELD_ORG("mem_ram_kbyte", m->MemTotal) << __SRS_JFIELD_CONT << __SRS_JFIELD_ORG("mem_ram_percent", m->percent_ram) << __SRS_JFIELD_CONT << __SRS_JFIELD_ORG("mem_swap_kbyte", m->SwapTotal) << __SRS_JFIELD_CONT diff --git a/trunk/src/app/srs_app_utility.hpp b/trunk/src/app/srs_app_utility.hpp index c54e716e0..5270154b0 100644 --- a/trunk/src/app/srs_app_utility.hpp +++ b/trunk/src/app/srs_app_utility.hpp @@ -59,8 +59,10 @@ public: // the time in ms when sample. int64_t sample_time; +public: rusage r; +public: SrsRusage(); }; @@ -81,6 +83,8 @@ public: // the percent of usage. 0.153 is 15.3%. float percent; +// data of /proc/[pid]/stat +public: // pid %d The process ID. int pid; // comm %s The filename of the executable, in parentheses. This is visible whether or not the executable is @@ -219,6 +223,7 @@ public: // Guest time of the process’s children, measured in clock ticks (divide by sysconf(_SC_CLK_TCK). long cguest_time; +public: SrsProcSelfStat(); }; @@ -271,6 +276,7 @@ public: // always be cpu char label[32]; +// data of /proc/stat public: // The amount of time, measured in units of USER_HZ // (1/100ths of a second on most architectures, use @@ -304,6 +310,7 @@ public: // operating systems under the control of the Linux kernel. unsigned long guest; +public: SrsProcSystemStat(); // get total cpu units. @@ -317,6 +324,40 @@ extern SrsProcSystemStat* srs_get_system_proc_stat(); // the deamon st-thread will update it. extern void srs_update_proc_stat(); +// stat disk iops +// @see: http://stackoverflow.com/questions/4458183/how-the-util-of-iostat-is-computed +// for total disk io, @see: cat /proc/vmstat |grep pgpg +// for device disk io, @see: cat /proc/diskstats +class SrsDiskStat +{ +public: + // whether the data is ok. + bool ok; + // the time in ms when sample. + int64_t sample_time; + // input(read) KBytes per seconds + int in_KBps; + // output(write) KBytes per seconds + int out_KBps; + +public: + // @see: cat /proc/vmstat + // the in(read) page count, pgpgin*1024 is the read bytes. + // Total number of kilobytes the system paged in from disk per second. + unsigned long pgpgin; + // the out(write) page count, pgpgout*1024 is the write bytes. + // Total number of kilobytes the system paged out to disk per second. + unsigned long pgpgout; + +public: + SrsDiskStat(); +}; + +// get disk stat, use cache to avoid performance problem. +extern SrsDiskStat* srs_get_disk_stat(); +// the deamon st-thread will update it. +extern void srs_update_disk_stat(); + // stat system memory info // @see: cat /proc/meminfo class SrsMemInfo @@ -330,6 +371,8 @@ public: float percent_ram; float percent_swap; +// data of /proc/meminfo +public: // MemActive = MemTotal - MemFree int64_t MemActive; // RealInUse = MemActive - Buffers - Cached @@ -347,6 +390,7 @@ public: int64_t SwapTotal; int64_t SwapFree; +public: SrsMemInfo(); }; @@ -357,17 +401,21 @@ extern void srs_update_meminfo(); // system cpu hardware info. // @see: cat /proc/cpuinfo +// @remark, we use sysconf(_SC_NPROCESSORS_CONF) to get the cpu count. class SrsCpuInfo { public: // whether the data is ok. bool ok; +// data of /proc/cpuinfo +public: // The number of processors configured. int nb_processors; // The number of processors currently online (available). int nb_processors_online; +public: SrsCpuInfo(); }; @@ -384,6 +432,7 @@ public: // srs startup time, in ms. int64_t srs_startup_time; +public: // @see: cat /proc/uptime // system startup time in seconds. double os_uptime; @@ -397,6 +446,7 @@ public: double load_five_minutes; double load_fifteen_minutes; +public: SrsPlatformInfo(); }; @@ -418,6 +468,7 @@ public: // the sample time in ms. int64_t sample_time; +public: // data for receive. unsigned long long rbytes; unsigned long rpackets; @@ -438,6 +489,7 @@ public: unsigned long scarrier; unsigned long scompressed; +public: SrsNetworkDevices(); }; @@ -457,6 +509,7 @@ public: // the sample time in ms. int64_t sample_time; +public: // data for receive. int64_t rbytes; int rkbps; @@ -476,6 +529,7 @@ public: int nb_conn_sys_ls; // listen int nb_conn_srs; +public: SrsNetworkRtmpServer(); }; diff --git a/trunk/src/core/srs_core.hpp b/trunk/src/core/srs_core.hpp index 3acbcb515..61e0cd92b 100644 --- a/trunk/src/core/srs_core.hpp +++ b/trunk/src/core/srs_core.hpp @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // current release version #define VERSION_MAJOR "0" #define VERSION_MINOR "9" -#define VERSION_REVISION "173" +#define VERSION_REVISION "174" #define RTMP_SIG_SRS_VERSION VERSION_MAJOR"."VERSION_MINOR"."VERSION_REVISION // server info. #define RTMP_SIG_SRS_KEY "SRS"