From fcbdefa8feff91b6d1a31bde7b56c2467317f7e4 Mon Sep 17 00:00:00 2001 From: wenshao Date: Tue, 9 Oct 2012 10:52:29 +0800 Subject: [PATCH] profile support & add license info --- .../druid/support/http/WebStatFilter.java | 3 + .../druid/support/http/stat/WebURIStat.java | 4 - .../support/jconsole/DruidSqlDetailFrame.java | 15 +++ .../support/jconsole/model/ColumnGroup.java | 15 +++ .../model/DruidTableCellRenderer.java | 15 +++ .../jconsole/model/GroupableTableHeader.java | 15 +++ .../model/GroupableTableHeaderUI.java | 15 +++ .../druid/support/profile/ProfileEntry.java | 15 +++ .../support/profile/ProfileEntryKey.java | 16 +++- .../support/profile/ProfileEntryReqStat.java | 15 +++ .../support/profile/ProfileEntryStat.java | 15 +++ .../druid/support/profile/ProfileStat.java | 95 ++++++++++++++----- .../druid/support/profile/Profiler.java | 19 +++- .../support/http/resources/js/common.js | 4 + .../support/http/resources/weburi-detail.html | 85 +++++++++++++---- 15 files changed, 294 insertions(+), 52 deletions(-) diff --git a/src/main/java/com/alibaba/druid/support/http/WebStatFilter.java b/src/main/java/com/alibaba/druid/support/http/WebStatFilter.java index f594a7848f..f95525b5a0 100644 --- a/src/main/java/com/alibaba/druid/support/http/WebStatFilter.java +++ b/src/main/java/com/alibaba/druid/support/http/WebStatFilter.java @@ -122,6 +122,7 @@ public class WebStatFilter implements Filter { if (isProfileEnable()) { Profiler.initLocal(); + Profiler.enter(requestURI, Profiler.PROFILE_TYPE_WEB); } // 第一次访问时,uriStat这里为null,是为了防止404攻击。 @@ -189,6 +190,8 @@ public class WebStatFilter implements Filter { WebRequestStat.set(null); if (isProfileEnable()) { + Profiler.release(nanos); + Map requestStatsMap = Profiler.getStatsMap(); uriStat.getProfiletat().record(requestStatsMap); Profiler.removeLocal(); diff --git a/src/main/java/com/alibaba/druid/support/http/stat/WebURIStat.java b/src/main/java/com/alibaba/druid/support/http/stat/WebURIStat.java index c41b97b949..c07bab855f 100644 --- a/src/main/java/com/alibaba/druid/support/http/stat/WebURIStat.java +++ b/src/main/java/com/alibaba/druid/support/http/stat/WebURIStat.java @@ -143,8 +143,6 @@ public class WebURIStat { if (requestStat != null) { this.setLastAccessTimeMillis(requestStat.getStartMillis()); } - - Profiler.enter(uri, Profiler.PROFILE_TYPE_WEB); } public void afterInvoke(Throwable error, long nanos) { @@ -216,8 +214,6 @@ public class WebURIStat { } currentLocal.set(null); - - Profiler.release(nanos); } public int getRunningCount() { diff --git a/src/main/java/com/alibaba/druid/support/jconsole/DruidSqlDetailFrame.java b/src/main/java/com/alibaba/druid/support/jconsole/DruidSqlDetailFrame.java index 37f4ad4f82..fc8bbb075b 100644 --- a/src/main/java/com/alibaba/druid/support/jconsole/DruidSqlDetailFrame.java +++ b/src/main/java/com/alibaba/druid/support/jconsole/DruidSqlDetailFrame.java @@ -1,3 +1,18 @@ +/* + * Copyright 1999-2011 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.alibaba.druid.support.jconsole; import java.awt.BorderLayout; diff --git a/src/main/java/com/alibaba/druid/support/jconsole/model/ColumnGroup.java b/src/main/java/com/alibaba/druid/support/jconsole/model/ColumnGroup.java index efb70d517b..0e6b9c243b 100644 --- a/src/main/java/com/alibaba/druid/support/jconsole/model/ColumnGroup.java +++ b/src/main/java/com/alibaba/druid/support/jconsole/model/ColumnGroup.java @@ -1,3 +1,18 @@ +/* + * Copyright 1999-2011 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.alibaba.druid.support.jconsole.model; import java.awt.Component; diff --git a/src/main/java/com/alibaba/druid/support/jconsole/model/DruidTableCellRenderer.java b/src/main/java/com/alibaba/druid/support/jconsole/model/DruidTableCellRenderer.java index a55c2ca855..74902596ac 100644 --- a/src/main/java/com/alibaba/druid/support/jconsole/model/DruidTableCellRenderer.java +++ b/src/main/java/com/alibaba/druid/support/jconsole/model/DruidTableCellRenderer.java @@ -1,3 +1,18 @@ +/* + * Copyright 1999-2011 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.alibaba.druid.support.jconsole.model; import java.awt.Color; diff --git a/src/main/java/com/alibaba/druid/support/jconsole/model/GroupableTableHeader.java b/src/main/java/com/alibaba/druid/support/jconsole/model/GroupableTableHeader.java index b06e2fb105..a909e50f21 100644 --- a/src/main/java/com/alibaba/druid/support/jconsole/model/GroupableTableHeader.java +++ b/src/main/java/com/alibaba/druid/support/jconsole/model/GroupableTableHeader.java @@ -1,3 +1,18 @@ +/* + * Copyright 1999-2011 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.alibaba.druid.support.jconsole.model; import java.util.Enumeration; diff --git a/src/main/java/com/alibaba/druid/support/jconsole/model/GroupableTableHeaderUI.java b/src/main/java/com/alibaba/druid/support/jconsole/model/GroupableTableHeaderUI.java index d98337d9b0..5e5e6a8560 100644 --- a/src/main/java/com/alibaba/druid/support/jconsole/model/GroupableTableHeaderUI.java +++ b/src/main/java/com/alibaba/druid/support/jconsole/model/GroupableTableHeaderUI.java @@ -1,3 +1,18 @@ +/* + * Copyright 1999-2011 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.alibaba.druid.support.jconsole.model; import java.awt.Component; diff --git a/src/main/java/com/alibaba/druid/support/profile/ProfileEntry.java b/src/main/java/com/alibaba/druid/support/profile/ProfileEntry.java index 0eb3c83297..7331f34678 100644 --- a/src/main/java/com/alibaba/druid/support/profile/ProfileEntry.java +++ b/src/main/java/com/alibaba/druid/support/profile/ProfileEntry.java @@ -1,3 +1,18 @@ +/* + * Copyright 1999-2011 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.alibaba.druid.support.profile; public class ProfileEntry { diff --git a/src/main/java/com/alibaba/druid/support/profile/ProfileEntryKey.java b/src/main/java/com/alibaba/druid/support/profile/ProfileEntryKey.java index e8469acd13..cb3ee8db03 100644 --- a/src/main/java/com/alibaba/druid/support/profile/ProfileEntryKey.java +++ b/src/main/java/com/alibaba/druid/support/profile/ProfileEntryKey.java @@ -1,7 +1,21 @@ +/* + * Copyright 1999-2011 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.alibaba.druid.support.profile; public class ProfileEntryKey { - private final String parentName; private final String name; private final String type; diff --git a/src/main/java/com/alibaba/druid/support/profile/ProfileEntryReqStat.java b/src/main/java/com/alibaba/druid/support/profile/ProfileEntryReqStat.java index cd711dbaae..a600afa745 100644 --- a/src/main/java/com/alibaba/druid/support/profile/ProfileEntryReqStat.java +++ b/src/main/java/com/alibaba/druid/support/profile/ProfileEntryReqStat.java @@ -1,3 +1,18 @@ +/* + * Copyright 1999-2011 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.alibaba.druid.support.profile; public class ProfileEntryReqStat { diff --git a/src/main/java/com/alibaba/druid/support/profile/ProfileEntryStat.java b/src/main/java/com/alibaba/druid/support/profile/ProfileEntryStat.java index 657132ddd7..393444be92 100644 --- a/src/main/java/com/alibaba/druid/support/profile/ProfileEntryStat.java +++ b/src/main/java/com/alibaba/druid/support/profile/ProfileEntryStat.java @@ -1,3 +1,18 @@ +/* + * Copyright 1999-2011 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.alibaba.druid.support.profile; import java.util.concurrent.atomic.AtomicLongFieldUpdater; diff --git a/src/main/java/com/alibaba/druid/support/profile/ProfileStat.java b/src/main/java/com/alibaba/druid/support/profile/ProfileStat.java index e99b9f90c2..2f8fdda339 100644 --- a/src/main/java/com/alibaba/druid/support/profile/ProfileStat.java +++ b/src/main/java/com/alibaba/druid/support/profile/ProfileStat.java @@ -1,14 +1,33 @@ +/* + * Copyright 1999-2011 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.alibaba.druid.support.profile; +import java.util.ArrayList; +import java.util.Collections; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; public class ProfileStat { - private ConcurrentHashMap entries = new ConcurrentHashMap( - 4, - 0.75f, - 1); + + private Map entries = new LinkedHashMap(4); + + private ReadWriteLock lock = new ReentrantReadWriteLock(); public Map getEntries() { return entries; @@ -23,35 +42,61 @@ public class ProfileStat { ProfileEntryKey entryKey = entry.getKey(); ProfileEntryReqStat reqEntryStat = entry.getValue(); - ProfileEntryStat entryStat = entries.get(entryKey); - if (entryStat == null) { - entries.putIfAbsent(entryKey, new ProfileEntryStat()); - entryStat = entries.get(entryKey); - } + ProfileEntryStat entryStat = getProfileEntry(entryKey); entryStat.addExecuteCount(reqEntryStat.getExecuteCount()); entryStat.addExecuteTimeNanos(reqEntryStat.getExecuteTimeNanos()); } } - public Map, Map> getStatData() { - Map, Map> data = new LinkedHashMap, Map>(); + private ProfileEntryStat getProfileEntry(ProfileEntryKey entryKey) { - for (Map.Entry entry : entries.entrySet()) { - Map key = new LinkedHashMap(); - Map value = new LinkedHashMap(); - - key.put("Parent", entry.getKey().getParentName()); - key.put("Name", entry.getKey().getName()); - key.put("Type", entry.getKey().getType()); - - value.put("ExecuteCount", entry.getValue().getExecuteCount()); - value.put("ExecuteTimeNanos", entry.getValue().getExecuteTimeNanos()); - - data.put(key, value); + lock.readLock().lock(); + try { + ProfileEntryStat entryStat = entries.get(entryKey); + if (entryStat != null) { + return entryStat; + } + } finally { + lock.readLock().unlock(); } - return data; + lock.writeLock().lock(); + try { + ProfileEntryStat entryStat = entries.get(entryKey); + if (entryStat == null) { + entries.put(entryKey, new ProfileEntryStat()); + entryStat = entries.get(entryKey); + } + return entryStat; + } finally { + lock.writeLock().unlock(); + } + } + + public List> getStatData() { + List> list = new ArrayList>(); + + lock.readLock().lock(); + try { + for (Map.Entry entry : entries.entrySet()) { + Map entryData = new LinkedHashMap(); + + entryData.put("Name", entry.getKey().getName()); + entryData.put("Parent", entry.getKey().getParentName()); + entryData.put("Type", entry.getKey().getType()); + entryData.put("ExecuteCount", entry.getValue().getExecuteCount()); + entryData.put("ExecuteTimeMillis", entry.getValue().getExecuteTimeNanos() / 1000 / 1000); + + list.add(entryData); + } + } finally { + lock.readLock().unlock(); + } + + Collections.reverse(list); + + return list; } } diff --git a/src/main/java/com/alibaba/druid/support/profile/Profiler.java b/src/main/java/com/alibaba/druid/support/profile/Profiler.java index 37d2089e6f..5570697877 100644 --- a/src/main/java/com/alibaba/druid/support/profile/Profiler.java +++ b/src/main/java/com/alibaba/druid/support/profile/Profiler.java @@ -1,6 +1,21 @@ +/* + * Copyright 1999-2011 Alibaba Group Holding Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.alibaba.druid.support.profile; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; public class Profiler { @@ -64,7 +79,7 @@ public class Profiler { } public static void initLocal() { - statsMapLocal.set(new HashMap()); + statsMapLocal.set(new LinkedHashMap()); } public static void removeLocal() { diff --git a/src/main/resources/support/http/resources/js/common.js b/src/main/resources/support/http/resources/js/common.js index 6868de1c3a..6c47acc295 100644 --- a/src/main/resources/support/http/resources/js/common.js +++ b/src/main/resources/support/http/resources/js/common.js @@ -144,6 +144,10 @@ druid.common = function () { }, subSqlString : function(sql, len) { + if (sql == undefined || sql == null) { + return ''; + } + if (sql.length <= len) return sql; return sql.substr(0, len) + '...'; diff --git a/src/main/resources/support/http/resources/weburi-detail.html b/src/main/resources/support/http/resources/weburi-detail.html index 9f75f501bc..5b26ba6ef7 100644 --- a/src/main/resources/support/http/resources/weburi-detail.html +++ b/src/main/resources/support/http/resources/weburi-detail.html @@ -98,6 +98,21 @@ + +

Profiles

+ + + + + + + + + + + + +
NNameParentNameTypeExecuteCountExecuteTimeMillis
@@ -122,26 +137,56 @@ success: function(data) { if (data.Content == null) return; - $("#URI").text(data.Content.URI) - $("#RequestCount").text(data.Content.RequestCount) - $("#RequestTimeMillis").text(data.Content.RequestTimeMillis) - $("#LastAccessTime").text(data.Content.LastAccessTime) - $("#RunningCount").text(data.Content.RunningCount) - $("#ConcurrentMax").text(data.Content.ConcurrentMax) - $("#JdbcExecuteCount").text(data.Content.JdbcExecuteCount) - $("#JdbcExecuteErrorCount").text(data.Content.JdbcExecuteErrorCount) - $("#JdbcExecutePeak").text(data.Content.JdbcExecutePeak) - $("#JdbcExecuteTimeMillis").text(data.Content.JdbcExecuteTimeMillis) - $("#JdbcCommitCount").text(data.Content.JdbcCommitCount) - $("#JdbcRollbackCount").text(data.Content.JdbcRollbackCount) - $("#JdbcFetchRowCount").text(data.Content.JdbcFetchRowCount) - $("#JdbcFetchRowPeak").text(data.Content.JdbcFetchRowPeak) - $("#JdbcUpdateCount").text(data.Content.JdbcUpdateCount) - $("#JdbcUpdatePeak").text(data.Content.JdbcUpdatePeak) - $("#JdbcPoolConnectionOpenCount").text(data.Content.JdbcPoolConnectionOpenCount) - $("#JdbcPoolConnectionCloseCount").text(data.Content.JdbcPoolConnectionCloseCount) - $("#JdbcResultSetOpenCount").text(data.Content.JdbcResultSetOpenCount) - $("#JdbcResultSetCloseCount").text(data.Content.JdbcResultSetCloseCount) + $("#URI").text(data.Content.URI); + $("#RequestCount").text(data.Content.RequestCount); + $("#RequestTimeMillis").text(data.Content.RequestTimeMillis); + $("#LastAccessTime").text(data.Content.LastAccessTime); + $("#RunningCount").text(data.Content.RunningCount); + $("#ConcurrentMax").text(data.Content.ConcurrentMax); + $("#JdbcExecuteCount").text(data.Content.JdbcExecuteCount); + $("#JdbcExecuteErrorCount").text(data.Content.JdbcExecuteErrorCount); + $("#JdbcExecutePeak").text(data.Content.JdbcExecutePeak); + $("#JdbcExecuteTimeMillis").text(data.Content.JdbcExecuteTimeMillis); + $("#JdbcCommitCount").text(data.Content.JdbcCommitCount); + $("#JdbcRollbackCount").text(data.Content.JdbcRollbackCount); + $("#JdbcFetchRowCount").text(data.Content.JdbcFetchRowCount); + $("#JdbcFetchRowPeak").text(data.Content.JdbcFetchRowPeak); + $("#JdbcUpdateCount").text(data.Content.JdbcUpdateCount); + $("#JdbcUpdatePeak").text(data.Content.JdbcUpdatePeak); + $("#JdbcPoolConnectionOpenCount").text(data.Content.JdbcPoolConnectionOpenCount); + $("#JdbcPoolConnectionCloseCount").text(data.Content.JdbcPoolConnectionCloseCount); + $("#JdbcResultSetOpenCount").text(data.Content.JdbcResultSetOpenCount); + $("#JdbcResultSetCloseCount").text(data.Content.JdbcResultSetCloseCount); + + var profiles = data.Content.Profiles; + if (profiles == null) { + return; + } + + var profileDataTable = document.getElementById("profileDataTable"); + while (profileDataTable.rows.length > 1) { + profileDataTable.deleteRow(1); + } + + var html = ""; + for ( var i = 0; i < profiles.length; i++) { + var stat = profiles[i]; + var newRow = profileDataTable.insertRow(-1); + html += ""; + html += "" + (i + 1) + ""; + html += "" + stat.Name + ""; + if (stat.Parent == null) { + html += " "; + } else { + html += "" + stat.Parent + ""; + } + + html += "" + stat.Type + ""; + html += "" + stat.ExecuteCount + ""; + html += "" + stat.ExecuteTimeMillis + ""; + html += ""; + } + $("#profileDataTable tbody").html(html); }, dataType: "json" });