func (p *ProcMetrics) Collect() {
	if m, err := CollectProcInfo(p.pid); err == nil {
		now := time.Now()
		if !p.lastTime.IsZero() {
			ratio := 1.0
			switch {
			case m.CPU.Period > 0 && m.CPU.Quota > 0:
				ratio = float64(m.CPU.Quota) / float64(m.CPU.Period)
			case m.CPU.Shares > 0:
				ratio = float64(m.CPU.Shares) / 1024
			default:
				ratio = 1 / float64(runtime.NumCPU())
			}
			interval := ratio * float64(now.Sub(p.lastTime))
			p.cpu.user.time = m.CPU.User - p.last.CPU.User
			p.cpu.user.percent = 100 * float64(p.cpu.user.time) / interval
			p.cpu.system.time = m.CPU.Sys - p.last.CPU.Sys
			p.cpu.system.percent = 100 * float64(p.cpu.system.time) / interval
			p.cpu.total.time = (m.CPU.User + m.CPU.Sys) - (p.last.CPU.User + p.last.CPU.Sys)
			p.cpu.total.percent = 100 * float64(p.cpu.total.time) / interval
		}
		p.memory.available = m.Memory.Available
		p.memory.size = m.Memory.Size
		p.memory.resident.usage = m.Memory.Resident
		p.memory.resident.percent = 100 * float64(p.memory.resident.usage) / float64(p.memory.available)
		p.memory.shared.usage = m.Memory.Shared
		p.memory.text.usage = m.Memory.Text
		p.memory.data.usage = m.Memory.Data
		p.memory.pagefault.major.count = m.Memory.MajorPageFaults - p.last.Memory.MajorPageFaults
		p.memory.pagefault.minor.count = m.Memory.MinorPageFaults - p.last.Memory.MinorPageFaults
		p.files.open = m.Files.Open
		p.files.max = m.Files.Max
		p.threads.num = m.Threads.Num
		p.threads.switches.voluntary.count = m.Threads.VoluntaryContextSwitches - p.last.Threads.VoluntaryContextSwitches
		p.threads.switches.involuntary.count = m.Threads.InvoluntaryContextSwitches - p.last.Threads.InvoluntaryContextSwitches
		p.last = m
		p.lastTime = now
		p.engine.Report(p)
	}
}
Collect satisfies the Collector interface.
package procstats
import (
	"os"
	"runtime"
	"time"
	"github.com/segmentio/stats/v4"
)
type ProcMetrics struct {
	engine   *stats.Engine
	pid      int
	cpu      procCPU     `metric:"cpu"`
	memory   procMemory  `metric:"memory"`
	files    procFiles   `metric:"files"`
	threads  procThreads `metric:"threads"`
	last     ProcInfo
	lastTime time.Time
}
type procCPU struct {
	user struct {  
		time    time.Duration `metric:"usage.seconds" type:"counter"`
		percent float64       `metric:"usage.percent" type:"gauge"`
		typ     string        `tag:"type"`  
	}
	system struct {  
		time    time.Duration `metric:"usage.seconds" type:"counter"`
		percent float64       `metric:"usage.percent" type:"gauge"`
		typ     string        `tag:"type"`  
	}
	total struct {
		time    time.Duration `metric:"usage_total.seconds" type:"counter"`
		percent float64       `metric:"usage_total.percent" type:"gauge"`
	}
}
type procMemory struct {
	available uint64 `metric:"available.bytes" type:"gauge"`  
	size      uint64 `metric:"total.bytes"     type:"gauge"`  
	resident struct {  
		usage   uint64  `metric:"usage.bytes"   type:"gauge"`
		percent float64 `metric:"usage.percent" type:"gauge"`
		typ     string  `tag:"type"`  
	}
	shared struct {  
		usage uint64 `metric:"usage.bytes" type:"gauge"`
		typ   string `tag:"type"`  
	}
	text struct {  
		usage uint64 `metric:"usage.bytes" type:"gauge"`
		typ   string `tag:"type"`  
	}
	data struct {  
		usage uint64 `metric:"usage.bytes" type:"gauge"`
		typ   string `tag:"type"`  
	}
	pagefault struct {
		major struct {
			count uint64 `metric:"count" type:"counter"`
			typ   string `tag:"type"`  
		}
		minor struct {
			count uint64 `metric:"count" type:"counter"`
			typ   string `tag:"type"`  
		}
	} `metric:"pagefault"`
}
type procFiles struct {
	open uint64 `metric:"open.count" type:"gauge"`  
	max  uint64 `metric:"open.max"   type:"gauge"`  
}
type procThreads struct {
	num uint64 `metric:"count" type:"gauge"`
	switches struct {
		voluntary struct {
			count uint64 `metric:"count" type:"counter"`
			typ   string `tag:"type"`  
		}
		involuntary struct {
			count uint64 `metric:"count" type:"counter"`
			typ   string `tag:"type"`  
		}
	} `metric:"switch"`
}
func NewProcMetrics() *ProcMetrics {
	return NewProcMetricsWith(stats.DefaultEngine, os.Getpid())
}
func NewProcMetricsWith(eng *stats.Engine, pid int) *ProcMetrics {
	p := &ProcMetrics{engine: eng, pid: pid}
	p.cpu.user.typ = "user"
	p.cpu.system.typ = "system"
	p.memory.resident.typ = "resident"
	p.memory.shared.typ = "shared"
	p.memory.text.typ = "text"
	p.memory.data.typ = "data"
	p.memory.pagefault.major.typ = "major"
	p.memory.pagefault.minor.typ = "minor"
	p.threads.switches.voluntary.typ = "voluntary"
	p.threads.switches.involuntary.typ = "involuntary"
	return p
}