inspektor-gadget

Форк
0
114 строк · 2.6 Кб
1
// Copyright 2023 The Inspektor Gadget authors
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//     http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14

15
//go:build !withoutebpf
16

17
package tracer
18

19
import (
20
	"bufio"
21
	"fmt"
22
	"os"
23
	"os/exec"
24

25
	gadgetcontext "github.com/inspektor-gadget/inspektor-gadget/pkg/gadget-context"
26
	"github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets"
27
	"github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets/script/types"
28
)
29

30
type Config struct {
31
	Program string
32
}
33

34
type Tracer struct {
35
	eventCallback func(ev *types.Event)
36
	config        Config
37
}
38

39
func (t *Tracer) Run(gadgetCtx gadgets.GadgetContext) error {
40
	params := gadgetCtx.GadgetParams()
41
	t.config.Program = params.Get(ParamProgram).AsString()
42
	log := gadgetCtx.Logger()
43

44
	// TODO: Consider using CommandContext() once we support Go 1.20
45
	cmd := exec.Command("bpftrace", "-e", t.config.Program)
46

47
	stdout, err := cmd.StdoutPipe()
48
	if err != nil {
49
		return fmt.Errorf("getting stdout pipe: %w", err)
50
	}
51

52
	stderr, err := cmd.StderrPipe()
53
	if err != nil {
54
		return fmt.Errorf("getting stderr pipe: %w", err)
55
	}
56

57
	if err := cmd.Start(); err != nil {
58
		return fmt.Errorf("running bpftrace: %w", err)
59
	}
60

61
	// read and send stdout as events
62
	go func() {
63
		scanner := bufio.NewScanner(stdout)
64

65
		for scanner.Scan() {
66
			t.eventCallback(&types.Event{
67
				Output: scanner.Text(),
68
			})
69
		}
70

71
		if err := scanner.Err(); err != nil {
72
			log.Error("error reading bpftrace output: %s", err)
73
		}
74
	}()
75

76
	// print stderr through logger
77
	go func() {
78
		scanner := bufio.NewScanner(stderr)
79

80
		for scanner.Scan() {
81
			log.Error(scanner.Text())
82
		}
83

84
		if err := scanner.Err(); err != nil {
85
			log.Error("error reading bpftrace output: %s", err)
86
		}
87
	}()
88

89
	gadgetcontext.WaitForTimeoutOrDone(gadgetCtx)
90

91
	if err := cmd.Process.Signal(os.Interrupt); err != nil {
92
		log.Errorf("failed to stop process: %s", err)
93
		return nil
94
	}
95

96
	if err := cmd.Wait(); err != nil {
97
		log.Errorf("failed to wait process: %s", err)
98
		return nil
99
	}
100

101
	return nil
102
}
103

104
func (t *Tracer) SetEventHandler(handler any) {
105
	nh, ok := handler.(func(ev *types.Event))
106
	if !ok {
107
		panic("event handler invalid")
108
	}
109
	t.eventCallback = nh
110
}
111

112
func (g *GadgetDesc) NewInstance() (gadgets.Gadget, error) {
113
	return &Tracer{}, nil
114
}
115

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.