Skip to content

Tcp long conn metrics and accesslogs (new) #1298

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Apr 17, 2025

Conversation

yp969803
Copy link
Contributor

What type of PR is this?
/kind feature

What this PR does / why we need it:

Which issue(s) this PR fixes:
Fixes #1211

Special notes for your reviewer:

Does this PR introduce a user-facing change?:
Yes

Tcp long conn metrics and accesslogs

Copy link

codecov bot commented Apr 10, 2025

Codecov Report

Attention: Patch coverage is 37.61905% with 131 lines in your changes missing coverage. Please review.

Project coverage is 45.50%. Comparing base (cff9c00) to head (3a7c6e8).
Report is 32 commits behind head on main.

Files with missing lines Patch % Lines
pkg/controller/telemetry/metric.go 14.49% 59 Missing ⚠️
pkg/bpf/workload/skb.go 52.45% 39 Missing and 19 partials ⚠️
pkg/bpf/workload/loader.go 0.00% 8 Missing and 4 partials ⚠️
pkg/controller/telemetry/accesslog.go 71.42% 2 Missing ⚠️
Files with missing lines Coverage Δ
pkg/controller/telemetry/accesslog.go 90.32% <71.42%> (ø)
pkg/bpf/workload/loader.go 23.43% <0.00%> (-2.43%) ⬇️
pkg/bpf/workload/skb.go 52.45% <52.45%> (ø)
pkg/controller/telemetry/metric.go 48.55% <14.49%> (-2.87%) ⬇️

... and 4 files with indirect coverage changes


Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 5745678...3a7c6e8. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@yp969803
Copy link
Contributor Author

@hzxuzhonghu can you look at this pr, I have used a more improved approach

@hzxuzhonghu
Copy link
Member

Not sure why you open a new pr, basically it is more facilitating to update on the existing one. Which is more easy for reviewing

@yp969803
Copy link
Contributor Author

I have done a lot of experiments with the previous pr, it contains lots of unnecessary commits, also this time, I’ve taken a different and cleaner approach, which will make it much easier to review and merge.
Sorry for the inconvenience caused by me !!

@@ -3,6 +3,7 @@

#ifndef __KMESH_BPF_PROBE_H__
#define __KMESH_BPF_PROBE_H__
#define LONG_CONN_THRESHOLD_TIME (5 * 1000000000ULL) // 5s
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please move down after the include

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, i have misunderstood it to move down one line !!

bpf_sk_storage_delete(&map_of_sock_storage, sk);
}

static inline void observe_on_recv(struct bpf_sock *sk)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove, i donot see it is used now. I guess you are writing for recv metric later.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for inconvience, it is different approach, it do not need different hooks for send and recv only one hook do the work, currently i have drafted that pr

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think only do in recv is not right, some tcp connections only have send no recv message

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if that is the case i can use

SEC("cgroup_skb/egress")
int sendmsg_cgrp_prog(struct __sk_buff *skb)

Copy link
Contributor Author

@yp969803 yp969803 Apr 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if i you want i can also use both the hooks for send and recv
SEC("cgroup_skb/ingress")
and
SEC("cgroup_skb/egress")

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAK, we have sk_msg, we donont need cgroup_skb/egress now. cgroup_skb/ingress may still need to acquire the relatively realtime recv bytes

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yp969803 can you please explain about this confusion, could we duplicately calculate the send/recv bytes

@@ -35,18 +35,20 @@ struct tcp_probe_info {
__u32 type;
struct bpf_sock_tuple tuple;
struct orig_dst_info orig_dst;
__u32 sent_bytes;
__u32 received_bytes;
__u64 conn_id; /* sock_cookie */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we donot need this

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am using conn_id in the userspace as key for the map

tcp_conns := make(map[uint64]connMetric)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can use tuple as key, sock cookie is meaningless in userspace

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

different connections with same src and dest address has same tuple keys,

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The metrics actually are accumulated at application to application level. So it does not matter at all

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we want, for long connections, we can also accumulate metrics at connection level

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should and we must

#include "probe.h"

SEC("cgroup_skb/ingress")
int recvmsg_prog(struct __sk_buff *skb)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove and handle recv in the other pr. And i do not see it in the proposal?

Copy link
Member

@hzxuzhonghu hzxuzhonghu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I donot see the send msg logic, do you miss it?

@yp969803
Copy link
Contributor Author

@hzxuzhonghu I am using a different approach here, which does not require send_msg logic, I will make changes to the proposal for this pr to make the understanding of the approach clear, also I will explain the approach in today's meet

@hzxuzhonghu
Copy link
Member

#1298 (comment)

@LiZhenCheng9527 LiZhenCheng9527 added this to the v1.1 milestone Apr 10, 2025
@yp969803 yp969803 force-pushed the issue1211 branch 3 times, most recently from e5b081c to 5b3a8ef Compare April 10, 2025 14:14
@yp969803
Copy link
Contributor Author

These are the final logs

accesslog: 2025-04-09 15:05:58.511324246 +0000 UTC src.addr=10.244.2.10:39826, src.workload=busybox-telnet, src.namespace=default, dst.addr=10.244.2.7:23, dst.service=telnet-service.default.svc.cluster.local, dst.workload=busybox-telnet-server, dst.namespace=default, connection_id=712410, start_time=2025-04-09 15:05:58.511169295 +0000 UTC, direction=OUTBOUND, status=BPF_TCP_ESTABLISHED, sent_bytes=1, received_bytes=0, packet_loss=0, retransmissions=0, srtt=760us, min_rtt=95us, duration=0.154951ms
accesslog: 2025-04-09 15:05:58.511381102 +0000 UTC src.addr=10.244.2.10:39826, src.workload=busybox-telnet, src.namespace=default, dst.addr=10.244.2.7:23, dst.service=telnet-service.default.svc.cluster.local, dst.workload=busybox-telnet-server, dst.namespace=default, connection_id=712411, start_time=2025-04-09 15:05:58.511378715 +0000 UTC, direction=INBOUND, status=BPF_TCP_ESTABLISHED, sent_bytes=1, received_bytes=0, packet_loss=0, retransmissions=0, srtt=808us, min_rtt=101us, duration=0.002387ms
accesslog: 2025-04-09 15:06:03.676574254 +0000 UTC src.addr=10.244.2.10:39826, src.workload=busybox-telnet, src.namespace=default, dst.addr=10.244.2.7:23, dst.service=telnet-service.default.svc.cluster.local, dst.workload=busybox-telnet-server, dst.namespace=default, connection_id=712410, start_time=2025-04-09 15:05:58.511169295 +0000 UTC, direction=OUTBOUND, status=BPF_TCP_ESTABLISHED, sent_bytes=10, received_bytes=55, packet_loss=0, retransmissions=0, srtt=566us, min_rtt=52us, duration=5165.404959ms
accesslog: 2025-04-09 15:06:03.676628152 +0000 UTC src.addr=10.244.2.10:39826, src.workload=busybox-telnet, src.namespace=default, dst.addr=10.244.2.7:23, dst.service=telnet-service.default.svc.cluster.local, dst.workload=busybox-telnet-server, dst.namespace=default, connection_id=712411, start_time=2025-04-09 15:05:58.511378715 +0000 UTC, direction=INBOUND, status=BPF_TCP_ESTABLISHED, sent_bytes=11, received_bytes=29, packet_loss=0, retransmissions=0, srtt=14527us, min_rtt=12us, duration=5165.249437ms
accesslog: 2025-04-09 15:06:08.706203481 +0000 UTC src.addr=10.244.2.10:39826, src.workload=busybox-telnet, src.namespace=default, dst.addr=10.244.2.7:23, dst.service=telnet-service.default.svc.cluster.local, dst.workload=busybox-telnet-server, dst.namespace=default, connection_id=712410, start_time=2025-04-09 15:05:58.511169295 +0000 UTC, direction=OUTBOUND, status=BPF_TCP_ESTABLISHED, sent_bytes=30, received_bytes=124, packet_loss=0, retransmissions=0, srtt=5704us, min_rtt=43us, duration=10195.034186ms
accesslog: 2025-04-09 15:06:08.706228193 +0000 UTC src.addr=10.244.2.10:39826, src.workload=busybox-telnet, src.namespace=default, dst.addr=10.244.2.7:23, dst.service=telnet-service.default.svc.cluster.local, dst.workload=busybox-telnet-server, dst.namespace=default, connection_id=712411, start_time=2025-04-09 15:05:58.511378715 +0000 UTC, direction=INBOUND, status=BPF_TCP_ESTABLISHED, sent_bytes=32, received_bytes=55, packet_loss=0, retransmissions=0, srtt=41995us, min_rtt=8us, duration=10194.849478ms

Signed-off-by: Yash Patel <[email protected]>

rfac: added workload include to performance_probe.h

Signed-off-by: Yash Patel <[email protected]>

rfac: moved is_managed_bt_kmesh_skb to bpf_common.h

Signed-off-by: Yash Patel <[email protected]>

chore: run make gen

Signed-off-by: Yash Patel <[email protected]>

rfac: changed recv.c to cgrp_skb.c

Signed-off-by: Yash Patel <[email protected]>

rfac: created skb.go to load and attach cgroup_skb

Signed-off-by: Yash Patel <[email protected]>

rfac: tcp_probe.h

Signed-off-by: Yash Patel <[email protected]>

rfac: skb.go

Signed-off-by: Yash Patel <[email protected]>
timeInfo := fmt.Sprintf("%v", uptime)
sourceInfo := fmt.Sprintf("src.addr=%s, src.workload=%s, src.namespace=%s", accesslog.sourceAddress, accesslog.sourceWorkload, accesslog.sourceNamespace)
destinationInfo := fmt.Sprintf("dst.addr=%s, dst.service=%s, dst.workload=%s, dst.namespace=%s", accesslog.destinationAddress, accesslog.destinationService, accesslog.destinationWorkload, accesslog.destinationNamespace)
connectionInfo := fmt.Sprintf("direction=%s, sent_bytes=%d, received_bytes=%d, srtt=%dus, min_rtt=%dus, duration=%vms", accesslog.direction, data.sentBytes, data.receivedBytes, data.srtt, data.minRtt, (float64(data.duration) / 1000000.0))
connectionInfo := fmt.Sprintf("connection_id=%d, start_time=%s, direction=%s, status=%s, sent_bytes=%d, received_bytes=%d, packet_loss=%d, retransmissions=%d, srtt=%dus, min_rtt=%dus, duration=%vms", conn_metrics.connId, startTimeInfo, accesslog.direction, accesslog.status, conn_metrics.sentBytes, conn_metrics.receivedBytes, conn_metrics.packetLost, conn_metrics.totalRetrans, data.srtt, data.minRtt, (float64(data.duration) / 1000000.0))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we donot need to build accesslog periodically.

@@ -86,17 +102,18 @@ type statistics struct {
ConnectSuccess uint32
Direction uint32
State uint32
_ uint32
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add some comments

@@ -106,11 +123,13 @@ type connectionDataV4 struct {
OriginalAddr uint32
OriginalPort uint16
_ uint16
_ [3]uint32
_ [4]uint32
ConnId uint64
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove

@@ -383,9 +431,10 @@ func (m *MetricController) Run(ctx context.Context, mapOfTcpInfo *ebpf.Map) {
}
}

func buildV4Metric(buf *bytes.Buffer) (requestMetric, error) {
func buildV4Metric(buf *bytes.Buffer, tcp_conns map[uint64]connMetric) (requestMetric, error) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yp969803
Copy link
Contributor Author

@hzxuzhonghu i have addressed all your comments, you can look into it when you get time

@@ -81,5 +83,26 @@ static inline void observe_on_close(struct bpf_sock *sk)
}

tcp_report(sk, tcp_sock, storage, BPF_TCP_CLOSE);
bpf_sk_storage_delete(&map_of_sock_storage, sk);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove, this kind of map does not need to delete manually

@hzxuzhonghu
Copy link
Member

I think i have requested many many times, we donot need connection_id=712411,, which is meaningless from user view

@yp969803
Copy link
Contributor Author

yp969803 commented Apr 14, 2025

I will remove the connection_id from the access logs
I want conn_id in userspace for the key of the map

tcp_conns := make(map[uint64]connMetric)

I can use tuple as a key, but then I have to declare a new struct in userspace, also this struct will have variable size for IP v4 and v6 , which is a problem, also the size of the key will also increase, I think there is no flaw in using conn_id in the userspace as a map key because it is much more smaller size than the tupple and have fix size.

@hzxuzhonghu

@yp969803
Copy link
Contributor Author

yp969803 commented Apr 14, 2025

@nlgwcy can you review the ebpf part when you get time !!

@hzxuzhonghu
Copy link
Member

I want conn_id in userspace for the key of the map

Can you use the src dst {ip: port}, it can not conflict during the small interval

@yp969803
Copy link
Contributor Author

@hzxuzhonghu removed conn_id from everywhere as per your request, you can merge the pr now

@@ -44,6 +44,8 @@ struct {

struct sock_storage_data {
__u64 connect_ns;
__u64 last_report_ns;
__u64 sock_cookie;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can remove now, right?

…ric.go, also rmoved conn_id in tcp_probe_info

Signed-off-by: Yash Patel <[email protected]>

rfac: rmoved conn_id from tcp_probe_info

Signed-off-by: Yash Patel <[email protected]>
@hzxuzhonghu
Copy link
Member

@nlgwcy Is there any other comments

@hzxuzhonghu
Copy link
Member

/retest

Copy link
Member

@hzxuzhonghu hzxuzhonghu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/lgtm

Some tests needed, but can be added later

@kmesh-bot
Copy link
Collaborator

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: hzxuzhonghu

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@kmesh-bot kmesh-bot merged commit 578f3ee into kmesh-net:main Apr 17, 2025
12 of 13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[lfx-mentorship-2025-Mar-May] Metrics for TCP Long Connection
4 participants