Example #1
0
func GetRuntimeStats(channel chan *lib.RuntimeStatus, sleep time.Duration) {
	memStats := &runtime.MemStats{}
	lastSampleTime := time.Now()
	var lastPauseNs uint64 = 0
	var lastNumGc uint32 = 0
	var runtime_status lib.RuntimeStatus

	nsInMs := float64(time.Millisecond)

	for {
		runtime.ReadMemStats(memStats)

		now := time.Now()

		runtime_status.TimeString = lib.GetTimeString()

		runtime_status.Alloc = memStats.Alloc
		runtime_status.Sys = memStats.Sys
		runtime_status.Mallocs = memStats.Mallocs
		runtime_status.Frees = memStats.Frees

		runtime_status.HeapAlloc = memStats.HeapAlloc
		runtime_status.HeapSys = memStats.HeapSys
		runtime_status.HeapIdle = memStats.HeapIdle
		runtime_status.HeapInuse = memStats.HeapInuse
		runtime_status.HeapObjects = memStats.HeapObjects

		runtime_status.StackSys = memStats.StackSys
		runtime_status.StackInuse = memStats.StackInuse
		runtime_status.MSpanInuse = memStats.MSpanInuse
		runtime_status.MSpanSys = memStats.MSpanSys
		runtime_status.MCacheInuse = memStats.MCacheInuse
		runtime_status.MCacheSys = memStats.MCacheSys

		runtime_status.GCTotalPause = float64(memStats.PauseTotalNs) / nsInMs

		/*
		   计算平均每秒GC暂停的时间
		*/

		// 总的GC暂停时间大于0
		if lastPauseNs > 0 {
			// 获取两次GC间隔的时间
			pauseSinceLastSample := memStats.PauseTotalNs - lastPauseNs
			runtime_status.GCPausePerSecond = float64(pauseSinceLastSample) / nsInMs / sleep.Seconds()
		}
		lastPauseNs = memStats.PauseTotalNs

		// 两次采样之间GC的次数
		countGc := int(memStats.NumGC - lastNumGc)

		/*
		   计算平均每秒GC的次数
		*/

		if lastNumGc > 0 {
			diff := float64(countGc)
			diffTime := now.Sub(lastSampleTime).Seconds()
			runtime_status.GCPerSecond = diff / diffTime
		}

		/*
		   如果两次采样之间发生了GC,则获取暂停时间(ms)
		*/

		if countGc > 0 {
			/*
			   如果两次采样之间发生了超过256次的GC,就有可能获取不到一些GC动作的暂停时间
			   因为memStats.PauseNS是一个环形的缓存,最多只能记录256次GC动作的暂停时间
			*/
			if countGc > 256 {
				fmt.Fprintf(os.Stderr, "We're missing some gc pause times")
				countGc = 256
			}

			for i := 0; i < countGc; i++ {
				// 最近一次的GC暂停时间保存在[(NumGC+255)%256]
				idx := int((memStats.NumGC-uint32(i))+255) % 256
				pause := float64(memStats.PauseNs[idx])
				// 暂停时间单位为ns,ns/nsInMs单位为ms
				runtime_status.GCPause = pause / nsInMs
			}
		}

		// 记录前一次的状态,为下次采样做准备
		lastNumGc = memStats.NumGC
		lastSampleTime = now

		channel <- &runtime_status

		time.Sleep(sleep)
	}
}
Example #2
0
func GetLoadInfo(channel chan *lib.LoadInfo, sleep time.Duration) {
	var load_info lib.LoadInfo

	for {
		meminfo_file := "/proc/meminfo"

		meminfo_data, err := lib.ReadFileFullContentByLine(meminfo_file)

		if err != nil {
			log.Fatal(err)
			return
		}

		now_time := lib.GetTimeString()
		load_info.TimeString = now_time

		meminfo_total_splited := bytes.Fields(meminfo_data[0])
		meminfo_free_splited := bytes.Fields(meminfo_data[1])
		meminfo_buffers_splited := bytes.Fields(meminfo_data[2])
		meminfo_cached_splited := bytes.Fields(meminfo_data[3])

		if v, err := strconv.ParseUint(string(meminfo_total_splited[1]), 10, 0); err == nil {
			load_info.MemTotal = v
		}

		if v, err := strconv.ParseUint(string(meminfo_free_splited[1]), 10, 0); err == nil {
			load_info.MemFree = v
		}

		if v, err := strconv.ParseUint(string(meminfo_buffers_splited[1]), 10, 0); err == nil {
			load_info.MemBuffers = v
		}

		if v, err := strconv.ParseUint(string(meminfo_cached_splited[1]), 10, 0); err == nil {
			load_info.MemCached = v
		}

		load_info.MemUsed = load_info.MemTotal - load_info.MemFree

		loadavg_file := "/proc/loadavg"

		loadavg_data, err := lib.ReadFileFullContent(loadavg_file)

		if err != nil {
			log.Fatal(err)
			return
		}

		loadavg_splited := strings.Split(string(loadavg_data), " ")

		if len(loadavg_splited) > 0 {
			// 1分钟内的负载
			load1 := strings.Trim(loadavg_splited[0], " ")
			if v, err := strconv.ParseFloat(load1, 64); err == nil {
				load_info.LoadAVG1 = v
			}

			// 5分钟内的负载
			load5 := strings.Trim(loadavg_splited[1], " ")
			if v, err := strconv.ParseFloat(load5, 64); err == nil {
				load_info.LoadAVG5 = v
			}

			// 15分钟内的负载
			load15 := strings.Trim(loadavg_splited[2], " ")
			if v, err := strconv.ParseFloat(load15, 64); err == nil {
				load_info.LoadAVG15 = v
			}
		}

		channel <- &load_info
		time.Sleep(sleep)
	}
}
Example #3
0
// 获取进程的信息
func GetProcessInfo(channel chan *lib.ProcessInfo, sleep time.Duration) {
	/*
	   Process's memory status in /proc/PID/statm:
	   total program pages |
	   resident pages |
	   shared pages |
	   text(code) |
	   data/stack |
	   library |
	   dirty pages

	   page size is 4K
	*/

	var process_info lib.ProcessInfo

	pagesize := int64(os.Getpagesize())

	for {
		pid := os.Getpid()

		statm_file := fmt.Sprintf("/proc/%d/statm", pid)

		data, err := lib.ReadFileFullContent(statm_file)

		if err != nil {
			log.Fatal(err)
			return
		}

		now_time := lib.GetTimeString()
		process_info.TimeString = now_time

		memory_splited := strings.Split(string(data), " ")

		if len(memory_splited) > 0 {
			// 虚拟内存(VIRT)
			virtual_pages := strings.Trim(memory_splited[0], " ")
			if v, err := strconv.ParseInt(virtual_pages, 10, 0); err == nil {
				process_info.VirtualMemory = v * pagesize
			}

			// 物理内存(RES)
			resisdent_pages := strings.Trim(memory_splited[1], " ")
			if v, err := strconv.ParseInt(resisdent_pages, 10, 0); err == nil {
				process_info.ResisdentMemory = v * pagesize
			}

			// 共享内存(SHR)
			shared_pages := strings.Trim(memory_splited[2], " ")
			if v, err := strconv.ParseInt(shared_pages, 10, 0); err == nil {
				process_info.SharedMemory = v * pagesize
			}
		}

		// 进程运行了多长时间
		process_info.Uptime = int64(time.Now().Sub(lib.StartTime).Seconds())

		channel <- &process_info

		time.Sleep(sleep)
	}
}