Skip to content

Commit f53f8fc

Browse files
authored
Merge pull request #70 from akto-api-security/cpu_optimizations
Cpu optimizations
2 parents 155f1af + 866de1c commit f53f8fc

File tree

8 files changed

+100
-38
lines changed

8 files changed

+100
-38
lines changed

ebpf/main.go

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -152,15 +152,19 @@ func run() {
152152
var isRunning_2 bool
153153
var mu_2 = &sync.Mutex{}
154154

155-
pollInterval := 5 * time.Minute
155+
pollInterval := 20 * time.Minute
156156

157157
trafficUtils.InitVar("UPROBE_POLL_INTERVAL", &pollInterval)
158158

159159
ssl.InitMaps(bpfModule)
160160

161161
if captureSsl == "true" || captureAll == "true" {
162162
go func() {
163-
for {
163+
fmt.Printf("Starting to attach to processes in ticker start\n")
164+
ticker := time.NewTicker(pollInterval) // Create a ticker to trigger every minute
165+
defer ticker.Stop()
166+
for range ticker.C {
167+
fmt.Printf("Starting to attach to processes in ticker\n")
164168
if !isRunning_2 {
165169
mu_2.Lock()
166170
if isRunning_2 {
@@ -177,8 +181,9 @@ func run() {
177181
isRunning_2 = false
178182
mu_2.Unlock()
179183
}
180-
time.Sleep(pollInterval)
184+
fmt.Printf("Ended attaching to processes in ticker\n")
181185
}
186+
fmt.Printf("Ended attaching to processes in ticker end\n")
182187
}()
183188
}
184189

@@ -194,6 +199,13 @@ func run() {
194199
}
195200
}
196201

202+
//ticker := time.NewTicker(15 * time.Second)
203+
//defer ticker.Stop()
204+
//
205+
//for range ticker.C {
206+
// go captureCpuProfile()
207+
//}
208+
197209
sig := make(chan os.Signal, 1)
198210
signal.Notify(sig, syscall.SIGHUP, syscall.SIGINT, syscall.SIGQUIT, syscall.SIGTERM)
199211
log.Println("Sniffer is ready")
@@ -207,3 +219,24 @@ func captureMemoryProfile() {
207219

208220
pprof.WriteHeapProfile(f) // Write memory profile
209221
}
222+
223+
func captureCpuProfile() {
224+
timestamp := time.Now().Format("20060102_150405")
225+
fileName := fmt.Sprintf("cpu_%s.prof", timestamp)
226+
f, err := os.Create(fileName)
227+
if err != nil {
228+
panic("could not create CPU profile: " + err.Error())
229+
}
230+
defer f.Close()
231+
232+
if err := pprof.StartCPUProfile(f); err != nil {
233+
panic("could not start CPU profile: " + err.Error())
234+
}
235+
fmt.Println("CPU profiling started")
236+
237+
// Allow profiling for a certain duration or simulate workload
238+
time.Sleep(12 * time.Second) // Sleep for 10 seconds to simulate CPU activity
239+
240+
pprof.StopCPUProfile()
241+
fmt.Println("CPU profiling stopped")
242+
}

ebpf/uprobeBuilder/process/process.go

Lines changed: 16 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"fmt"
66
"log"
77
"os"
8+
"os/exec"
89
"regexp"
910
"strings"
1011

@@ -20,39 +21,27 @@ var (
2021
func CheckProcessCGroupBelongToKube(pid int32) ([]string, error) {
2122
cgroupAbsPath := fmt.Sprintf("/proc/%d/cgroup", pid)
2223
processCgroupFilePath := host.GetFileInHost(cgroupAbsPath)
23-
cgroupFile, err := os.Open(processCgroupFilePath)
24-
if err != nil {
25-
return nil, err
26-
}
27-
defer cgroupFile.Close()
28-
29-
cache := make(map[string]bool)
30-
scanner := bufio.NewScanner(cgroupFile)
31-
for scanner.Scan() {
32-
infos := strings.Split(scanner.Text(), ":")
33-
if len(infos) < 3 {
34-
continue
35-
}
36-
lastPath := strings.LastIndex(infos[2], "/")
37-
if lastPath > 1 && lastPath != len(infos[2])-1 {
38-
path := infos[2][lastPath+1:]
39-
// ex: cri-containerd-7dae778c37bd1204677518f1032bbecf01f5c41878ea7bd370021263417cc626.scope
40-
if kubepod := kubepodsRegex.FindStringSubmatch(path); len(kubepod) >= 1 {
41-
path = kubepod[1]
42-
}
43-
cache[path] = true
44-
}
45-
}
46-
if len(cache) == 0 {
24+
output := checkKubeProcess(processCgroupFilePath)
25+
if len(output) <= 1 {
4726
return nil, fmt.Errorf("no k8s cgroups")
27+
} else {
28+
log.Printf("successfully found a kube process %s", processCgroupFilePath)
4829
}
4930
result := make([]string, 0)
50-
for k := range cache {
51-
result = append(result, k)
52-
}
31+
result = append(result, output)
5332
return result, nil
5433
}
5534

35+
func checkKubeProcess(exePath string) string {
36+
cmd := exec.Command("sh", "-c", "strings "+exePath+" | grep cri-containerd | head -n 1")
37+
output, err := cmd.CombinedOutput()
38+
if err != nil {
39+
fmt.Printf("Error executing command in checkKubeProcess: %v\n", err)
40+
return ""
41+
}
42+
return string(output)
43+
}
44+
5645
func isIgnoreModuleName(name string) bool {
5746
return name != "" &&
5847
(strings.HasPrefix(name, "//anon") ||

ebpf/uprobeBuilder/process/processFactory.go

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"log"
66
"strings"
77
"sync"
8+
"time"
89

910
"github.com/akto-api-security/mirroring-api-logging/ebpf/uprobeBuilder/ssl"
1011
"github.com/akto-api-security/mirroring-api-logging/trafficUtil/utils"
@@ -29,15 +30,17 @@ type Process struct {
2930
}
3031

3132
type ProcessFactory struct {
32-
processMap map[int32]Process
33-
mutex *sync.RWMutex
33+
processMap map[int32]Process
34+
mutex *sync.RWMutex
35+
unattachedProcess map[int32]bool
3436
}
3537

3638
// NewFactory creates a new instance of the factory.
3739
func NewFactory() *ProcessFactory {
3840
return &ProcessFactory{
39-
processMap: make(map[int32]Process),
40-
mutex: &sync.RWMutex{},
41+
processMap: make(map[int32]Process),
42+
mutex: &sync.RWMutex{},
43+
unattachedProcess: make(map[int32]bool),
4144
}
4245
}
4346

@@ -80,7 +83,13 @@ func (processFactory *ProcessFactory) AddNewProcessesToProbe(bpfModule *bcc.Modu
8083
}
8184
fmt.Printf("Attempt for %v processes\n", len(pidSet))
8285
for pid := range pidSet {
83-
_, ok := processFactory.processMap[pid]
86+
time.Sleep(200 * time.Millisecond)
87+
_, ok := processFactory.unattachedProcess[pid]
88+
if ok {
89+
fmt.Printf("Not attempting for %v processes\n", pid)
90+
continue
91+
}
92+
_, ok = processFactory.processMap[pid]
8493
if !ok {
8594

8695
if checkSelf(pid) {
@@ -94,13 +103,15 @@ func (processFactory *ProcessFactory) AddNewProcessesToProbe(bpfModule *bcc.Modu
94103
if err != nil {
95104
if !probeAllPid {
96105
fmt.Printf("No libraries for pid: %v %v\n", pid, err)
106+
processFactory.unattachedProcess[pid] = true
97107
continue
98108
}
99109
}
100110

101111
libraries, err := FindLibrariesPathInMapFile(pid)
102112
if err != nil {
103113
fmt.Printf("No libraries for pid: %v %v\n", pid, err)
114+
processFactory.unattachedProcess[pid] = true
104115
continue
105116
}
106117

@@ -149,6 +160,8 @@ func (processFactory *ProcessFactory) AddNewProcessesToProbe(bpfModule *bcc.Modu
149160
log.Printf("Node probing error: %v %v\n", pid, err)
150161
}
151162

163+
processFactory.unattachedProcess[pid] = true
164+
152165
}
153166
}
154167
}

ebpf/uprobeBuilder/ssl/gohelper.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,16 @@ func gettingGoVersionFromString(s string) (v *version.Version, success bool, err
6767
return v, true, err
6868
}
6969

70+
func checkGoProcess(exePath string) bool {
71+
cmd := exec.Command("sh", "-c", "strings "+exePath+" | grep go1")
72+
output, err := cmd.CombinedOutput()
73+
if err != nil {
74+
fmt.Printf("Error executing command in checkGoProcess: %v\n", err)
75+
return false
76+
}
77+
return len(output) > 1
78+
}
79+
7080
type goStringInC struct {
7181
Ptr uint64
7282
Size uint64

ebpf/uprobeBuilder/ssl/gotls.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,14 @@ func TryGoTLSProbes(pid int32, m map[string]bool, bpfModule *bcc.Module) (bool,
2929
if err != nil {
3030
return false, err
3131
}
32+
33+
isGo := checkGoProcess(symLinkHostPath)
34+
if !isGo {
35+
return false, fmt.Errorf("Not a go process")
36+
} else {
37+
log.Printf("successfully found a go process %s", symLinkHostPath)
38+
}
39+
3240
elfFile, err := elf.NewFile(symLinkHostPath)
3341
if err != nil {
3442
return false, fmt.Errorf("read executable file error: %v", err)

ebpf/uprobeBuilder/ssl/node.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,9 @@ package ssl
22

33
import (
44
"fmt"
5-
"log"
6-
75
"github.com/akto-api-security/mirroring-api-logging/ebpf/bpfwrapper"
86
"github.com/iovisor/gobpf/bcc"
7+
"log"
98
)
109

1110
type NodeTLSSymbolAddress struct {

ebpf/uprobeBuilder/ssl/openssl.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ package ssl
22

33
import (
44
"fmt"
5+
"github.com/akto-api-security/mirroring-api-logging/ebpf/bpfwrapper"
56
"log"
67
"os/exec"
78
"regexp"
89
"strconv"
910
"strings"
1011

11-
"github.com/akto-api-security/mirroring-api-logging/ebpf/bpfwrapper"
1212
"github.com/iovisor/gobpf/bcc"
1313
)
1414

trafficUtil/utils/stats.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,15 @@ func LogMemoryStats() int {
2626
log.Println("Alloc in MB: ", mem)
2727
log.Println("Sys in MB: ", m.Sys/1024/1024)
2828

29+
// gc stats
30+
31+
log.Println("Last gc finished: ", m.LastGC)
32+
log.Println("Target heap size of next gc cycle: ", m.NextGC)
33+
log.Println("Stop The world pauses ", m.PauseTotalNs)
34+
log.Println("GcSys ", m.GCSys)
35+
log.Println("GCCPUFraction ", m.GCCPUFraction)
36+
log.Println("NumGC ", m.NumGC)
37+
log.Println("NumForcedGC ", m.NumForcedGC)
38+
2939
return mem
3040
}

0 commit comments

Comments
 (0)