1// (c) Copyright IBM Corp. 2021 2// (c) Copyright Instana Inc. 2020 3 4package acceptor 5 6import "github.com/instana/go-sensor/process" 7 8// ProcessData is a representation of a running process for com.instana.plugin.process plugin 9type ProcessData struct { 10 PID int `json:"pid"` 11 Exec string `json:"exec"` 12 Args []string `json:"args,omitempty"` 13 Env map[string]string `json:"env,omitempty"` 14 User string `json:"user,omitempty"` 15 Group string `json:"group,omitempty"` 16 ContainerID string `json:"container,omitempty"` 17 ContainerPid int `json:"containerPid,string,omitempty"` 18 ContainerType string `json:"containerType,omitempty"` 19 Start int64 `json:"start"` 20 HostName string `json:"com.instana.plugin.host.name"` 21 HostPID int `json:"com.instana.plugin.host.pid,string"` 22 CPU *ProcessCPUStatsDelta `json:"cpu,omitempty"` 23 Memory *ProcessMemoryStatsUpdate `json:"mem,omitempty"` 24 OpenFiles *ProcessOpenFilesStatsUpdate `json:"openFiles,omitempty"` 25} 26 27// NewProcessPluginPayload returns payload for the process plugin of Instana acceptor 28func NewProcessPluginPayload(entityID string, data ProcessData) PluginPayload { 29 const pluginName = "com.instana.plugin.process" 30 31 return PluginPayload{ 32 Name: pluginName, 33 EntityID: entityID, 34 Data: data, 35 } 36} 37 38// ProcessCPUStatsDelta represents the CPU stats that have changed since the last measurement 39type ProcessCPUStatsDelta struct { 40 User float64 `json:"user,omitempty"` 41 System float64 `json:"sys,omitempty"` 42} 43 44// NewProcessCPUStatsDelta calculates the difference between two CPU usage stats. 45// It returns nil if stats are equal or if the stats were taken at the same time (ticks). 46// The stats are considered to be equal if the change is less then 1%. 47func NewProcessCPUStatsDelta(prev, next process.CPUStats, ticksElapsed int) *ProcessCPUStatsDelta { 48 if prev == next || ticksElapsed == 0 { 49 return nil 50 } 51 52 delta := &ProcessCPUStatsDelta{} 53 if d := float64(next.System-prev.System) / float64(ticksElapsed); d >= 0.01 { 54 delta.System = d 55 } 56 if d := float64(next.User-prev.User) / float64(ticksElapsed); d >= 0.01 { 57 delta.User = d 58 } 59 60 if delta.User == 0 && delta.System == 0 { 61 return nil 62 } 63 64 return delta 65} 66 67// ProcessMemoryStatsUpdate represents the memory stats that have changed since the last measurement 68type ProcessMemoryStatsUpdate struct { 69 Total *int `json:"virtual,omitempty"` 70 Rss *int `json:"resident,omitempty"` 71 Shared *int `json:"share,omitempty"` 72} 73 74// NewProcessMemoryStatsUpdate returns the fields that have been updated since the last measurement. 75// It returns nil if nothing has changed. 76func NewProcessMemoryStatsUpdate(prev, next process.MemStats) *ProcessMemoryStatsUpdate { 77 if prev == next { 78 return nil 79 } 80 81 update := &ProcessMemoryStatsUpdate{} 82 if prev.Total != next.Total { 83 update.Total = &next.Total 84 } 85 if prev.Rss != next.Rss { 86 update.Rss = &next.Rss 87 } 88 if prev.Shared != next.Shared { 89 update.Shared = &next.Shared 90 } 91 92 return update 93} 94 95// ProcessOpenFilesStatsUpdate represents the open file stats and limits that have changed since the last measurement 96type ProcessOpenFilesStatsUpdate struct { 97 Current *int `json:"current,omitempty"` 98 Max *int `json:"max,omitempty"` 99} 100 101// NewProcessOpenFilesStatsUpdate returns the (process.ResourceLimits).OpenFiles fields that have been updated 102// since the last measurement. It returns nil if nothing has changed. 103func NewProcessOpenFilesStatsUpdate(prev, next process.ResourceLimits) *ProcessOpenFilesStatsUpdate { 104 if prev.OpenFiles == next.OpenFiles { 105 return nil 106 } 107 108 update := &ProcessOpenFilesStatsUpdate{} 109 if prev.OpenFiles.Current != next.OpenFiles.Current { 110 update.Current = &next.OpenFiles.Current 111 } 112 if prev.OpenFiles.Max != next.OpenFiles.Max { 113 update.Max = &next.OpenFiles.Max 114 } 115 116 return update 117} 118