func()

in pkg/exporter/probe/tracesoftirq/tracesoftirq.go [233:299]


func (p *softirqProbe) perfLoop() {
	for {
		record, err := p.perfReader.Read()
		if err != nil {
			if errors.Is(err, ringbuf.ErrClosed) {
				log.Errorf("%s received signal, exiting..", probeName)
				return
			}
			log.Warnf("%s failed reading from reader, err: %v", probeName, err)
			continue
		}

		if record.LostSamples != 0 {
			log.Warnf("%s perf event ring buffer full, drop: %d", probeName, record.LostSamples)
			continue
		}

		var event bpfInspSoftirqEventT
		if err := binary.Read(bytes.NewBuffer(record.RawSample), binary.LittleEndian, &event); err != nil {
			log.Errorf("%s failed parsing event, err: %v", probeName, err)
			continue
		}

		evt := &probe.Event{
			Timestamp: time.Now().UnixNano(),
			Labels: []probe.Label{
				{
					Name:  "type",
					Value: convertIrqType(event.VecNr),
				},
			},
		}

		/*
					#define PHASE_SCHED 1
			        #define PHASE_EXCUTE 2
		*/
		switch event.Phase {
		case 1:
			evt.Type = "SOFTIRQ_SCHED_SLOW"
			p.updateMetrics(SOFTIRQ_SCHED_SLOW, event.VecNr)

			if event.Latency > 100_000_000 {
				evt.Type = "SOFTIRQ_SCHED_100MS"
				p.updateMetrics(SOFTIRQ_SCHED_100MS, event.VecNr)
			}
		case 2:
			evt.Type = "SOFTIRQ_EXCUTE_SLOW"
			p.updateMetrics(SOFTIRQ_EXCUTE_SLOW, event.VecNr)

			if event.Latency > 100_000_000 {
				evt.Type = "SOFTIRQ_EXCUTE_100MS"
				p.updateMetrics(SOFTIRQ_EXCUTE_100MS, event.VecNr)
			}

		default:
			log.Infof("%s failed parsing event, phase: %d", probeName, event.Phase)
			continue
		}

		evt.Message = fmt.Sprintf("cpu=%d pid=%d latency=%s ", event.Cpu, event.Pid, bpfutil.GetHumanTimes(event.Latency))
		if filterIrqEvent(p.eventProbeIrqTypes, event.VecNr) && p.sink != nil {
			log.Debugf("%s sink event %s", probeName, util.ToJSONString(evt))
			p.sink <- evt
		}
	}
}