Project: SkyWalking (Observability and Analysis / Observability)
File: profiling-protocol.md

SkyWalking offers two types of Profiling, in-process and out-process, each with its own API. commonly interacts with auto-instrument agents. It gathers stack traces of programs and sends the data to the OAP for further analysis. ```protobuf syntax = "proto3"; package skywalking.v3; option javamultiplefiles = true; option java_package = "org.apache.skywalking.apm.network.language.profile.v3"; option csharp_namespace = "SkyWalking.NetworkProtocol.V3"; option go_package = "skywalking.apache.org/repo/goapi/collect/language/profile/v3"; import "common/Command.proto"; service ProfileTask { // query all sniffer need to execute profile task commands rpc getProfileTaskCommands (ProfileTaskCommandQuery) returns (Commands) { } // collect dumped thread snapshot rpc collectSnapshot (stream ThreadSnapshot) returns (Commands) { } // report profiling task finished rpc reportTaskFinish (ProfileTaskFinishReport) returns (Commands) { } } message ProfileTaskCommandQuery { // current sniffer information string service = 1; string serviceInstance = 2; // last command timestamp int64 lastCommandTime = 3; } // dumped thread snapshot message ThreadSnapshot { // profile task id string taskId = 1; // dumped segment id string traceSegmentId = 2; // dump timestamp int64 time = 3; // snapshot dump sequence, start with zero int32 sequence = 4; // snapshot stack ThreadStack stack = 5; } message ThreadStack { // stack code signature list repeated string codeSignatures = 1; } // profile task finished report message ProfileTaskFinishReport { // current sniffer information string service = 1; string serviceInstance = 2; // profile task string taskId = 3; } ``` interacts with eBPF agent, which receives tasks and captures data, then reports it to the OAP for further analysis. Similar to Service Instance, all processes must be reported to the OAP storage segment prior to analysis. ```protobuf syntax = "proto3"; package skywalking.v3; option javamultiplefiles = true; option java_package = "org.apache.skywalking.apm.network.ebpf.profiling.process.v3"; option go_package = "skywalking.apache.org/repo/goapi/collect/ebpf/profiling/process/v3"; import "common/Common.proto"; import "common/Command.proto"; // Define the detected processes and report them. service EBPFProcessService { // Report discovered process in Rover rpc reportProcesses (EBPFProcessReportList) returns (EBPFReportProcessDownstream) { } // Keep the process alive in the backend. rpc keepAlive (EBPFProcessPingPkgList) returns (Commands) { } } message EBPFProcessReportList { repeated EBPFProcessProperties processes = 1; // An ID generated by eBPF agent, should be unique

string ebpfAgentID = 2; } message EBPFProcessProperties { // The Process metadata oneof metadata { EBPFHostProcessMetadata hostProcess = 1; EBPFKubernetesProcessMetadata k8sProcess = 2; } } message EBPFHostProcessMetadata { // [required] Entity metadata // Must ensure that entity information is unique at the time of reporting EBPFProcessEntityMetadata entity = 1; // [required] The Process id of the host int32 pid = 2; // [optional] properties of the process repeated KeyStringValuePair properties = 3; } // Process Entity metadata message EBPFProcessEntityMetadata { // [required] Process belong layer name which define in the backend string layer = 1; // [required] Process belong service name string serviceName = 2; // [required] Process belong service instance name string instanceName = 3; // [required] Process name string processName = 4; // Process labels for aggregate from service repeated string labels = 5; } // Kubernetes process metadata message EBPFKubernetesProcessMetadata { // [required] Entity metadata // Must ensure that entity information is unique at the time of reporting EBPFProcessEntityMetadata entity = 1; // [required] The Process id of the host int32 pid = 2; // [optional] properties of the process repeated KeyStringValuePair properties = 3; } message EBPFReportProcessDownstream { repeated EBPFProcessDownstream processes = 1; } message EBPFProcessDownstream { // Generated process id string processId = 1; // Locate the process by basic information oneof process { EBPFHostProcessDownstream hostProcess = 2; EBPFKubernetesProcessDownstream k8sProcess = 3; } } message EBPFHostProcessDownstream { int32 pid = 1; EBPFProcessEntityMetadata entityMetadata = 2; } // Kubernetes process downstream message EBPFKubernetesProcessDownstream { int32 pid = 1; EBPFProcessEntityMetadata entityMetadata = 2; } message EBPFProcessPingPkgList { repeated EBPFProcessPingPkg processes = 1; // An ID generated by eBPF agent, should be unique globally. string ebpfAgentID = 2; } message EBPFProcessPingPkg { // Process entity EBPFProcessEntityMetadata entityMetadata = 1; // Minimize necessary properties repeated KeyStringValuePair properties = 2; } ``` ```protobuf syntax = "proto3"; package skywalking.v3; option javamultiplefiles = true; option java_package = "org.apache.skywalking.apm.network.ebpf.profiling.v3"; option go_package = "skywalking.apache.org/repo/goapi/collect/ebpf/profiling/v3"; import "common/Command.proto"; // Define the Rover Process profiling task and upload profiling data. service EBPFProfilingService { // Query profiling (start or stop) tasks rpc queryTasks (EBPFProfilingTaskQuery) returns (Commands) { } // collect profiling data rpc collectProfilingData (stream EBPFProfilingData) returns (Commands) { } } message EBPFProfilingTaskQuery { // rover instance id string roverInstanceId = 1; // latest task update time int64 latestUpdateTime = 2; } message EBPFProfilingData { // task metadata EBPFProfilingTaskMetadata task = 1; // profiling data oneof profiling { EBPFOnCPUProfiling onCPU = 2; EBPFOffCPUProfiling offCPU = 3; } } message EBPFProfilingTaskMetadata { // profiling task id string taskId = 1; // profiling process id string processId = 2; // the start time of this profiling process int64 profilingStartTime = 3; // report time int64 currentTime = 4; } message EBPFProfilingStackMetadata { // stack type EBPFProfilingStackType stackType = 1; // stack id from kernel provide int32 stackId = 2; // stack symbols repeated string stackSymbols = 3; } enum EBPFProfilingStackType { PROCESSKERNELSPACE = 0; PROCESSUSERSPACE = 1; } message EBPFOnCPUProfiling { // stack data in one task(thread) repeated EBPFProfilingStackMetadata stacks = 1; // stack counts int32 dumpCount = 2; } message EBPFOffCPUProfiling { // stack data in one task(thread) repeated EBPFProfilingStackMetadata stacks = 1; // total count of the process is switched to off cpu by the scheduler. int32 switchCount = 2; // where time(nanoseconds) is spent waiting while blocked on I/O, locks, timers, paging/swapping, etc. int64 duration = 3; } ```