Skip to content

Commit

Permalink
Support Attach Agent for NoAPM Java Application (#431)
Browse files Browse the repository at this point in the history
Signed-off-by: huxiangyuan <huxiangyuan@harmonycloud.cn>
  • Loading branch information
hocktea214 authored Feb 2, 2023
1 parent bfe2fb2 commit be46fd6
Show file tree
Hide file tree
Showing 10 changed files with 164 additions and 4 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

## Unreleased
### New features
- Support Attach Agent for NoAPM Java Application. ([#431](https://github.com/KindlingProject/kindling/pull/431))

### Enhancements
- Add an option edge_events_window_size to allow users to reduce the size of the files by narrowing the time window where seats the edge events. ([#437](https://github.com/KindlingProject/kindling/pull/437))
Expand Down
5 changes: 3 additions & 2 deletions collector/docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ RUN yum install -y qt5-qtbase-devel
RUN yum install -y gdb
COPY gdb_print.sh /app/
RUN curl https://k8s-bpf-probes-public.oss-cn-hangzhou.aliyuncs.com/kindling-falcolib-probe-v0.6.0.tar.gz -o kindling-falcolib-probe.tar.gz
RUN curl -O https://k8s-bpf-probes-public.oss-cn-hangzhou.aliyuncs.com/async-profiler-kindling-v1.0.1.tar.gz
RUN tar -zvxf async-profiler-kindling-v1.0.1.tar.gz

COPY build-asyncprofiler.sh /app/
RUN sh build-asyncprofiler.sh

COPY libso/libkindling.so /lib64/
COPY libso/* /usr/lib64/
Expand Down
5 changes: 3 additions & 2 deletions collector/docker/DockerfileLocalProbe
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ RUN yum install -y qt5-qtbase-devel
RUN yum install -y gdb
COPY gdb_print.sh /app/
COPY kindling-falcolib-probe.tar.gz ./
RUN curl -O https://k8s-bpf-probes-public.oss-cn-hangzhou.aliyuncs.com/async-profiler-kindling-v1.0.1.tar.gz
RUN tar -zvxf async-profiler-kindling-v1.0.1.tar.gz

COPY build-asyncprofiler.sh /app/
RUN sh build-asyncprofiler.sh

COPY libso/libkindling.so /lib64/
COPY libso/* /usr/lib64/
Expand Down
24 changes: 24 additions & 0 deletions collector/docker/build-asyncprofiler.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
ASYNC_PROFILER=async-profiler-1.0.2-linux-x64.tar.gz
KINDLING_JAVA=kindling-java-1.0.2.tar.gz
APM_ALL=apm-all-3.1.0.jar

SCRIPT_DIR="$(cd "$(dirname "$SCRIPT_BIN")" > /dev/null 2>&1; pwd -P)"
if [ ! -d "$SCRIPT_DIR/async-profiler" ];then
curl -O https://k8s-bpf-probes-public.oss-cn-hangzhou.aliyuncs.com/$ASYNC_PROFILER
tar -zvxf $ASYNC_PROFILER
rm -f $ASYNC_PROFILER
fi

if [ ! -d "$SCRIPT_DIR/async-profiler/agent/kindling-java" ];then
curl -O https://k8s-bpf-probes-public.oss-cn-hangzhou.aliyuncs.com/$KINDLING_JAVA
tar -zxvf $KINDLING_JAVA
mkdir -p $SCRIPT_DIR/async-profiler/agent
mv kindling-java $SCRIPT_DIR/async-profiler/agent/
rm -f $KINDLING_JAVA
fi

if [ ! -f "$SCRIPT_DIR/async-profiler/agent/apm-all/apm-all.jar" ];then
mkdir -p $SCRIPT_DIR/async-profiler/agent/apm-all
cd $SCRIPT_DIR/async-profiler/agent/apm-all
curl -o apm-all.jar https://k8s-bpf-probes-public.oss-cn-hangzhou.aliyuncs.com/$APM_ALL
fi
43 changes: 43 additions & 0 deletions collector/pkg/component/controller/profile_module.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"errors"
"fmt"
"time"
"unsafe"

"github.com/Kindling-project/kindling/collector/pkg/component"
)
Expand Down Expand Up @@ -88,6 +89,26 @@ func (p *Profile) GetModuleKey() string {
return p.Name()
}

func startAttachAgent(pid int) string {
result := C.startAttachAgent(C.int(pid))
errorMsg := C.GoString(result)
C.free(unsafe.Pointer(result))
if len(errorMsg) > 0 {
return errorMsg
}
return ""
}

func stopAttachAgent(pid int) string {
result := C.stopAttachAgent(C.int(pid))
errorMsg := C.GoString(result)
C.free(unsafe.Pointer(result))
if len(errorMsg) > 0 {
return errorMsg
}
return ""
}

func startDebug(pid int, tid int) error {
C.startProfileDebug(C.int(pid), C.int(tid))
return nil
Expand Down Expand Up @@ -123,6 +144,28 @@ func (p *Profile) HandRequest(req *ControlRequest) *ControlResponse {
Code: NoError,
Msg: "stop success",
}
case "start_attach_agent":
if errMsg := startAttachAgent(req.Pid); errMsg != "" {
return &ControlResponse{
Code: StartWithError,
Msg: errMsg,
}
}
return &ControlResponse{
Code: NoError,
Msg: "start success",
}
case "stop_attach_agent":
if errMsg := stopAttachAgent(req.Pid); errMsg != "" {
return &ControlResponse{
Code: StopWithError,
Msg: errMsg,
}
}
return &ControlResponse{
Code: NoError,
Msg: "stop success",
}
case "status":
var status string
switch p.Status() {
Expand Down
2 changes: 2 additions & 0 deletions collector/pkg/component/receiver/cgoreceiver/cgo_func.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ int getKindlingEvent(void **kindlingEvent);
int subEventForGo(char* eventName, char* category, void *params);
int startProfile();
int stopProfile();
char* startAttachAgent(int pid);
char* stopAttachAgent(int pid);
void startProfileDebug(int pid, int tid);
void stopProfileDebug();
void getCaptureStatistics();
Expand Down
3 changes: 3 additions & 0 deletions probe/src/cgo/cgo_func.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ int getKindlingEvent(void** kindlingEvent) { return getEvent(kindlingEvent); }
int startProfile() { return start_profile(); }
int stopProfile() { return stop_profile(); }

char* startAttachAgent(int pid) { return start_attach_agent(pid); }
char* stopAttachAgent(int pid) { return stop_attach_agent(pid); }

void subEventForGo(char* eventName, char* category, void *params) { sub_event(eventName, category, (event_params_for_subscribe *)params); }
void startProfileDebug(int pid, int tid) { start_profile_debug(pid, tid); }

Expand Down
2 changes: 2 additions & 0 deletions probe/src/cgo/cgo_func.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ int getKindlingEvent(void** kindlingEvent);
void subEventForGo(char* eventName, char* category, void* params);
int startProfile();
int stopProfile();
char* startAttachAgent(int pid);
char* stopAttachAgent(int pid);
void startProfileDebug(int pid, int tid);
void stopProfileDebug();
void getCaptureStatistics();
Expand Down
77 changes: 77 additions & 0 deletions probe/src/cgo/kindling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -934,6 +934,83 @@ void attach_pid(char* pid, bool is_new_start, bool is_attach, bool is_all_attach
}
}

void attach_agent(int64_t pid, char* error_message, bool is_attach) {
char result_buf[1024], command[1024];
string attach_command_prefix;
if (is_attach) {
attach_command_prefix = "./async-profiler/jattach.sh start ";
} else {
attach_command_prefix = "./async-profiler/jattach.sh stop ";
}
attach_command_prefix.append(std::to_string(pid));
strcpy(command, attach_command_prefix.c_str());

FILE* fp;
fp = popen(command, "r");
if (NULL == fp) {
perror("popen execute failed!\n");
strcpy(error_message, "popen execute failed");
return;
}
if (is_attach) {
cout << "------"
<< " start attach agent for pid " << pid << "------" << endl;
} else {
cout << "------"
<< " start detach agent for pid " << pid << "------" << endl;
}

char* error_msg;
while (fgets(result_buf, sizeof(result_buf), fp) != NULL) {
if ('\n' == result_buf[strlen(result_buf) - 1]) {
result_buf[strlen(result_buf) - 1] = '\0';
}
error_msg = strstr(result_buf, "[ERROR] ");
if (error_msg) {
strcpy(error_message, error_msg);
}
printf("%s\r\n", result_buf);
}

int rc = pclose(fp);
if (-1 == rc) {
perror("close command fp failed!\n");
strcpy(error_message, "close command fp failed");
return;
} else {
printf("command:【%s】command process status:【%d】command return value:【%d】\r\n", command,
rc, WEXITSTATUS(rc));
}

if (is_attach) {
cout << "------end attach agent for pid " << pid << "------" << endl;
} else {
cout << "------end detach agent for pid " << pid << "------" << endl;
}
}

char* start_attach_agent(int64_t pid) {
char* error_message = (char*) malloc(1024 * sizeof(char));
error_message[0] = '\0';
if (!inspector) {
strcpy(error_message, "Please start profile first");
} else {
attach_agent(pid, error_message, true);
}
return error_message;
}

char* stop_attach_agent(int64_t pid) {
char* error_message = (char*) malloc(1024 * sizeof(char));
error_message[0] = '\0';
if (!inspector) {
strcpy(error_message, "Please start profile first");
} else {
attach_agent(pid, error_message, false);
}
return error_message;
}

int start_profile() {
if (!inspector) {
return -1;
Expand Down
6 changes: 6 additions & 0 deletions probe/src/cgo/kindling.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ void print_profile_debug_info(sinsp_evt* sevt);

void attach_pid(char* pid, bool is_new_start, bool is_attach, bool is_all_attach, bool is_ps);

char* start_attach_agent(int64_t pid);

char* stop_attach_agent(int64_t pid);

void attach_agent(int64_t pid, char* error_message, bool is_attach);

void get_capture_statistics();

uint16_t get_protocol(scap_l4_proto proto);
Expand Down

0 comments on commit be46fd6

Please sign in to comment.