func()

in metric/system/process/process.go [241:329]


func (procStats *Stats) pidFill(pid int, filter bool) (ProcState, bool, error) {
	// Fetch proc state so we can get the name for filtering based on user's filter.
	var wrappedErr error
	// OS-specific entrypoint, get basic info so we can at least run matchProcess
	status, err := GetInfoForPid(procStats.Hostfs, pid)
	if err != nil {
		return status, true, fmt.Errorf("GetInfoForPid failed for pid %d: %w", pid, err)
	}
	if procStats.skipExtended {
		return status, true, nil
	}

	// Some OSes use the cache to avoid expensive system calls,
	// cacheCmdLine reads from the cache.
	status = procStats.cacheCmdLine(status)

	// Filter based on user-supplied func
	if filter {
		if !procStats.matchProcess(status.Name) {
			return status, false, nil
		}
	}

	// If we've passed the filter, continue to fill out the rest of the metrics
	status, err = FillPidMetrics(procStats.Hostfs, pid, status, procStats.isWhitelistedEnvVar)
	if err != nil {
		if !errors.Is(err, NonFatalErr{}) {
			return status, true, fmt.Errorf("FillPidMetrics failed for PID %d: %w", pid, err)
		}
		wrappedErr = errors.Join(wrappedErr, err)
		procStats.logger.Debugf(wrappedErr.Error())
	}

	if status.CPU.Total.Ticks.Exists() {
		status.CPU.Total.Value = opt.FloatWith(metric.Round(float64(status.CPU.Total.Ticks.ValueOr(0))))
	}

	// postprocess with cgroups and percentages
	last, ok := procStats.ProcsMap.GetPid(status.Pid.ValueOr(0))
	status.SampleTime = time.Now()
	if ok {
		status = GetProcCPUPercentage(last, status)
	}

	if procStats.EnableCgroups {
		cgStats, err := procStats.cgroups.GetStatsForPid(status.Pid.ValueOr(0))
		if err != nil {
			procStats.logger.Debugf("Non-fatal error fetching cgroups metrics for pid %d, metrics are valid but partial: %s", pid, err)
		} else {
			status.Cgroup = cgStats
			if ok {
				status.Cgroup.FillPercentages(last.Cgroup, status.SampleTime, last.SampleTime)
			}
		}

	} // end cgroups processor

	if _, isExcluded := procStats.excludedPIDs[uint64(pid)]; !isExcluded {
		status, err = FillMetricsRequiringMoreAccess(pid, status)
		if err != nil {
			procStats.logger.Debugf("error calling FillMetricsRequiringMoreAccess for pid %d: %w", pid, err)
		}

		// Generate `status.Cmdline` here for compatibility because on Windows
		// `status.Args` is set by `FillMetricsRequiringMoreAccess`.
		if len(status.Args) > 0 && status.Cmdline == "" {
			status.Cmdline = strings.Join(status.Args, " ")
		}
	}

	// network data
	if procStats.EnableNetwork {
		procHandle, err := sysinfo.Process(pid)
		// treat this as a soft error
		if err != nil {
			procStats.logger.Debugf("error initializing process handler for pid %d while trying to fetch network data: %w", pid, err)
		} else {
			procNet, ok := procHandle.(sysinfotypes.NetworkCounters)
			if ok {
				status.Network, err = procNet.NetworkCounters()
				if err != nil {
					procStats.logger.Debugf("error fetching network counters for process %d: %w", pid, err)
				}
			}
		}
	}

	return status, true, wrappedErr
}