Profiling APIs

SkyWalking offers two types of Profiling, in-process and out-process, each with its own API.

In-process profiling APIs

In-process profiling commonly interacts with auto-instrument agents. It gathers stack traces of programs and sends the data to the OAP for further analysis.

syntax = "proto3";

package skywalking.v3;

option java_multiple_files = 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;
}

Out-process profiling

Out-process profiling interacts with eBPF agent, which receives tasks and captures data, then reports it to the OAP for further analysis.

Process APIs

Similar to Service Instance, all processes must be reported to the OAP storage segment prior to analysis.

syntax = "proto3";

package skywalking.v3;

option java_multiple_files = 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 globally.
    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;
}

Out-process profiling APIs

syntax = "proto3";

package skywalking.v3;

option java_multiple_files = 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 {
    PROCESS_KERNEL_SPACE = 0;
    PROCESS_USER_SPACE = 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;
}