All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.ideaaedi.commonds.monitor.WatchTimeUtil Maven / Gradle / Ivy

The newest version!
package com.ideaaedi.commonds.monitor;

import com.alibaba.fastjson2.JSON;
import org.apache.commons.lang3.StringUtils;

import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Function;


/**
 * 耗时统计工具
 *
 * @author JustryDeng 
 * @since 2100.10.7.LTS17
 */
public final class WatchTimeUtil {
    
    /** 初始化标识 */
    private static final ThreadLocal initThreadLocal = ThreadLocal.withInitial(() -> false);
    
    /** 存放执行中任务的ThreadLocal */
    private static final ThreadLocal> runningTaskThreadLocal = new ThreadLocal<>();
    
    /** 存放已结束任务的ThreadLocal */
    private static final ThreadLocal> endTaskThreadLocal = new ThreadLocal<>();
    
    /** 存放最大序号的ThreadLocal */
    private static final ThreadLocal maxTaskNoThreadLocal = new ThreadLocal<>();
    
    /**
     * 开始统计
     * 
     * 若计时器尚未初始化,则会静默忽略当前操作
     * 
* * @param taskName 任务名 */ public static void start(String taskName) { if (!initThreadLocal.get()) { return; } TaskInfo taskInfo = new TaskInfo(); String no = Manager.nextNo(); taskInfo.setTaskNo(no); taskInfo.setTaskName(taskName); taskInfo.setStartTime(System.nanoTime()); runningTaskThreadLocal.get().addFirst(taskInfo); maxTaskNoThreadLocal.set(no); } /** * 结束统计 *
     * 若计时器尚未初始化,则会静默忽略当前操作
     * 
*/ public static void stop() { if (!initThreadLocal.get()) { return; } LinkedList runningTaskDeque = runningTaskThreadLocal.get(); if (runningTaskDeque.size() == 0) { return; } TaskInfo taskInfo = runningTaskDeque.pollFirst(); taskInfo.setEndTime(System.nanoTime()); endTaskThreadLocal.get().addLast(taskInfo); } /** * 执行 * * @param taskName 任务名 * @param function 业务逻辑块 * @param param 参数 * * @return 逻辑执行结果 */ public static R watch(@Nonnull String taskName, Function function, P param) { try { start(taskName); return function.apply(param); } finally { stop(); } } /** * 执行 * * @param taskName 任务名 * @param function 业务逻辑块 * * @return 执行结果 */ public static R watch(@Nonnull String taskName, InnerNoArgFunction function) { try { start(taskName); return function.apply(); } finally { stop(); } } /** * 执行 * * @param taskName 任务名 * @param consumer 业务逻辑块 * @param param 参数 */ public static

void voidWatch(@Nonnull String taskName, Consumer

consumer, P param) { try { start(taskName); consumer.accept(param); } finally { stop(); } } /** * 执行 * * @param taskName 任务名 * @param consumer 业务逻辑块 */ public static void voidWatch(@Nonnull String taskName, InnerNoArgConsumer consumer) { try { start(taskName); consumer.accept(); } finally { stop(); } } /** * 耗时信息 */ public static String prettyResult() { if (!initThreadLocal.get()) { throw new IllegalStateException("Not initialized yet. You could do it by 'TimeWatchUtil.Manager.init()', " + "and don't forget to clear him last by 'TimeWatchUtil.Manager.clear()'"); } if (!Manager.currIsEnd()) { throw new IllegalStateException("There are also running tasks. " + Manager.getIngTaskList()); } List endTaskList = Manager.getEndTaskList(); return Manager.prettyResult(endTaskList); } /** * 耗时信息 */ public static String result() { if (!initThreadLocal.get()) { throw new IllegalStateException("Not initialized yet. You could do it by 'TimeWatchUtil.Manager.init()', " + "and don't forget to clear him last by 'TimeWatchUtil.Manager.clear()'"); } if (!Manager.currIsEnd()) { throw new IllegalStateException("There are also running tasks. " + Manager.getIngTaskList()); } List endTaskList = Manager.getEndTaskList(); return Manager.result(endTaskList); } /** * 管理器 */ public static class Manager { /** * 初始化 */ public static void init() { if (initThreadLocal.get()) { throw new IllegalStateException("It has already been initialized, please do not initialize it repeatedly."); } initThreadLocal.set(true); runningTaskThreadLocal.set(new LinkedList<>()); endTaskThreadLocal.set(new LinkedList<>()); } /** * 初始化 */ public static void initSilence() { if (initThreadLocal.get()) { return; } initThreadLocal.set(true); runningTaskThreadLocal.set(new LinkedList<>()); endTaskThreadLocal.set(new LinkedList<>()); } /** * 所有耗时统计任务当前是否都已结束 */ public static boolean currIsEnd() { LinkedList list = runningTaskThreadLocal.get(); return list == null || list.size() == 0; } /** * 获取已完成的任务集合 */ public static List getEndTaskList() { return new ArrayList<>(endTaskThreadLocal.get()); } /** * 获取进行中的任务集合 */ public static List getIngTaskList() { return new ArrayList<>(runningTaskThreadLocal.get()); } /** * 清空 */ public static void clear() { runningTaskThreadLocal.remove(); endTaskThreadLocal.remove(); maxTaskNoThreadLocal.remove(); initThreadLocal.remove(); } /** * 获取下一个执行序号 */ public static String nextNo() { TaskInfo taskInfo = runningTaskThreadLocal.get().peekFirst(); String maxNo = maxTaskNoThreadLocal.get(); String nextNo; if (taskInfo == null) { if (maxNo == null) { nextNo = "1"; } else { nextNo = String.valueOf(Long.parseLong(maxNo.split("\\.")[0]) + 1); } } else { Objects.requireNonNull(maxNo, "maxNo should not be null."); String parentNo = taskInfo.getTaskNo(); String[] parentNoArr = parentNo.split("\\."); String[] maxNoArr = maxNo.split("\\."); long subNo; if (maxNoArr.length > parentNoArr.length) { subNo = Long.parseLong(maxNoArr[parentNoArr.length]) + 1; } else { subNo = 1; } nextNo = parentNo + "." + subNo; } return nextNo; } /** * 按照任务序号排序 */ public static void sortByTaskNo(List taskInfoList) { if (taskInfoList == null) { return; } taskInfoList.sort( (x, y) -> { String xNo = x.getTaskNo(); String yNo = y.getTaskNo(); String[] xNoArr = xNo.split("\\."); String[] yNoArr = yNo.split("\\."); int minLength = Math.min(xNoArr.length, yNoArr.length); for (int i = 0; i < minLength; i++) { long xVal = Long.parseLong(xNoArr[i]); long yVal = Long.parseLong(yNoArr[i]); if (xVal < yVal) { return -1; } if (xVal > yVal) { return 1; } } return Integer.compare(xNoArr.length, yNoArr.length); } ); } /** * 耗时信息 */ public static String prettyResult(@Nonnull List endTaskList) { StringBuilder sb = new StringBuilder(); int size = endTaskList.size(); if (size == 0) { sb.append("no tasks time info."); return sb.toString(); } if (size == 1) { WatchTimeUtil.TaskInfo taskInfo = endTaskList.get(0); long consumeMilli = (taskInfo.getEndTime() - taskInfo.getStartTime()) / 1000000; return consumeMilli + "ms @ " + taskInfo.getTaskName(); } WatchTimeUtil.Manager.sortByTaskNo(endTaskList); WatchTimeUtil.TaskInfo preTask = null; for (WatchTimeUtil.TaskInfo taskInfo : endTaskList) { String taskNo = taskInfo.getTaskNo(); long startTime = taskInfo.getStartTime(); long endTime = taskInfo.getEndTime(); String[] noArr = taskNo.split("\\."); sb.append("\n"); sb.append(StringUtils.rightPad("|--".repeat(Math.max(0, noArr.length - 1)) + taskNo, 34, ".")); long consumeMilli = (endTime - startTime) / 1000000; // 计算和前一个任务的间隔 Long intervalMilli = null; if (preTask != null) { String preTaskNo = preTask.getTaskNo(); long preStartTime = preTask.getStartTime(); long preEndTime = preTask.getEndTime(); if (preTaskNo.length() > taskNo.length()) { // 前一任务是当前任务的子任务 intervalMilli = (endTime - preEndTime) / 1000000; } else if (taskNo.startsWith(preTaskNo)) { // 前一任务是当前任务的父任务 intervalMilli = (startTime - preStartTime) / 1000000; } else { // 同级任务 intervalMilli = (startTime - preEndTime) / 1000000; } } sb.append(StringUtils.leftPad(consumeMilli + "", 6, ".")) .append("ms"); // 两个任务之间的间隔时间 if (intervalMilli != null) { sb.append("(").append(StringUtils.leftPad(intervalMilli + "ms) @ ", 11, " ")); } else { sb.append(StringUtils.leftPad(" @ ", 12, " ")); } sb.append(taskInfo.getTaskName()); preTask = taskInfo; } return sb.toString(); } /** * 耗时信息 */ public static String result(@Nonnull List endTaskList) { int size = endTaskList.size(); if (size == 0) { return "no tasks time info."; } if (size == 1) { TaskInfo taskInfo = endTaskList.get(0); long consumeMilli = (taskInfo.getEndTime() - taskInfo.getStartTime()) / 1000000; return consumeMilli + "ms @ " + taskInfo.getTaskName(); } Manager.sortByTaskNo(endTaskList); List list = new ArrayList<>(); WatchTimeUtil.TaskInfo preTask = null; for (TaskInfo taskInfo : endTaskList) { StringBuilder sb = new StringBuilder(); String taskNo = taskInfo.getTaskNo(); long startTime = taskInfo.getStartTime(); long endTime = taskInfo.getEndTime(); sb.append("taskNo: "); sb.append(taskNo); sb.append(", "); long consumeMilli = (taskInfo.getEndTime() - taskInfo.getStartTime()) / 1000000; // 计算和前一个任务的间隔 Long intervalMilli = null; if (preTask != null) { String preTaskNo = preTask.getTaskNo(); long preStartTime = preTask.getStartTime(); long preEndTime = preTask.getEndTime(); if (preTaskNo.length() > taskNo.length()) { // 前一任务是当前任务的子任务 intervalMilli = (endTime - preEndTime) / 1000000; } else if (taskNo.startsWith(preTaskNo)) { // 前一任务是当前任务的父任务 intervalMilli = (startTime - preStartTime) / 1000000; } else { // 同级任务 intervalMilli = (startTime - preEndTime) / 1000000; } } sb.append("consumeTime: "); sb.append(consumeMilli).append("ms, "); if (intervalMilli != null) { sb.append("intervalTime: ").append(intervalMilli).append("ms, "); } sb.append("taskName: ") .append(taskInfo.getTaskName()); list.add(sb.toString()); preTask = taskInfo; } return JSON.toJSONString(list); } } /** * 任务信息 */ public static class TaskInfo { /** 执行序号(格式形如:xxx.xxx.xxx) */ private String taskNo; /** 任务名 */ private String taskName; /** 开始时间(纳秒) */ private long startTime; /** 结束时间(纳秒) */ private long endTime; public String getTaskNo() { return taskNo; } public void setTaskNo(String taskNo) { this.taskNo = taskNo; } public String getTaskName() { return taskName; } public void setTaskName(String taskName) { this.taskName = taskName; } public long getStartTime() { return startTime; } public void setStartTime(long startTime) { this.startTime = startTime; } public long getEndTime() { return endTime; } public void setEndTime(long endTime) { this.endTime = endTime; } @Override public String toString() { return "TaskInfo{" + "taskNo='" + taskNo + '\'' + ", taskName='" + taskName + '\'' + ", startTime=" + startTime + ", endTime=" + endTime + '}'; } } /** * (non-javadoc) */ @FunctionalInterface public interface InnerNoArgFunction { R apply(); } /** * (non-javadoc) */ @FunctionalInterface public interface InnerNoArgConsumer { void accept(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy