github.com/instana/go-sensor@v1.62.2-0.20240520081010-4919868049e1/acceptor/process.go (about)

     1  // (c) Copyright IBM Corp. 2021
     2  // (c) Copyright Instana Inc. 2020
     3  
     4  package acceptor
     5  
     6  import "github.com/instana/go-sensor/process"
     7  
     8  // ProcessData is a representation of a running process for com.instana.plugin.process plugin
     9  type 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
    28  func 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
    39  type 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%.
    47  func 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
    68  type 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.
    76  func 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
    96  type 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.
   103  func 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  }