diff --git a/config/config.go b/config/config.go index 388e183..0196cc9 100644 --- a/config/config.go +++ b/config/config.go @@ -24,10 +24,11 @@ type Config struct { } type MetricConfig struct { - PingSpan int `yaml:"ping_span"` - PidSpan int `yaml:"pid_span"` - LRUCacheSize int `yaml:"lru_cache_size"` - ProcessTime bool `yaml:"process_time"` + PingSpan int `yaml:"ping_span"` + PidSpan int `yaml:"pid_span"` + LRUCacheSize int `yaml:"lru_cache_size"` + ProcessTime bool `yaml:"process_time"` + ScrapProcessLastSeen bool `yaml:"scrap_process_last_seen"` } func (m *MetricConfig) setDefault() { diff --git a/metric/metric.go b/metric/metric.go index 40c1d95..8437d87 100644 --- a/metric/metric.go +++ b/metric/metric.go @@ -54,11 +54,31 @@ func (rc *RttCollector) Collect(ch chan<- prometheus.Metric) { cfg.NodeName, cfg.NodeIP, processInfo.ContainId, + processInfo.Comm, ) pid2cid[pid] = processInfo.ContainId } proc.GlobalPidMutex.RUnlock() } + + if cfg.Metric.ScrapProcessLastSeen { + proc.GlobalPidMutex.RLock() + for pid, processInfo := range proc.GlobalNeedMonitorPid { + // TODO Check network traffic + ch <- prometheus.MustNewConstMetric( + processLastSeen, prometheus.GaugeValue, + float64(processInfo.LastSeen.Unix()), + strconv.FormatUint(uint64(pid), 10), + cfg.NodeName, + cfg.NodeIP, + processInfo.ContainId, + processInfo.Comm, + ) + pid2cid[pid] = processInfo.ContainId + } + proc.GlobalPidMutex.RUnlock() + } + middleware.MiddlewareInstance.Mu.Lock() for pid, conn := range middleware.MiddlewareInstance.Pid2Connect { for _, info := range conn { diff --git a/metric/process.go b/metric/process.go index d20fab1..14dca92 100644 --- a/metric/process.go +++ b/metric/process.go @@ -10,6 +10,20 @@ var processStartTime = prometheus.NewDesc( "node_name", "node_ip", "container_id", + "comm", + }, + nil, +) + +var processLastSeen = prometheus.NewDesc( + "originx_process_last_seen", + "Unix timestamp when the process was last detected.", + []string{ + "pid", + "node_name", + "node_ip", + "container_id", + "comm", }, nil, ) diff --git a/proc/pid.go b/proc/pid.go index 6435725..f217491 100644 --- a/proc/pid.go +++ b/proc/pid.go @@ -37,6 +37,8 @@ var GlobalNeedMonitorPid = make(map[uint32]*ProcessInfo) type ProcessInfo struct { StartTime time.Time ContainId string + LastSeen time.Time + Comm string } func GetPid() { @@ -63,6 +65,8 @@ func UpdatePid() { for pid := range newSet { if _, ok := GlobalNeedMonitorPid[pid]; !ok { GlobalNeedMonitorPid[pid] = pids[pid] + } else { + GlobalNeedMonitorPid[pid].LastSeen = pids[pid].LastSeen } } GlobalPidMutex.Unlock() @@ -99,9 +103,12 @@ func listPids() map[uint32]*ProcessInfo { if err != nil { continue } + comm := getComm(uint32(pid)) pids[intpid] = &ProcessInfo{ StartTime: *startTime, ContainId: cid, + LastSeen: time.Now(), + Comm: comm, } } return pids diff --git a/proc/proc.go b/proc/proc.go index 086eeb7..0a5c9b5 100644 --- a/proc/proc.go +++ b/proc/proc.go @@ -25,6 +25,16 @@ func getCommand(pid uint32) string { } return strings.Replace(string(cmdline), "\x00", " ", -1) } + +func getComm(pid uint32) string { + comm, err := os.ReadFile(Path(pid, "comm")) + if err != nil { + return "" + } + + return strings.TrimRight(string(comm), "\n\r ") +} + func getContainerId(pid uint32) string { data, err := os.ReadFile(Path(pid, "cgroup")) if err != nil { @@ -54,6 +64,7 @@ func getContainerId(pid uint32) string { } return "" } + func getProcessStartTime(pid uint32) (*time.Time, error) { data, err := os.ReadFile(Path(pid, "stat")) if err != nil {