diff --git a/src/com/wenshuo/agent/log/ExecuteLogUtils.java b/src/com/wenshuo/agent/log/ExecuteLogUtils.java index ac2851f..a5633c6 100644 --- a/src/com/wenshuo/agent/log/ExecuteLogUtils.java +++ b/src/com/wenshuo/agent/log/ExecuteLogUtils.java @@ -20,7 +20,6 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicLong; import com.wenshuo.agent.AgentUtils; import com.wenshuo.agent.ConfigUtils; @@ -44,7 +43,7 @@ public class ExecuteLogUtils { private static ScheduledThreadPoolExecutor counterLogExecutor; - private static Map> executeCounterMap; + private static ConcurrentHashMap> executeCounterMap; private static final Object executeCounterLock = new Object(); @@ -82,7 +81,7 @@ public static synchronized void init() { } setNextDateStartTimeMillis(); initWriter(); - executeCounterMap = new ConcurrentHashMap>(); + executeCounterMap = new ConcurrentHashMap>(); startTimeMillis = System.currentTimeMillis(); counterLogExecutor = new ScheduledThreadPoolExecutor(1, new NamedThreadFactory("pool-thread-agent-log", true)); counterLogExecutor.scheduleWithFixedDelay(new OutputLogRunnable(), interval, interval, TimeUnit.SECONDS); @@ -99,26 +98,26 @@ public static void log(String className, String methodName, long executeTime) { * @author dingjsh * @time 2015-7-28下午01:35:25 */ - synchronized static void outputCounterLog() throws IOException { - Map> executeCounterMapInner = executeCounterMap; - executeCounterMap = new ConcurrentHashMap>(); + synchronized static void outputCounterLog() throws IOException { + ConcurrentHashMap> executeCounterMapInner = executeCounterMap; + executeCounterMap = new ConcurrentHashMap>(); String startTime = formatTimeMillis(startTimeMillis); String endTime = formatTimeMillis(System.currentTimeMillis()); long byteLength = removeJSONArrayEndBracket(); if (0 == byteLength) { - writeLog("[",true, startTimeMillis); + writeLog("[", true, startTimeMillis); } - Set>> entrySet = executeCounterMapInner.entrySet(); - Iterator>> ite = entrySet.iterator(); + Set>> entrySet = executeCounterMapInner.entrySet(); + Iterator>> ite = entrySet.iterator(); int length = entrySet.size(); if (length > 0 && byteLength > 10) { // 说明文件不只是[],json数组中已经有内容 writeLog(",", startTimeMillis); } for (int index = 0; ite.hasNext(); index++) { - Map.Entry> entry = ite.next(); + Map.Entry> entry = ite.next(); String className = entry.getKey(); - Map method2ExecuteMap = entry.getValue(); + Map method2ExecuteMap = entry.getValue(); String methodExecuteJson = MethodExecuteJSONformatter.getMethodExecuteJSON(className, method2ExecuteMap, startTime, endTime, isUsingNanoTime, logAvgExecuteTime); writeLog(methodExecuteJson, startTimeMillis); @@ -132,42 +131,35 @@ synchronized static void outputCounterLog() throws IOException { } private static void logExecuteCounter(String className, String methodName, long executeTime) { - Map methodCounterMap = getOrCreateClassExecutesMapping(className); - AtomicLong[] counter = methodCounterMap.get(methodName); + // dingjs modfied in 20210825 原来是用锁和Atomiclong来避免线程安全问题,现在去掉这些实现。原因是此处线程安全问题顶多导致 + // 数据有一些误差,这个误差对于agent数据监控并没有什么影响,牺牲一定的准确性带来性能的提升是有必要的 + ConcurrentHashMap methodCounterMap = getOrCreateClassExecutesMapping(className); + long[] counter = methodCounterMap.get(methodName); if (null == counter) { - synchronized (methodCounterMap) { - counter = methodCounterMap.get(methodName); - if (null == counter) { - methodCounterMap.put(methodName, new AtomicLong[] {new AtomicLong(1), new AtomicLong(executeTime)}); - } else { - counter[0].incrementAndGet(); - counter[1].addAndGet(executeTime); - } - } + methodCounterMap.put(methodName, new long[]{1, executeTime}); } else { - counter[0].incrementAndGet(); - counter[1].addAndGet(executeTime); + counter[0]++; + counter[1] = executeTime + counter[1]; } } /** - * * ExecuteLogUtils * - * @description 获得class和它的调用次数映射关系,如果exeuteCounterMap中没有,则创建一个并放入 * @param className 类名 * @return class和它的调用次数映射关系 + * @description 获得class和它的调用次数映射关系,如果exeuteCounterMap中没有,则创建一个并放入 * @author dingjsh * @date 2018年5月25日 下午4:40:33 * @version 1.2.0 */ - private static Map getOrCreateClassExecutesMapping(String className) { - Map methodCounterMap = executeCounterMap.get(className); + private static ConcurrentHashMap getOrCreateClassExecutesMapping(String className) { + ConcurrentHashMap methodCounterMap = executeCounterMap.get(className); if (null == methodCounterMap) { synchronized (executeCounterLock) { methodCounterMap = executeCounterMap.get(className); if (null == methodCounterMap) { - methodCounterMap = new ConcurrentHashMap(); + methodCounterMap = new ConcurrentHashMap(); executeCounterMap.put(className, methodCounterMap); } } diff --git a/src/com/wenshuo/agent/log/MethodExecuteJSONformatter.java b/src/com/wenshuo/agent/log/MethodExecuteJSONformatter.java index a886f08..13e1454 100644 --- a/src/com/wenshuo/agent/log/MethodExecuteJSONformatter.java +++ b/src/com/wenshuo/agent/log/MethodExecuteJSONformatter.java @@ -1,7 +1,7 @@ package com.wenshuo.agent.log; import java.util.Map; -import java.util.concurrent.atomic.AtomicLong; + /** * MethodExecuteJSONformatter @@ -17,7 +17,7 @@ class MethodExecuteJSONformatter { * MethodExecuteJSONformatter * * @param className 类名 - * @param method2ExecuteMap Map<方法名, AtomicLong[]> 数组第一个是执行次数,第二个是执行时间 + * @param method2ExecuteMap Map<方法名, Long[]> 数组第一个是执行次数,第二个是执行时间 * @param startTime 统计周期的开始时间,格式为 yyyy-MM-dd HH:mm:ss * @param endTime 统计周期的结束时间,格式为 yyyy-MM-dd HH:mm:ss * @return 格式化后的json string @@ -26,19 +26,19 @@ class MethodExecuteJSONformatter { * @date 2018年8月22日 下午8:49:18 * @version 2.0.0 */ - static String getMethodExecuteJSON(String className, Map method2ExecuteMap, + static String getMethodExecuteJSON(String className, Map method2ExecuteMap, String startTime, String endTime, boolean isUsingNanoTime, boolean logAvgExecuteTime) { StringBuilder json = new StringBuilder("{"); appendString(json, "class", className).append(","); appendString(json, "start", startTime).append(","); appendString(json, "end", endTime).append(","); appendKey(json, "methods").append("["); - for (Map.Entry methodEntry : method2ExecuteMap.entrySet()) { + for (Map.Entry methodEntry : method2ExecuteMap.entrySet()) { String methodName = methodEntry.getKey(); - AtomicLong[] executeCounter = methodEntry.getValue(); - long counter = executeCounter[0].longValue(); + long[] executeCounter = methodEntry.getValue(); + long counter = executeCounter[0]; long timeInMillis - = isUsingNanoTime ? executeCounter[1].longValue() / 1000000 : executeCounter[1].longValue(); + = isUsingNanoTime ? executeCounter[1] / 1000000 : executeCounter[1]; json.append("{"); appendString(json, "name", methodName).append(","); appendLong(json, "counter", counter).append(",");