Core analysis engine and storage abstractions for Apache SkyWalking observability platform
—
The SkyWalking profiling system provides distributed performance profiling capabilities for Java applications, including trace-based profiling, thread snapshots, and performance analysis. It enables detailed method-level performance monitoring with minimal overhead.
Service for querying profiling tasks and retrieving profiling results.
public class ProfileTaskQueryService implements Service {
/**
* Queries profiling tasks with pagination and filtering
* @param serviceId Service identifier to filter tasks
* @param endpointName Endpoint name filter (optional)
* @param startTimeBucket Start time bucket for task query
* @param endTimeBucket End time bucket for task query
* @param paging Pagination configuration
* @return Paginated list of profiling tasks
* @throws IOException If query fails
*/
public ProfileTaskList getTaskList(String serviceId, String endpointName,
long startTimeBucket, long endTimeBucket,
Pagination paging) throws IOException;
/**
* Gets detailed information about specific profiling task
* @param taskId Profiling task identifier
* @return Detailed task information
* @throws IOException If query fails
*/
public ProfileTask getTaskDetail(String taskId) throws IOException;
/**
* Gets profiling task logs for monitoring task execution
* @param taskId Profiling task identifier
* @param paging Pagination configuration
* @return Paginated task execution logs
* @throws IOException If query fails
*/
public ProfileTaskLogList getTaskLogs(String taskId, Pagination paging) throws IOException;
/**
* Gets thread snapshots for profiling task
* @param taskId Profiling task identifier
* @param segmentId Trace segment identifier
* @param paging Pagination configuration
* @return List of thread snapshots
* @throws IOException If query fails
*/
public List<ProfiledSegment> getProfiledSegments(String taskId, String segmentId,
Pagination paging) throws IOException;
/**
* Analyzes thread snapshots to generate profiling tree
* @param segmentId Trace segment identifier
* @param timeRanges Time ranges within segment for analysis
* @return Profiling analysis tree with method call hierarchy
* @throws IOException If analysis fails
*/
public ProfileAnalyzeTimeRange getProfileAnalyzeTimeRange(String segmentId,
List<ProfileAnalyzeTimeRange> timeRanges)
throws IOException;
/**
* Gets thread snapshot details for specific time range
* @param segmentId Trace segment identifier
* @param threadId Thread identifier
* @param startTime Start time for snapshot range
* @param endTime End time for snapshot range
* @return Thread snapshot data
* @throws IOException If query fails
*/
public List<ThreadSnapshot> getThreadSnapshots(String segmentId, String threadId,
long startTime, long endTime) throws IOException;
}Service for creating and managing profiling tasks.
public class ProfileTaskMutationService implements Service {
/**
* Creates new profiling task
* @param creationRequest Profiling task creation parameters
* @return Created task result with task ID
* @throws IOException If task creation fails
*/
public ProfileTaskCreationResult createTask(ProfileTaskCreationRequest creationRequest)
throws IOException;
/**
* Gets profiling task creation result by request ID
* @param requestId Task creation request identifier
* @return Task creation result
* @throws IOException If query fails
*/
public ProfileTaskCreationResult getTaskCreationResult(String requestId) throws IOException;
/**
* Cancels active profiling task
* @param taskId Profiling task identifier to cancel
* @return Cancellation result
* @throws IOException If cancellation fails
*/
public ProfileTaskCancellationResult cancelTask(String taskId) throws IOException;
/**
* Updates profiling task configuration
* @param taskId Profiling task identifier
* @param updateRequest Task update parameters
* @return Update result
* @throws IOException If update fails
*/
public ProfileTaskUpdateResult updateTask(String taskId, ProfileTaskUpdateRequest updateRequest)
throws IOException;
/**
* Validates profiling task parameters before creation
* @param request Task creation request to validate
* @return Validation result with error messages if invalid
*/
public ProfileTaskValidationResult validateTaskRequest(ProfileTaskCreationRequest request);
/**
* Gets profiling task statistics
* @param taskId Profiling task identifier
* @return Task execution statistics
* @throws IOException If query fails
*/
public ProfileTaskStats getTaskStats(String taskId) throws IOException;
}Storage record for profiling task metadata and configuration.
public class ProfileTaskRecord extends Record {
@Column(name = "task_id", dataType = Column.ValueDataType.VARCHAR, length = 255)
@Getter @Setter
private String taskId;
@Column(name = "service_id", dataType = Column.ValueDataType.VARCHAR, length = 255)
@Getter @Setter
private String serviceId;
@Column(name = "endpoint_name", dataType = Column.ValueDataType.VARCHAR, length = 512)
@Getter @Setter
private String endpointName;
@Column(name = "start_time", dataType = Column.ValueDataType.BIGINT)
@Getter @Setter
private long startTime;
@Column(name = "create_time", dataType = Column.ValueDataType.BIGINT)
@Getter @Setter
private long createTime;
@Column(name = "duration", dataType = Column.ValueDataType.INT)
@Getter @Setter
private int duration;
@Column(name = "min_duration_threshold", dataType = Column.ValueDataType.INT)
@Getter @Setter
private int minDurationThreshold;
@Column(name = "dump_period", dataType = Column.ValueDataType.INT)
@Getter @Setter
private int dumpPeriod;
@Column(name = "max_sampling_count", dataType = Column.ValueDataType.INT)
@Getter @Setter
private int maxSamplingCount;
@Override
public StorageID id();
public static class Builder implements StorageBuilder<ProfileTaskRecord> {
@Override
public ProfileTaskRecord storage2Entity(Convert2Entity converter);
@Override
public void entity2Storage(ProfileTaskRecord storageData, Convert2Storage converter);
}
}Storage record for thread profiling snapshots.
public class ProfileThreadSnapshotRecord extends Record {
@Column(name = "task_id", dataType = Column.ValueDataType.VARCHAR, length = 255)
@Getter @Setter
private String taskId;
@Column(name = "segment_id", dataType = Column.ValueDataType.VARCHAR, length = 255)
@Getter @Setter
private String segmentId;
@Column(name = "dump_time", dataType = Column.ValueDataType.BIGINT)
@Getter @Setter
private long dumpTime;
@Column(name = "sequence", dataType = Column.ValueDataType.INT)
@Getter @Setter
private int sequence;
@Column(name = "stack_binary", dataType = Column.ValueDataType.SAMPLED_RECORD)
@Getter @Setter
private byte[] stackBinary;
@Override
public StorageID id();
/**
* Deserializes stack trace from binary data
* @return Thread stack trace
* @throws IOException If deserialization fails
*/
public ThreadStack deserializeStack() throws IOException;
/**
* Serializes stack trace to binary data
* @param stack Thread stack trace to serialize
* @throws IOException If serialization fails
*/
public void serializeStack(ThreadStack stack) throws IOException;
public static class Builder implements StorageBuilder<ProfileThreadSnapshotRecord> {
@Override
public ProfileThreadSnapshotRecord storage2Entity(Convert2Entity converter);
@Override
public void entity2Storage(ProfileThreadSnapshotRecord storageData, Convert2Storage converter);
}
}Request parameters for creating new profiling tasks.
public class ProfileTaskCreationRequest {
private String serviceId;
private List<String> endpointNames;
private int duration;
private int minDurationThreshold;
private int dumpPeriod;
private int maxSamplingCount;
private String requestId;
/**
* Gets service identifier for profiling
* @return Service ID
*/
public String getServiceId();
/**
* Sets service identifier for profiling
* @param serviceId Service ID
*/
public void setServiceId(String serviceId);
/**
* Gets endpoint names to profile
* @return List of endpoint names
*/
public List<String> getEndpointNames();
/**
* Sets endpoint names to profile
* @param endpointNames List of endpoint names
*/
public void setEndpointNames(List<String> endpointNames);
/**
* Gets profiling duration in minutes
* @return Duration in minutes
*/
public int getDuration();
/**
* Sets profiling duration in minutes
* @param duration Duration in minutes (max 10 minutes)
*/
public void setDuration(int duration);
/**
* Gets minimum trace duration threshold for profiling
* @return Minimum duration in milliseconds
*/
public int getMinDurationThreshold();
/**
* Sets minimum trace duration threshold for profiling
* @param minDurationThreshold Minimum duration in milliseconds
*/
public void setMinDurationThreshold(int minDurationThreshold);
/**
* Gets thread dump period interval
* @return Dump period in milliseconds
*/
public int getDumpPeriod();
/**
* Sets thread dump period interval
* @param dumpPeriod Dump period in milliseconds (default 10ms)
*/
public void setDumpPeriod(int dumpPeriod);
/**
* Gets maximum sampling count per endpoint
* @return Maximum sampling count
*/
public int getMaxSamplingCount();
/**
* Sets maximum sampling count per endpoint
* @param maxSamplingCount Maximum sampling count (default 5)
*/
public void setMaxSamplingCount(int maxSamplingCount);
/**
* Gets unique request identifier
* @return Request ID
*/
public String getRequestId();
/**
* Sets unique request identifier
* @param requestId Request ID for tracking
*/
public void setRequestId(String requestId);
}Request parameters for updating existing profiling tasks.
public class ProfileTaskUpdateRequest {
private Integer duration;
private Integer minDurationThreshold;
private Integer maxSamplingCount;
/**
* Gets updated duration (null if no change)
* @return Duration in minutes or null
*/
public Integer getDuration();
/**
* Sets updated duration
* @param duration Duration in minutes
*/
public void setDuration(Integer duration);
/**
* Gets updated minimum duration threshold (null if no change)
* @return Minimum duration in milliseconds or null
*/
public Integer getMinDurationThreshold();
/**
* Sets updated minimum duration threshold
* @param minDurationThreshold Minimum duration in milliseconds
*/
public void setMinDurationThreshold(Integer minDurationThreshold);
/**
* Gets updated maximum sampling count (null if no change)
* @return Maximum sampling count or null
*/
public Integer getMaxSamplingCount();
/**
* Sets updated maximum sampling count
* @param maxSamplingCount Maximum sampling count
*/
public void setMaxSamplingCount(Integer maxSamplingCount);
}Complete profiling task information with status and results.
public class ProfileTask {
private String taskId;
private String serviceId;
private String serviceName;
private List<String> endpointNames;
private long createTime;
private long startTime;
private int duration;
private int minDurationThreshold;
private int dumpPeriod;
private int maxSamplingCount;
private ProfileTaskStatus status;
private String errorReason;
private List<ProfileTaskLog> logs;
/**
* Gets task identifier
* @return Task ID
*/
public String getTaskId();
/**
* Gets service identifier
* @return Service ID
*/
public String getServiceId();
/**
* Gets service name
* @return Service name
*/
public String getServiceName();
/**
* Gets profiled endpoint names
* @return List of endpoint names
*/
public List<String> getEndpointNames();
/**
* Gets task creation timestamp
* @return Creation time in milliseconds
*/
public long getCreateTime();
/**
* Gets task start timestamp
* @return Start time in milliseconds
*/
public long getStartTime();
/**
* Gets profiling duration
* @return Duration in minutes
*/
public int getDuration();
/**
* Gets task status
* @return Current task status
*/
public ProfileTaskStatus getStatus();
/**
* Gets error reason if task failed
* @return Error message or null if successful
*/
public String getErrorReason();
/**
* Gets task execution logs
* @return List of task logs
*/
public List<ProfileTaskLog> getLogs();
/**
* Checks if task is currently active
* @return True if task is running
*/
public boolean isActive();
/**
* Checks if task completed successfully
* @return True if task finished without errors
*/
public boolean isCompleted();
/**
* Gets estimated completion time
* @return Estimated completion timestamp or -1 if not applicable
*/
public long getEstimatedCompletionTime();
}Profiled trace segment with thread snapshots and analysis.
public class ProfiledSegment {
private String segmentId;
private String traceId;
private List<String> endpointNames;
private int duration;
private long startTime;
private long endTime;
private List<ThreadSnapshot> snapshots;
private ProfileAnalysis analysis;
/**
* Gets trace segment identifier
* @return Segment ID
*/
public String getSegmentId();
/**
* Gets trace identifier
* @return Trace ID
*/
public String getTraceId();
/**
* Gets endpoint names in segment
* @return List of endpoint names
*/
public List<String> getEndpointNames();
/**
* Gets segment duration
* @return Duration in milliseconds
*/
public int getDuration();
/**
* Gets segment start time
* @return Start timestamp in milliseconds
*/
public long getStartTime();
/**
* Gets segment end time
* @return End timestamp in milliseconds
*/
public long getEndTime();
/**
* Gets thread snapshots for this segment
* @return List of thread snapshots
*/
public List<ThreadSnapshot> getSnapshots();
/**
* Gets profiling analysis results
* @return Profile analysis or null if not analyzed
*/
public ProfileAnalysis getAnalysis();
/**
* Gets snapshot count
* @return Number of thread snapshots
*/
public int getSnapshotCount();
}Individual thread stack snapshot at specific time point.
public class ThreadSnapshot {
private String taskId;
private String segmentId;
private long dumpTime;
private int sequence;
private ThreadStack stack;
/**
* Gets profiling task identifier
* @return Task ID
*/
public String getTaskId();
/**
* Gets trace segment identifier
* @return Segment ID
*/
public String getSegmentId();
/**
* Gets snapshot dump time
* @return Dump timestamp in milliseconds
*/
public long getDumpTime();
/**
* Gets snapshot sequence number within segment
* @return Sequence number
*/
public int getSequence();
/**
* Gets thread stack trace
* @return Thread stack information
*/
public ThreadStack getStack();
/**
* Sets thread stack trace
* @param stack Thread stack information
*/
public void setStack(ThreadStack stack);
}Thread stack trace information with method call hierarchy.
public class ThreadStack {
private String threadName;
private String threadId;
private List<StackElement> elements;
/**
* Gets thread name
* @return Thread name
*/
public String getThreadName();
/**
* Sets thread name
* @param threadName Thread name
*/
public void setThreadName(String threadName);
/**
* Gets thread identifier
* @return Thread ID
*/
public String getThreadId();
/**
* Sets thread identifier
* @param threadId Thread ID
*/
public void setThreadId(String threadId);
/**
* Gets stack trace elements
* @return List of stack elements (bottom to top)
*/
public List<StackElement> getElements();
/**
* Sets stack trace elements
* @param elements List of stack elements
*/
public void setElements(List<StackElement> elements);
/**
* Gets stack depth
* @return Number of stack elements
*/
public int getDepth();
/**
* Gets top stack element (current method)
* @return Top stack element or null if empty
*/
public StackElement getTopElement();
}Individual method call in thread stack trace.
public class StackElement {
private String className;
private String methodName;
private String fileName;
private int lineNumber;
/**
* Gets class name
* @return Fully qualified class name
*/
public String getClassName();
/**
* Sets class name
* @param className Fully qualified class name
*/
public void setClassName(String className);
/**
* Gets method name
* @return Method name
*/
public String getMethodName();
/**
* Sets method name
* @param methodName Method name
*/
public void setMethodName(String methodName);
/**
* Gets source file name
* @return File name or null if unknown
*/
public String getFileName();
/**
* Sets source file name
* @param fileName File name
*/
public void setFileName(String fileName);
/**
* Gets line number in source file
* @return Line number or -1 if unknown
*/
public int getLineNumber();
/**
* Sets line number in source file
* @param lineNumber Line number
*/
public void setLineNumber(int lineNumber);
/**
* Gets formatted stack element string
* @return Formatted string like "className.methodName(fileName:lineNumber)"
*/
public String getFormattedString();
}Analysis results of profiling data with performance metrics.
public class ProfileAnalysis {
private String segmentId;
private List<ProfileNode> tree;
private Map<String, MethodStats> methodStats;
private long totalDuration;
private int totalSamples;
/**
* Gets analyzed segment identifier
* @return Segment ID
*/
public String getSegmentId();
/**
* Gets profiling tree structure
* @return List of root profile nodes
*/
public List<ProfileNode> getTree();
/**
* Gets method statistics
* @return Map of method name to statistics
*/
public Map<String, MethodStats> getMethodStats();
/**
* Gets total analysis duration
* @return Total duration in milliseconds
*/
public long getTotalDuration();
/**
* Gets total sample count
* @return Total number of samples analyzed
*/
public int getTotalSamples();
/**
* Gets top CPU consuming methods
* @param limit Maximum number of methods to return
* @return List of top methods by CPU usage
*/
public List<MethodStats> getTopCpuMethods(int limit);
/**
* Gets method call tree depth
* @return Maximum depth of call tree
*/
public int getMaxDepth();
}Node in profiling analysis tree representing method call hierarchy.
public class ProfileNode {
private String methodName;
private String className;
private long inclusiveTime;
private long exclusiveTime;
private int sampleCount;
private double cpuPercentage;
private List<ProfileNode> children;
private ProfileNode parent;
/**
* Gets method name
* @return Method name
*/
public String getMethodName();
/**
* Gets class name
* @return Class name
*/
public String getClassName();
/**
* Gets inclusive time (including child calls)
* @return Inclusive time in milliseconds
*/
public long getInclusiveTime();
/**
* Gets exclusive time (excluding child calls)
* @return Exclusive time in milliseconds
*/
public long getExclusiveTime();
/**
* Gets sample count for this method
* @return Number of samples
*/
public int getSampleCount();
/**
* Gets CPU percentage relative to total
* @return CPU usage percentage (0-100)
*/
public double getCpuPercentage();
/**
* Gets child method calls
* @return List of child profile nodes
*/
public List<ProfileNode> getChildren();
/**
* Gets parent method call
* @return Parent profile node or null if root
*/
public ProfileNode getParent();
/**
* Adds child method call
* @param child Child profile node to add
*/
public void addChild(ProfileNode child);
/**
* Gets full method signature
* @return "className.methodName" format
*/
public String getFullMethodName();
}Statistical information about method performance.
public class MethodStats {
private String methodName;
private String className;
private long totalInclusiveTime;
private long totalExclusiveTime;
private int callCount;
private long avgInclusiveTime;
private long avgExclusiveTime;
private long maxInclusiveTime;
private long minInclusiveTime;
private double cpuPercentage;
/**
* Gets method name
* @return Method name
*/
public String getMethodName();
/**
* Gets class name
* @return Class name
*/
public String getClassName();
/**
* Gets total inclusive time across all calls
* @return Total inclusive time in milliseconds
*/
public long getTotalInclusiveTime();
/**
* Gets total exclusive time across all calls
* @return Total exclusive time in milliseconds
*/
public long getTotalExclusiveTime();
/**
* Gets total number of method calls
* @return Call count
*/
public int getCallCount();
/**
* Gets average inclusive time per call
* @return Average inclusive time in milliseconds
*/
public long getAvgInclusiveTime();
/**
* Gets average exclusive time per call
* @return Average exclusive time in milliseconds
*/
public long getAvgExclusiveTime();
/**
* Gets maximum inclusive time for single call
* @return Maximum inclusive time in milliseconds
*/
public long getMaxInclusiveTime();
/**
* Gets minimum inclusive time for single call
* @return Minimum inclusive time in milliseconds
*/
public long getMinInclusiveTime();
/**
* Gets CPU usage percentage
* @return CPU percentage (0-100)
*/
public double getCpuPercentage();
/**
* Gets full method name
* @return "className.methodName" format
*/
public String getFullMethodName();
}// Get profiling mutation service
ProfileTaskMutationService profilingService = moduleDefineHolder.find(CoreModule.NAME)
.provider().getService(ProfileTaskMutationService.class);
// Create profiling task request
ProfileTaskCreationRequest request = new ProfileTaskCreationRequest();
request.setServiceId("user-service-id");
request.setEndpointNames(Arrays.asList("/api/users", "/api/users/{id}"));
request.setDuration(5); // 5 minutes
request.setMinDurationThreshold(100); // 100ms minimum
request.setDumpPeriod(10); // 10ms dump interval
request.setMaxSamplingCount(5); // 5 samples per endpoint
request.setRequestId(UUID.randomUUID().toString());
// Validate request before creation
ProfileTaskValidationResult validation = profilingService.validateTaskRequest(request);
if (!validation.isValid()) {
System.out.println("Invalid request: " + validation.getErrorMessages());
return;
}
// Create profiling task
ProfileTaskCreationResult result = profilingService.createTask(request);
if (result.isSuccessful()) {
System.out.println("Created profiling task: " + result.getTaskId());
} else {
System.out.println("Failed to create task: " + result.getErrorReason());
}// Get profiling query service
ProfileTaskQueryService queryService = moduleDefineHolder.find(CoreModule.NAME)
.provider().getService(ProfileTaskQueryService.class);
// Query profiling tasks
long startTime = System.currentTimeMillis() - TimeUnit.HOURS.toMillis(24);
long endTime = System.currentTimeMillis();
Pagination paging = new Pagination();
paging.setPageNum(1);
paging.setPageSize(20);
ProfileTaskList taskList = queryService.getTaskList(
"user-service-id",
null, // all endpoints
TimeBucket.getMinuteTimeBucket(startTime),
TimeBucket.getMinuteTimeBucket(endTime),
paging
);
System.out.println("Found " + taskList.getTasks().size() + " profiling tasks");
// Get detailed task information
for (ProfileTask task : taskList.getTasks()) {
System.out.println("Task " + task.getTaskId() + ":");
System.out.println(" Status: " + task.getStatus());
System.out.println(" Duration: " + task.getDuration() + " minutes");
System.out.println(" Endpoints: " + task.getEndpointNames());
if (task.getStatus() == ProfileTaskStatus.FINISHED) {
// Query profiled segments for completed task
List<ProfiledSegment> segments = queryService.getProfiledSegments(
task.getTaskId(),
null, // all segments
paging
);
System.out.println(" Found " + segments.size() + " profiled segments");
// Analyze each segment
for (ProfiledSegment segment : segments) {
analyzeProfiledSegment(segment, queryService);
}
}
}private void analyzeProfiledSegment(ProfiledSegment segment, ProfileTaskQueryService queryService)
throws IOException {
System.out.println("Analyzing segment " + segment.getSegmentId() + ":");
System.out.println(" Trace ID: " + segment.getTraceId());
System.out.println(" Duration: " + segment.getDuration() + "ms");
System.out.println(" Snapshots: " + segment.getSnapshotCount());
// Get thread snapshots
List<ThreadSnapshot> snapshots = queryService.getThreadSnapshots(
segment.getSegmentId(),
null, // all threads
segment.getStartTime(),
segment.getEndTime()
);
// Analyze thread snapshots
Map<String, List<ThreadSnapshot>> snapshotsByThread = snapshots.stream()
.collect(Collectors.groupingBy(s -> s.getStack().getThreadId()));
for (Map.Entry<String, List<ThreadSnapshot>> entry : snapshotsByThread.entrySet()) {
String threadId = entry.getKey();
List<ThreadSnapshot> threadSnapshots = entry.getValue();
System.out.println(" Thread " + threadId + ":");
System.out.println(" Snapshots: " + threadSnapshots.size());
// Analyze method calls
Map<String, Integer> methodCounts = new HashMap<>();
for (ThreadSnapshot snapshot : threadSnapshots) {
ThreadStack stack = snapshot.getStack();
for (StackElement element : stack.getElements()) {
String methodKey = element.getClassName() + "." + element.getMethodName();
methodCounts.merge(methodKey, 1, Integer::sum);
}
}
// Show top methods by frequency
methodCounts.entrySet().stream()
.sorted(Map.Entry.<String, Integer>comparingByValue().reversed())
.limit(10)
.forEach(e -> System.out.println(" " + e.getKey() + ": " + e.getValue() + " samples"));
}
// Generate profiling analysis if needed
if (segment.getAnalysis() == null) {
List<ProfileAnalyzeTimeRange> timeRanges = Arrays.asList(
new ProfileAnalyzeTimeRange(segment.getStartTime(), segment.getEndTime())
);
ProfileAnalyzeTimeRange analysis = queryService.getProfileAnalyzeTimeRange(
segment.getSegmentId(),
timeRanges
);
if (analysis != null) {
displayProfileAnalysis(analysis);
}
}
}
private void displayProfileAnalysis(ProfileAnalyzeTimeRange analysis) {
System.out.println("Profile Analysis:");
System.out.println(" Total samples: " + analysis.getTotalSamples());
System.out.println(" Duration: " + analysis.getTotalDuration() + "ms");
// Display method statistics
Map<String, MethodStats> methodStats = analysis.getMethodStats();
if (methodStats != null && !methodStats.isEmpty()) {
System.out.println(" Top CPU consuming methods:");
methodStats.values().stream()
.sorted(Comparator.comparingDouble(MethodStats::getCpuPercentage).reversed())
.limit(10)
.forEach(stats -> {
System.out.printf(" %s: %.2f%% CPU, %d calls, avg %.2fms%n",
stats.getFullMethodName(),
stats.getCpuPercentage(),
stats.getCallCount(),
stats.getAvgExclusiveTime() / 1000.0);
});
}
// Display call tree
List<ProfileNode> tree = analysis.getTree();
if (tree != null && !tree.isEmpty()) {
System.out.println(" Call tree:");
for (ProfileNode root : tree) {
displayProfileNode(root, 0);
}
}
}
private void displayProfileNode(ProfileNode node, int depth) {
String indent = " " + " ".repeat(depth);
System.out.printf("%s%s: %.2f%% CPU, %dms exclusive, %d samples%n",
indent,
node.getFullMethodName(),
node.getCpuPercentage(),
node.getExclusiveTime(),
node.getSampleCount());
// Recursively display children (limit depth to avoid too much output)
if (depth < 5) {
for (ProfileNode child : node.getChildren()) {
displayProfileNode(child, depth + 1);
}
}
}// Update profiling task
ProfileTaskUpdateRequest updateRequest = new ProfileTaskUpdateRequest();
updateRequest.setMaxSamplingCount(10); // Increase sampling count
updateRequest.setMinDurationThreshold(50); // Lower threshold
ProfileTaskUpdateResult updateResult = profilingService.updateTask(taskId, updateRequest);
if (updateResult.isSuccessful()) {
System.out.println("Task updated successfully");
} else {
System.out.println("Failed to update task: " + updateResult.getErrorReason());
}
// Get task statistics
ProfileTaskStats stats = profilingService.getTaskStats(taskId);
System.out.println("Task Statistics:");
System.out.println(" Total segments profiled: " + stats.getTotalSegments());
System.out.println(" Total snapshots: " + stats.getTotalSnapshots());
System.out.println(" Average snapshots per segment: " + stats.getAvgSnapshotsPerSegment());
System.out.println(" Data size: " + stats.getDataSizeInBytes() + " bytes");
// Cancel running task if needed
if (task.isActive()) {
ProfileTaskCancellationResult cancelResult = profilingService.cancelTask(taskId);
if (cancelResult.isSuccessful()) {
System.out.println("Task cancelled successfully");
} else {
System.out.println("Failed to cancel task: " + cancelResult.getErrorReason());
}
}/**
* Profiling task status enumeration
*/
public enum ProfileTaskStatus {
PENDING, RUNNING, FINISHED, CANCELLED, ERROR
}
/**
* Profile analysis time range
*/
public class ProfileAnalyzeTimeRange {
private long startTime;
private long endTime;
private List<ProfileNode> tree;
private Map<String, MethodStats> methodStats;
private long totalDuration;
private int totalSamples;
public ProfileAnalyzeTimeRange(long startTime, long endTime);
public long getStartTime();
public long getEndTime();
public List<ProfileNode> getTree();
public Map<String, MethodStats> getMethodStats();
public long getTotalDuration();
public int getTotalSamples();
}
/**
* Profiling task creation result
*/
public class ProfileTaskCreationResult {
private boolean successful;
private String taskId;
private String errorReason;
public boolean isSuccessful();
public String getTaskId();
public String getErrorReason();
}
/**
* Profiling task validation result
*/
public class ProfileTaskValidationResult {
private boolean valid;
private List<String> errorMessages;
public boolean isValid();
public List<String> getErrorMessages();
}Install with Tessl CLI
npx tessl i tessl/maven-org-apache-skywalking--server-core