tracing

package
v0.0.0-...-2db35d6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 20, 2024 License: MPL-2.0 Imports: 13 Imported by: 0

Documentation

Index

Constants

View Source
const (
	ProbeSyscallRead = Probe(iota)
	ProbeSyscallWrite
	ProbeTcpProbe
	ProbeBlockIO
)

Variables

View Source
var (
	// TcpAddrPortKeyRegex matches the TCP address (byte array) and TCP port from a bpftrace map key.
	TcpAddrPortKeyRegex = regexp.MustCompile(`\[([0-9,-]+)\],([0-9]+)`)
	// ProbeNames maps supported tracing probe types to their bpftrace probe names.
	ProbeNames = map[Probe][]string{
		ProbeSyscallRead:  {"tracepoint:syscalls:sys_enter_read", "tracepoint:syscalls:sys_exit_read"},
		ProbeSyscallWrite: {"tracepoint:syscalls:sys_enter_write", "tracepoint:syscalls:sys_exit_write"},
		ProbeTcpProbe:     {"tracepoint:tcp:tcp_probe"},
		ProbeBlockIO:      {"tracepoint:block:block_io_start", "tracepoint:block:block_io_done"},
	}

	// BpftraceCode maps all supported probe types to templated bpftrace code.
	BpftraceCode = map[Probe]func(int, int) string{

		ProbeSyscallRead: func(pid, intervalSec int) string {
			if pid == 0 {
				return fmt.Sprintf(`
					tracepoint:syscalls:sys_enter_read {
						@fd[tid] = args->fd;
					}
					tracepoint:syscalls:sys_exit_read /@fd[tid]/ {
						if (args->ret > 0) {@read_fd[@fd[tid]] += args->ret;}
						delete(@fd[tid]);
					}
					interval:s:%d {
						print(@read_fd);
						clear(@read_fd);
					}
					`, intervalSec)
			}
			return fmt.Sprintf(`
				tracepoint:syscalls:sys_enter_read /pid == %d/ {
					@fd[tid] = args->fd;
				}
				tracepoint:syscalls:sys_exit_read /pid == %d && @fd[tid]/ {
					if (args->ret > 0) {@read_fd[@fd[tid]] += args->ret;}
					delete(@fd[tid]);
				}
				interval:s:%d {
					print(@read_fd);
					clear(@read_fd);
				}
				`, pid, pid, intervalSec)
		},
		ProbeSyscallWrite: func(pid, intervalSec int) string {
			if pid == 0 {
				return fmt.Sprintf(`
					tracepoint:syscalls:sys_enter_write {
						@fd[tid] = args->fd;
					}
					tracepoint:syscalls:sys_exit_write /@fd[tid]/ {
						if (args->ret > 0) {@write_fd[@fd[tid]] += args->ret;}
						delete(@fd[tid]);
					}
					interval:s:%d {
						print(@write_fd);
						clear(@write_fd);
					}
					`, intervalSec)
			}
			return fmt.Sprintf(`
				tracepoint:syscalls:sys_enter_write /pid == %d/ {
					@fd[tid] = args->fd;
				}
				tracepoint:syscalls:sys_exit_write /pid == %d && @fd[tid]/ {
					if (args->ret > 0) {@write_fd[@fd[tid]] += args->ret;}
					delete(@fd[tid]);
				}
				interval:s:%d {
					print(@write_fd);
					clear(@write_fd);
				}
				`, pid, pid, intervalSec)
		},
		ProbeTcpProbe: func(pid, intervalSec int) string {
			if pid == 0 {
				return fmt.Sprintf(`
					tracepoint:tcp:tcp_probe {
						@tcp_src[args->saddr, args->sport] += args->data_len;
						@tcp_dest[args->daddr, args->dport] += args->data_len;
					}
					interval:s:%d {
						print(@tcp_src); print(@tcp_dest);
						clear(@tcp_src); clear(@tcp_dest);
					}
					`, intervalSec)
			}
			return fmt.Sprintf(`
				tracepoint:tcp:tcp_probe /pid == %d/ {
					@tcp_src[args->saddr, args->sport] += args->data_len;
					@tcp_dest[args->daddr, args->dport] += args->data_len;
				}
				interval:s:%d {
					print(@tcp_src); print(@tcp_dest);
					clear(@tcp_src); clear(@tcp_dest);
				}
				`, pid, intervalSec)
		},
		ProbeBlockIO: func(pid, intervalSec int) string {
			if pid == 0 {
				return fmt.Sprintf(`
				tracepoint:block:block_io_start {
					@blkdev_sector_count[args->dev] += args->nr_sector;
					@blkdev_req[args->sector] = nsecs;
				}

				tracepoint:block:block_io_done /@blkdev_req[args->sector] != 0/ {
					@blkdev_dur[args->dev] += nsecs - @blkdev_req[args->sector];
					delete(@blkdev_req[args->sector]);
				}

				interval:s:%d {
					print(@blkdev_dur); print(@blkdev_sector_count);
					clear(@blkdev_dur); clear(@blkdev_sector_count);
				}
				`, intervalSec)
			}
			return fmt.Sprintf(`
				tracepoint:block:block_io_start /pid == %d/ {
					@blkdev_sector_count[args->dev] += args->nr_sector;
					@blkdev_req[args->sector] = nsecs;
				}

				tracepoint:block:block_io_done /@blkdev_req[args->sector] != 0/ {
					@blkdev_dur[args->dev] += nsecs - @blkdev_req[args->sector];
					delete(@blkdev_req[args->sector]);
				}

				interval:s:%d {
					print(@blkdev_dur); print(@blkdev_sector_count);
					clear(@blkdev_dur); clear(@blkdev_sector_count);
				}
				`, pid, intervalSec)
		},
	}
)

Functions

func ListTracePoints

func ListTracePoints() map[string]bool

ListTracePoints returns the list of probes supported by bpftrace.

Types

type ActivityMonitor

type ActivityMonitor struct {
	// PID is the ID of process being traced. All probes share the same PID.
	PID int
	// RunningProbes consist of the bpftrace probes running in separate processes.
	RunningProbes map[Probe]*ProcProbe
	// SamplingIntervalSec is the tracing data sampling rate in seconds. All probes share the same sampling interval.
	SamplingIntervalSec int
	// contains filtered or unexported fields
}

ActivityMonitor uses eBPF probes to sample system and process activities at regular intervals.

func NewActivityMonitor

func NewActivityMonitor(logger *lalog.Logger, pid int, samplingIntervalSec int, procStarter platform.ExternalProcessStarter) (ret *ActivityMonitor)

NewActivityMonitor returns a new initialised process activity monitor.

func (*ActivityMonitor) InstallProbe

func (mon *ActivityMonitor) InstallProbe(probe Probe) error

StartProbe starts a new probe. It does nothing if the probe is already running.

func (*ActivityMonitor) StopProbe

func (mon *ActivityMonitor) StopProbe(probe Probe)

StopProbe stops a probe. It does nothing if the probe is not running.

type BpfMapRecord

type BpfMapRecord struct {
	Type string                    `json:"type"`
	Data map[string]map[string]int `json:"data"`
}

BpfMapRecord is a print out of map by bpftrace in JSON format.

type BpfNetIOTrafficCounter

type BpfNetIOTrafficCounter struct {
	IP          net.IP
	Port        int
	ByteCounter int
}

BpfNetIOTrafficCounter is a TCP traffic counter decoded from bpftrace map output.

func TcpTrafficFromBpfMap

func TcpTrafficFromBpfMap(bpfMap map[string]int) []BpfNetIOTrafficCounter

type BpfSample

type BpfSample struct {
	FDBytesRead            map[string]int
	FDBytesWritten         map[string]int
	TcpTrafficSources      []BpfNetIOTrafficCounter
	TcpTrafficDestinations []BpfNetIOTrafficCounter
	BlockDeviceIONanos     map[string]int
	BlockDeviceIOSectors   map[string]int
}

type Probe

type Probe int

Probe identifies a supported tracing probe. Only one instance of each probe may be attached globally or to an individual PID at a time.

type ProcProbe

type ProcProbe struct {
	// ScriptCode is the bpftrace script of this probe.
	ScriptCode string
	// SamplingIntervalSec is the tracing data sampling rate in seconds.
	SamplingIntervalSec int
	// Sample is the latest sample data deserialised from bpftrace output.
	Sample BpfSample
	// contains filtered or unexported fields
}

func NewProcProbe

func NewProcProbe(logger *lalog.Logger, pid int, procStarter platform.ExternalProcessStarter, scriptCode string, samplingIntervalSec int) (ret *ProcProbe)

NewProcProbe returns a newly initialised process probe. Caller needs to call Start to start gathering data.

func (*ProcProbe) Start

func (probe *ProcProbe) Start() error

Start executes bpftrace and returns to the caller. It does not wait for bpftrace to complete.

func (*ProcProbe) Stop

func (probe *ProcProbe) Stop()

Stop the probe's bpftrace process.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL