PageRenderTime 60ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 1ms

/src/main/java/com/alibaba/druid/support/http/stat/WebAppStat.java

https://github.com/wangyan9110/druid
Java | 1183 lines | 940 code | 222 blank | 21 comment | 264 complexity | 6a34b27453d15083f90edd40a622ed37 MD5 | raw file
Possible License(s): Apache-2.0
  1. /*
  2. * Copyright 1999-2011 Alibaba Group Holding Ltd.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package com.alibaba.druid.support.http.stat;
  17. import static com.alibaba.druid.util.JdbcSqlStatUtils.get;
  18. import java.util.ArrayList;
  19. import java.util.Iterator;
  20. import java.util.List;
  21. import java.util.Map;
  22. import java.util.concurrent.ConcurrentHashMap;
  23. import java.util.concurrent.ConcurrentMap;
  24. import java.util.concurrent.atomic.AtomicInteger;
  25. import java.util.concurrent.atomic.AtomicLong;
  26. import java.util.concurrent.locks.ReadWriteLock;
  27. import java.util.concurrent.locks.ReentrantReadWriteLock;
  28. import com.alibaba.druid.support.logging.Log;
  29. import com.alibaba.druid.support.logging.LogFactory;
  30. import com.alibaba.druid.util.LRUCache;
  31. import java.util.Collections;
  32. public class WebAppStat {
  33. private final static Log LOG = LogFactory.getLog(WebAppStat.class);
  34. public final static int DEFAULT_MAX_STAT_URI_COUNT = 1000;
  35. public final static int DEFAULT_MAX_STAT_SESSION_COUNT = 1000;
  36. private final static ThreadLocal<WebAppStat> currentLocal = new ThreadLocal<WebAppStat>();
  37. private volatile int maxStatUriCount = DEFAULT_MAX_STAT_URI_COUNT;
  38. private volatile int maxStatSessionCount = DEFAULT_MAX_STAT_SESSION_COUNT;
  39. private final AtomicInteger runningCount = new AtomicInteger();
  40. private final AtomicInteger concurrentMax = new AtomicInteger();
  41. private final AtomicLong requestCount = new AtomicLong(0);
  42. private final AtomicLong sessionCount = new AtomicLong(0);
  43. private final AtomicLong jdbcFetchRowCount = new AtomicLong();
  44. private final AtomicLong jdbcUpdateCount = new AtomicLong();
  45. private final AtomicLong jdbcExecuteCount = new AtomicLong();
  46. private final AtomicLong jdbcExecuteTimeNano = new AtomicLong();
  47. private final AtomicLong jdbcCommitCount = new AtomicLong();
  48. private final AtomicLong jdbcRollbackCount = new AtomicLong();
  49. private final ConcurrentMap<String, WebURIStat> uriStatMap = new ConcurrentHashMap<String, WebURIStat>(
  50. 16,
  51. 0.75f,
  52. 1);
  53. private final LRUCache<String, WebSessionStat> sessionStatMap;
  54. private final ReadWriteLock sessionStatLock = new ReentrantReadWriteLock();
  55. private final AtomicLong uriStatMapFullCount = new AtomicLong();
  56. private final AtomicLong uriSessionMapFullCount = new AtomicLong();
  57. private final AtomicLong osMacOSXCount = new AtomicLong(0);
  58. private final AtomicLong osWindowsCount = new AtomicLong(0);
  59. private final AtomicLong osLinuxCount = new AtomicLong(0);
  60. private final AtomicLong osSymbianCount = new AtomicLong(0);
  61. private final AtomicLong osFreeBSDCount = new AtomicLong(0);
  62. private final AtomicLong osOpenBSDCount = new AtomicLong(0);
  63. private final AtomicLong osAndroidCount = new AtomicLong(0);
  64. private final AtomicLong osWindows98Count = new AtomicLong();
  65. private final AtomicLong osWindowsXPCount = new AtomicLong();
  66. private final AtomicLong osWindows2000Count = new AtomicLong();
  67. private final AtomicLong osWindowsVistaCount = new AtomicLong();
  68. private final AtomicLong osWindows7Count = new AtomicLong();
  69. private final AtomicLong osWindows8Count = new AtomicLong();
  70. private final AtomicLong osAndroid15Count = new AtomicLong(0);
  71. private final AtomicLong osAndroid16Count = new AtomicLong(0);
  72. private final AtomicLong osAndroid20Count = new AtomicLong(0);
  73. private final AtomicLong osAndroid21Count = new AtomicLong(0);
  74. private final AtomicLong osAndroid22Count = new AtomicLong(0);
  75. private final AtomicLong osAndroid23Count = new AtomicLong(0);
  76. private final AtomicLong osAndroid30Count = new AtomicLong(0);
  77. private final AtomicLong osAndroid31Count = new AtomicLong(0);
  78. private final AtomicLong osAndroid32Count = new AtomicLong(0);
  79. private final AtomicLong osAndroid40Count = new AtomicLong(0);
  80. private final AtomicLong osAndroid41Count = new AtomicLong(0);
  81. private final AtomicLong osAndroid42Count = new AtomicLong(0);
  82. private final AtomicLong osAndroid43Count = new AtomicLong(0);
  83. private final AtomicLong osLinuxUbuntuCount = new AtomicLong(0);
  84. private final AtomicLong browserIECount = new AtomicLong(0);
  85. private final AtomicLong browserFirefoxCount = new AtomicLong(0);
  86. private final AtomicLong browserChromeCount = new AtomicLong(0);
  87. private final AtomicLong browserSafariCount = new AtomicLong(0);
  88. private final AtomicLong browserOperaCount = new AtomicLong(0);
  89. private final AtomicLong browserIE5Count = new AtomicLong(0);
  90. private final AtomicLong browserIE6Count = new AtomicLong(0);
  91. private final AtomicLong browserIE7Count = new AtomicLong(0);
  92. private final AtomicLong browserIE8Count = new AtomicLong(0);
  93. private final AtomicLong browserIE9Count = new AtomicLong(0);
  94. private final AtomicLong browserIE10Count = new AtomicLong(0);
  95. private final AtomicLong browser360SECount = new AtomicLong(0);
  96. private final AtomicLong deviceAndroidCount = new AtomicLong(0);
  97. private final AtomicLong deviceIpadCount = new AtomicLong(0);
  98. private final AtomicLong deviceIphoneCount = new AtomicLong(0);
  99. private final AtomicLong deviceWindowsPhoneCount = new AtomicLong(0);
  100. private final AtomicLong botCount = new AtomicLong();
  101. private final AtomicLong botBaiduCount = new AtomicLong();
  102. private final AtomicLong botYoudaoCount = new AtomicLong();
  103. private final AtomicLong botGoogleCount = new AtomicLong();
  104. private final AtomicLong botMsnCount = new AtomicLong();
  105. private final AtomicLong botBingCount = new AtomicLong();
  106. private final AtomicLong botSosoCount = new AtomicLong();
  107. private final AtomicLong botSogouCount = new AtomicLong();
  108. private final AtomicLong botYahooCount = new AtomicLong();
  109. private String contextPath;
  110. public static WebAppStat current() {
  111. return currentLocal.get();
  112. }
  113. public void reset() {
  114. concurrentMax.set(0);
  115. requestCount.set(0);
  116. requestCount.set(0);
  117. sessionCount.set(0);
  118. jdbcFetchRowCount.set(0);
  119. jdbcUpdateCount.set(0);
  120. jdbcExecuteCount.set(0);
  121. jdbcExecuteTimeNano.set(0);
  122. jdbcCommitCount.set(0);
  123. jdbcRollbackCount.set(0);
  124. sessionStatLock.readLock().lock();
  125. try {
  126. Iterator<Map.Entry<String, WebSessionStat>> iter = sessionStatMap.entrySet().iterator();
  127. while (iter.hasNext()) {
  128. Map.Entry<String, WebSessionStat> entry = iter.next();
  129. entry.getValue().reset();
  130. }
  131. sessionStatMap.clear();
  132. } finally {
  133. sessionStatLock.readLock().unlock();
  134. }
  135. uriStatMap.clear();
  136. uriStatMapFullCount.set(0);
  137. uriSessionMapFullCount.set(0);
  138. osMacOSXCount.set(0);
  139. osWindowsCount.set(0);
  140. osLinuxCount.set(0);
  141. osSymbianCount.set(0);
  142. osOpenBSDCount.set(0);
  143. osFreeBSDCount.set(0);
  144. osAndroidCount.set(0);
  145. osWindows98Count.set(0);
  146. osWindowsXPCount.set(0);
  147. osWindows2000Count.set(0);
  148. osWindowsVistaCount.set(0);
  149. osWindows7Count.set(0);
  150. osWindows8Count.set(0);
  151. osLinuxUbuntuCount.set(0);
  152. osAndroid15Count.set(0);
  153. osAndroid16Count.set(0);
  154. osAndroid20Count.set(0);
  155. osAndroid21Count.set(0);
  156. osAndroid22Count.set(0);
  157. osAndroid23Count.set(0);
  158. osAndroid30Count.set(0);
  159. osAndroid31Count.set(0);
  160. osAndroid32Count.set(0);
  161. osAndroid40Count.set(0);
  162. osAndroid41Count.set(0);
  163. osAndroid42Count.set(0);
  164. osAndroid43Count.set(0);
  165. browserIE6Count.set(0);
  166. browserIE7Count.set(0);
  167. browserIE8Count.set(0);
  168. browserIE9Count.set(0);
  169. browserIE10Count.set(0);
  170. browserIECount.set(0);
  171. browserFirefoxCount.set(0);
  172. browserChromeCount.set(0);
  173. browserSafariCount.set(0);
  174. browserOperaCount.set(0);
  175. browser360SECount.set(0);
  176. deviceAndroidCount.set(0);
  177. deviceIpadCount.set(0);
  178. deviceIphoneCount.set(0);
  179. deviceWindowsPhoneCount.set(0);
  180. }
  181. public WebAppStat(){
  182. this(null);
  183. }
  184. public WebAppStat(String contextPath){
  185. this(contextPath, DEFAULT_MAX_STAT_SESSION_COUNT);
  186. }
  187. public WebAppStat(String contextPath, int maxStatSessionCount){
  188. this.contextPath = contextPath;
  189. this.maxStatSessionCount = maxStatSessionCount;
  190. sessionStatMap = new LRUCache<String, WebSessionStat>(maxStatSessionCount);
  191. }
  192. public String getContextPath() {
  193. return contextPath;
  194. }
  195. public void beforeInvoke() {
  196. currentLocal.set(this);
  197. int running = runningCount.incrementAndGet();
  198. for (;;) {
  199. int max = concurrentMax.get();
  200. if (running > max) {
  201. if (concurrentMax.compareAndSet(max, running)) {
  202. break;
  203. } else {
  204. continue;
  205. }
  206. } else {
  207. break;
  208. }
  209. }
  210. requestCount.incrementAndGet();
  211. }
  212. public WebURIStat getURIStat(String uri) {
  213. return getURIStat(uri, false);
  214. }
  215. public WebURIStat getURIStat(String uri, boolean create) {
  216. WebURIStat uriStat = uriStatMap.get(uri);
  217. if (uriStat != null) {
  218. return uriStat;
  219. }
  220. if (!create) {
  221. return null;
  222. }
  223. if (uriStatMap.size() >= this.getMaxStatUriCount()) {
  224. long fullCount = uriStatMapFullCount.getAndIncrement();
  225. if (fullCount == 0) {
  226. LOG.error("uriSessionMapFullCount is full");
  227. }
  228. return null;
  229. }
  230. if (uriStat == null) {
  231. uriStatMap.putIfAbsent(uri, new WebURIStat(uri));
  232. uriStat = uriStatMap.get(uri);
  233. }
  234. return uriStat;
  235. }
  236. public WebSessionStat getSessionStat(String sessionId) {
  237. return getSessionStat(sessionId, false);
  238. }
  239. public Map<String, Object> getSessionStatData(String sessionId) {
  240. WebSessionStat sessionStat = sessionStatMap.get(sessionId);
  241. if (sessionStat == null) {
  242. return null;
  243. }
  244. return sessionStat.getStatData();
  245. }
  246. public Map<String, Object> getURIStatData(String uri) {
  247. WebURIStat uriStat = getURIStat(uri);
  248. if (uriStat == null) {
  249. return null;
  250. }
  251. return uriStat.getStatData();
  252. }
  253. public WebSessionStat getSessionStat(String sessionId, boolean create) {
  254. sessionStatLock.readLock().lock();
  255. try {
  256. WebSessionStat uriStat = sessionStatMap.get(sessionId);
  257. if (uriStat != null) {
  258. return uriStat;
  259. }
  260. } finally {
  261. sessionStatLock.readLock().unlock();
  262. }
  263. if (!create) {
  264. return null;
  265. }
  266. sessionStatLock.writeLock().lock();
  267. try {
  268. WebSessionStat uriStat = sessionStatMap.get(sessionId);
  269. if (uriStat == null) {
  270. if (sessionStatMap.size() >= this.getMaxStatSessionCount()) {
  271. long fullCount = uriSessionMapFullCount.getAndIncrement();
  272. if (fullCount == 0) {
  273. LOG.error("sessionStatMap is full");
  274. }
  275. }
  276. WebSessionStat newStat = new WebSessionStat(sessionId);
  277. sessionStatMap.put(sessionId, newStat);
  278. return newStat;
  279. }
  280. return uriStat;
  281. } finally {
  282. sessionStatLock.writeLock().unlock();
  283. }
  284. }
  285. public void afterInvoke(Throwable error, long nanoSpan) {
  286. runningCount.decrementAndGet();
  287. currentLocal.set(null);
  288. WebRequestStat requestStat = WebRequestStat.current();
  289. if (requestStat != null) {
  290. this.addJdbcExecuteCount(requestStat.getJdbcExecuteCount());
  291. this.addJdbcFetchRowCount(requestStat.getJdbcFetchRowCount());
  292. this.addJdbcUpdateCount(requestStat.getJdbcUpdateCount());
  293. this.addJdbcCommitCount(requestStat.getJdbcCommitCount());
  294. this.addJdbcRollbackCount(requestStat.getJdbcRollbackCount());
  295. this.addJdbcExecuteTimeNano(requestStat.getJdbcExecuteTimeNano());
  296. }
  297. }
  298. public void incrementSessionCount() {
  299. sessionCount.incrementAndGet();
  300. }
  301. public long getSessionCount() {
  302. return sessionCount.get();
  303. }
  304. public void addJdbcFetchRowCount(long delta) {
  305. this.jdbcFetchRowCount.addAndGet(delta);
  306. }
  307. public long getJdbcFetchRowCount() {
  308. return jdbcFetchRowCount.get();
  309. }
  310. public void addJdbcUpdateCount(long updateCount) {
  311. this.jdbcUpdateCount.addAndGet(updateCount);
  312. }
  313. public long getJdbcUpdateCount() {
  314. return jdbcUpdateCount.get();
  315. }
  316. public void incrementJdbcExecuteCount() {
  317. jdbcExecuteCount.incrementAndGet();
  318. }
  319. public void addJdbcExecuteCount(long executeCount) {
  320. jdbcExecuteCount.addAndGet(executeCount);
  321. }
  322. public long getJdbcExecuteCount() {
  323. return jdbcExecuteCount.get();
  324. }
  325. public long getJdbcExecuteTimeNano() {
  326. return jdbcExecuteTimeNano.get();
  327. }
  328. public void addJdbcExecuteTimeNano(long nano) {
  329. jdbcExecuteTimeNano.addAndGet(nano);
  330. }
  331. public void incrementJdbcCommitCount() {
  332. jdbcCommitCount.incrementAndGet();
  333. }
  334. public long getJdbcCommitCount() {
  335. return jdbcCommitCount.get();
  336. }
  337. public void addJdbcCommitCount(long commitCount) {
  338. this.jdbcCommitCount.addAndGet(commitCount);
  339. }
  340. public void incrementJdbcRollbackCount() {
  341. jdbcRollbackCount.incrementAndGet();
  342. }
  343. public long getJdbcRollbackCount() {
  344. return jdbcRollbackCount.get();
  345. }
  346. public void addJdbcRollbackCount(long rollbackCount) {
  347. this.jdbcRollbackCount.addAndGet(rollbackCount);
  348. }
  349. public int getMaxStatUriCount() {
  350. return maxStatUriCount;
  351. }
  352. public void setMaxStatUriCount(int maxStatUriCount) {
  353. this.maxStatUriCount = maxStatUriCount;
  354. }
  355. public int getMaxStatSessionCount() {
  356. return maxStatSessionCount;
  357. }
  358. public void setMaxStatSessionCount(int maxStatSessionCount) {
  359. this.maxStatSessionCount = maxStatSessionCount;
  360. }
  361. public int getRunningCount() {
  362. return this.runningCount.get();
  363. }
  364. public long getConcurrentMax() {
  365. return concurrentMax.get();
  366. }
  367. public long getRequestCount() {
  368. return requestCount.get();
  369. }
  370. public Map<String, Object> getStatData() {
  371. return getStatValue(false).getStatData();
  372. }
  373. public List<WebURIStatValue> getURIStatValueList(boolean reset) {
  374. List<WebURIStatValue> list = new ArrayList<WebURIStatValue>(this.uriStatMap.size());
  375. for (WebURIStat uriStat : this.uriStatMap.values()) {
  376. WebURIStatValue statValue = uriStat.getValue(reset);
  377. if (statValue.getRunningCount() == 0 && statValue.getRequestCount() == 0) {
  378. continue;
  379. }
  380. list.add(statValue);
  381. }
  382. return list;
  383. }
  384. public List<Map<String, Object>> getURIStatDataList() {
  385. List<Map<String, Object>> uriStatDataList = new ArrayList<Map<String, Object>>(this.uriStatMap.size());
  386. for (WebURIStat uriStat : this.uriStatMap.values()) {
  387. Map<String, Object> uriStatData = uriStat.getStatData();
  388. int runningCount = ((Number) uriStatData.get("RunningCount")).intValue();
  389. long requestCount = (Long) uriStatData.get("RequestCount");
  390. if (runningCount == 0 && requestCount == 0) {
  391. continue;
  392. }
  393. uriStatDataList.add(uriStatData);
  394. }
  395. return uriStatDataList;
  396. }
  397. public List<Map<String, Object>> getSessionStatDataList() {
  398. List<Map<String, Object>> sessionStatDataList = new ArrayList<Map<String, Object>>(this.sessionStatMap.size());
  399. for (WebSessionStat sessionStat : Collections.unmodifiableCollection(this.sessionStatMap.values())) {
  400. Map<String, Object> sessionStatData = sessionStat.getStatData();
  401. int runningCount = ((Number) sessionStatData.get("RunningCount")).intValue();
  402. long requestCount = (Long) sessionStatData.get("RequestCount");
  403. if (runningCount == 0 && requestCount == 0) {
  404. continue;
  405. }
  406. sessionStatDataList.add(sessionStatData);
  407. }
  408. return sessionStatDataList;
  409. }
  410. public void computeUserAgent(String userAgent) {
  411. if (userAgent == null || userAgent.length() == 0) {
  412. return;
  413. }
  414. // Mozilla/5.0 (compatible;
  415. final int MOZILLA_COMPATIBLE_OFFSET = 25;
  416. boolean is360SE = userAgent.endsWith("360SE)");
  417. if (is360SE) {
  418. browser360SECount.incrementAndGet();
  419. }
  420. boolean isIE = userAgent.startsWith("MSIE", MOZILLA_COMPATIBLE_OFFSET);
  421. int iePrefixIndex = 30; // "Mozilla/5.0 (compatible; MSIE ".length();
  422. boolean isGoogleToolbar = false;
  423. if (!isIE) {
  424. isGoogleToolbar = userAgent.startsWith("GoogleToolbar", MOZILLA_COMPATIBLE_OFFSET);
  425. if (isGoogleToolbar) {
  426. // MSIE
  427. int tmp = userAgent.indexOf("IE ");
  428. if (tmp != -1) {
  429. isIE = true;
  430. iePrefixIndex = tmp + 3;
  431. }
  432. }
  433. }
  434. if (isIE) {
  435. browserIECount.incrementAndGet();
  436. char v1 = ' ', v2 = ' ';
  437. if (userAgent.length() > iePrefixIndex + 1) {
  438. v1 = userAgent.charAt(iePrefixIndex);
  439. v2 = userAgent.charAt(iePrefixIndex + 1);
  440. } else if (userAgent.length() > iePrefixIndex) {
  441. v1 = userAgent.charAt(iePrefixIndex);
  442. }
  443. switch (v1) {
  444. case '5':
  445. browserIE5Count.incrementAndGet();
  446. break;
  447. case '6':
  448. browserIE6Count.incrementAndGet();
  449. break;
  450. case '7':
  451. browserIE7Count.incrementAndGet();
  452. break;
  453. case '8':
  454. browserIE8Count.incrementAndGet();
  455. break;
  456. case '9':
  457. browserIE9Count.incrementAndGet();
  458. break;
  459. case '1':
  460. if (v2 == '0') {
  461. browserIE10Count.incrementAndGet();
  462. }
  463. break;
  464. default:
  465. break;
  466. }
  467. osWindowsCount.incrementAndGet();
  468. computeUserAgentIEWindowsVersion(userAgent);
  469. if (userAgent.indexOf("Windows Phone") != -1) {
  470. deviceWindowsPhoneCount.incrementAndGet();
  471. }
  472. return;
  473. }
  474. boolean isWindows = false;
  475. boolean isMac = false;
  476. boolean isIpad = false;
  477. boolean isIPhone = false;
  478. boolean isLinux = false;
  479. boolean isX11 = false;
  480. boolean isBSD = false;
  481. if (userAgent.startsWith("Windows", 13)) {
  482. isWindows = true;
  483. } else if (userAgent.startsWith("Macintosh", 13)) {
  484. isMac = true;
  485. } else if (userAgent.startsWith("iPad", 13)) {
  486. isIpad = true;
  487. isMac = true;
  488. } else if (userAgent.startsWith("iPhone", 13)) {
  489. isIPhone = true;
  490. isMac = true;
  491. } else if (userAgent.startsWith("Linux", 13)) {
  492. isLinux = true;
  493. } else if (userAgent.startsWith("X11", 13)) {
  494. isX11 = true;
  495. }
  496. boolean isAndroid = false;
  497. if (isWindows) {
  498. isWindows = true;
  499. osWindowsCount.incrementAndGet();
  500. if (userAgent.indexOf("Windows Phone") != -1) {
  501. deviceWindowsPhoneCount.incrementAndGet();
  502. }
  503. } else if (isMac) {
  504. isMac = true;
  505. osMacOSXCount.incrementAndGet();
  506. if (isIpad && userAgent.indexOf("iPad") != -1) {
  507. deviceIpadCount.incrementAndGet();
  508. } else if (isIPhone || userAgent.indexOf("iPhone") != -1) {
  509. deviceIphoneCount.incrementAndGet();
  510. }
  511. } else if (isLinux) {
  512. osLinuxCount.incrementAndGet();
  513. isAndroid = computeUserAgentAndroid(userAgent);
  514. } else if (userAgent.indexOf("Symbian") != -1) {
  515. osSymbianCount.incrementAndGet();
  516. } else if (userAgent.indexOf("Ubuntu") != -1) {
  517. osLinuxCount.incrementAndGet();
  518. osLinuxUbuntuCount.incrementAndGet();
  519. isLinux = true;
  520. }
  521. if (isX11) {
  522. if (userAgent.indexOf("OpenBSD") != -1) {
  523. osOpenBSDCount.incrementAndGet();
  524. isBSD = true;
  525. } else if (userAgent.indexOf("FreeBSD") != -1) {
  526. osFreeBSDCount.incrementAndGet();
  527. isBSD = true;
  528. } else if ((!isLinux) && userAgent.indexOf("Linux") != -1) {
  529. osLinuxCount.incrementAndGet();
  530. isLinux = true;
  531. }
  532. }
  533. boolean isOpera = userAgent.startsWith("Opera");
  534. if (isOpera) {
  535. if (userAgent.indexOf("Windows") != -1) {
  536. osWindowsCount.incrementAndGet();
  537. } else if (userAgent.indexOf("Linux") != -1) {
  538. osWindowsCount.incrementAndGet();
  539. } else if (userAgent.indexOf("Macintosh") != -1) {
  540. osMacOSXCount.incrementAndGet();
  541. }
  542. browserOperaCount.incrementAndGet();
  543. return;
  544. }
  545. if (isWindows) {
  546. computeUserAgentFirefoxWindowsVersion(userAgent);
  547. }
  548. if (isWindows || isMac || isLinux || isBSD) {
  549. if (userAgent.indexOf("Chrome") != -1) {
  550. browserChromeCount.incrementAndGet();
  551. return;
  552. }
  553. if ((!isAndroid) && userAgent.indexOf("Safari") != -1) {
  554. browserSafariCount.incrementAndGet();
  555. return;
  556. }
  557. if (userAgent.indexOf("Firefox") != -1) {
  558. browserFirefoxCount.incrementAndGet();
  559. return;
  560. }
  561. }
  562. if (userAgent.startsWith("User-Agent: ")) {
  563. String rest = userAgent.substring("User-Agent: ".length());
  564. computeUserAgent(rest);
  565. }
  566. boolean isJava = userAgent.startsWith("Java");
  567. if (isJava) {
  568. botCount.incrementAndGet();
  569. }
  570. if (userAgent.startsWith("msnbot")) {
  571. botCount.incrementAndGet();
  572. botMsnCount.incrementAndGet();
  573. } else if (userAgent.startsWith("Sosospider+")) {
  574. botCount.incrementAndGet();
  575. botSosoCount.incrementAndGet();
  576. } else if (userAgent.startsWith("Sogou")) {
  577. botCount.incrementAndGet();
  578. botSogouCount.incrementAndGet();
  579. } else if (userAgent.startsWith("HuaweiSymantecSpider")) {
  580. botCount.incrementAndGet();
  581. } else if (userAgent.startsWith("Yeti/")) {
  582. botCount.incrementAndGet();
  583. } else if (userAgent.startsWith("mahonie")) {
  584. botCount.incrementAndGet();
  585. } else if (userAgent.startsWith("findlinks")) {
  586. botCount.incrementAndGet();
  587. } else if (userAgent.startsWith("Updownerbot")) {
  588. botCount.incrementAndGet();
  589. } else if (userAgent.startsWith("DoCoMo/")) {
  590. botCount.incrementAndGet();
  591. } else if (userAgent.startsWith("Crawl")) {
  592. botCount.incrementAndGet();
  593. } else if (userAgent.startsWith("SkimBot")) {
  594. botCount.incrementAndGet();
  595. } else if (userAgent.startsWith("YoudaoBot", MOZILLA_COMPATIBLE_OFFSET)) {
  596. botCount.incrementAndGet();
  597. botYoudaoCount.incrementAndGet();
  598. } else if (userAgent.startsWith("bingbot", MOZILLA_COMPATIBLE_OFFSET)) {
  599. botCount.incrementAndGet();
  600. botBingCount.incrementAndGet();
  601. } else if (userAgent.startsWith("Googlebot", MOZILLA_COMPATIBLE_OFFSET)) {
  602. botCount.incrementAndGet();
  603. botGoogleCount.incrementAndGet();
  604. } else if (userAgent.startsWith("Baiduspider", MOZILLA_COMPATIBLE_OFFSET)) {
  605. botCount.incrementAndGet();
  606. botBaiduCount.incrementAndGet();
  607. } else if (userAgent.startsWith("MJ12bot", MOZILLA_COMPATIBLE_OFFSET)) {
  608. botCount.incrementAndGet();
  609. botBaiduCount.incrementAndGet();
  610. } else if (userAgent.startsWith("Mail.RU/", MOZILLA_COMPATIBLE_OFFSET)) {
  611. botCount.incrementAndGet();
  612. } else if (userAgent.startsWith("Yahoo!", MOZILLA_COMPATIBLE_OFFSET)) {
  613. botCount.incrementAndGet();
  614. botYahooCount.incrementAndGet();
  615. } else if (userAgent.startsWith("KaloogaBot", MOZILLA_COMPATIBLE_OFFSET)) {
  616. botCount.incrementAndGet();
  617. } else if (userAgent.startsWith("YandexBot", MOZILLA_COMPATIBLE_OFFSET)) {
  618. botCount.incrementAndGet();
  619. } else if (userAgent.startsWith("Ezooms/", MOZILLA_COMPATIBLE_OFFSET)) {
  620. botCount.incrementAndGet();
  621. } else if (userAgent.startsWith("Exabot/", MOZILLA_COMPATIBLE_OFFSET)) {
  622. botCount.incrementAndGet();
  623. } else if (userAgent.startsWith("AhrefsBot/", MOZILLA_COMPATIBLE_OFFSET)) {
  624. botCount.incrementAndGet();
  625. } else if (userAgent.startsWith("YodaoBot/", MOZILLA_COMPATIBLE_OFFSET)) {
  626. botCount.incrementAndGet();
  627. } else if (userAgent.startsWith("BeetleBot", MOZILLA_COMPATIBLE_OFFSET)) {
  628. botCount.incrementAndGet();
  629. } else if (userAgent.startsWith("archive.org_bot", MOZILLA_COMPATIBLE_OFFSET)) {
  630. botCount.incrementAndGet();
  631. } else if (userAgent.startsWith("aiHitBot", MOZILLA_COMPATIBLE_OFFSET)) {
  632. botCount.incrementAndGet();
  633. } else if (userAgent.startsWith("EventGuruBot", MOZILLA_COMPATIBLE_OFFSET)) {
  634. botCount.incrementAndGet();
  635. } else if (userAgent.equals("Mozilla/5.0 ()")) {
  636. botCount.incrementAndGet();
  637. } else if (userAgent.equals("\"Mozilla/5.0")) {
  638. botCount.incrementAndGet();
  639. } else if (userAgent.equals("Mozilla")) {
  640. botCount.incrementAndGet();
  641. } else if (userAgent.equals("-")) {
  642. botCount.incrementAndGet();
  643. } else if (userAgent.indexOf("Spider") != -1 || userAgent.indexOf("spider") != -1) {
  644. botCount.incrementAndGet();
  645. } else if (userAgent.indexOf("crawl") != -1 || userAgent.indexOf("Crawl") != -1) {
  646. botCount.incrementAndGet();
  647. } else if (userAgent.indexOf("Bot") != -1 || userAgent.indexOf("bot") != -1) {
  648. botCount.incrementAndGet();
  649. }
  650. // Mozilla/5.0 ()
  651. // Mozilla/5.0 (compatible; Mail.RU/2.0)
  652. // Mozilla/5.0 (compatible; bingbot/2.0;
  653. // YoudaoBot
  654. }
  655. private void computeUserAgentFirefoxWindowsVersion(String userAgent) {
  656. if (userAgent.startsWith("Windows NT 5.1", 13)) {
  657. osWindowsXPCount.incrementAndGet();
  658. } else if (userAgent.startsWith("Windows NT 5.1", 25)) {
  659. osWindowsXPCount.incrementAndGet();
  660. } else if (userAgent.startsWith("Windows NT 6.0", 13)) {
  661. osWindowsVistaCount.incrementAndGet();
  662. } else if (userAgent.startsWith("Windows NT 6.1", 13)) {
  663. osWindows7Count.incrementAndGet();
  664. } else if (userAgent.startsWith("Windows NT 6.2", 13)) {
  665. osWindows8Count.incrementAndGet();
  666. } else if (userAgent.startsWith("Windows NT 5.0", 13)) {
  667. osWindows2000Count.incrementAndGet();
  668. } else if (userAgent.startsWith("Windows NT 5.0", 25)) {
  669. osWindows2000Count.incrementAndGet();
  670. }
  671. }
  672. private void computeUserAgentIEWindowsVersion(String userAgent) {
  673. if (userAgent.startsWith("Windows NT 5.1", 35)) {
  674. osWindowsXPCount.incrementAndGet();
  675. } else if (userAgent.startsWith("Windows NT 5.0", 35)) {
  676. osWindows2000Count.incrementAndGet();
  677. } else if (userAgent.startsWith("Windows NT 5.0", 36)) {
  678. osWindows2000Count.incrementAndGet();
  679. } else if (userAgent.startsWith("Windows NT 6.0", 35)) {
  680. osWindowsVistaCount.incrementAndGet();
  681. } else if (userAgent.startsWith("Windows NT 6.1", 35)) {
  682. osWindows7Count.incrementAndGet();
  683. } else if (userAgent.startsWith("Windows NT 6.2", 36)) {
  684. osWindows8Count.incrementAndGet();
  685. } else if (userAgent.startsWith("Windows 98", 36)) {
  686. osWindows98Count.incrementAndGet();
  687. } else if (userAgent.startsWith("Windows 98", 35)) {
  688. osWindows98Count.incrementAndGet();
  689. } else if (userAgent.startsWith("Windows XP", 35)) {
  690. osWindowsXPCount.incrementAndGet();
  691. } else if (userAgent.startsWith("Windows XP", 34)) {
  692. osWindowsXPCount.incrementAndGet();
  693. }
  694. }
  695. private boolean computeUserAgentAndroid(String userAgent) {
  696. boolean isAndroid = userAgent.startsWith("Android", 23);
  697. int toffset = 31;
  698. if (!isAndroid) {
  699. isAndroid = userAgent.startsWith("Android", 20);
  700. toffset = 28;
  701. }
  702. if (isAndroid) {
  703. osAndroidCount.incrementAndGet();
  704. deviceAndroidCount.incrementAndGet();
  705. if (userAgent.startsWith("1.5", toffset)) {
  706. osAndroid15Count.incrementAndGet();
  707. } else if (userAgent.startsWith("1.6", toffset)) {
  708. osAndroid16Count.incrementAndGet();
  709. } else if (userAgent.startsWith("2.0", toffset)) {
  710. osAndroid20Count.incrementAndGet();
  711. } else if (userAgent.startsWith("2.1", toffset)) {
  712. osAndroid21Count.incrementAndGet();
  713. } else if (userAgent.startsWith("2.2", toffset)) {
  714. osAndroid22Count.incrementAndGet();
  715. } else if (userAgent.startsWith("2.3.3", toffset)) {
  716. osAndroid23Count.incrementAndGet();
  717. } else if (userAgent.startsWith("2.3.4", toffset)) {
  718. osAndroid23Count.incrementAndGet();
  719. } else if (userAgent.startsWith("3.0", toffset)) {
  720. osAndroid30Count.incrementAndGet();
  721. } else if (userAgent.startsWith("3.1", toffset)) {
  722. osAndroid31Count.incrementAndGet();
  723. } else if (userAgent.startsWith("3.2", toffset)) {
  724. osAndroid32Count.incrementAndGet();
  725. } else if (userAgent.startsWith("4.0", toffset)) {
  726. osAndroid40Count.incrementAndGet();
  727. } else if (userAgent.startsWith("4.1", toffset)) {
  728. osAndroid41Count.incrementAndGet();
  729. } else if (userAgent.startsWith("4.2", toffset)) {
  730. osAndroid42Count.incrementAndGet();
  731. } else if (userAgent.startsWith("4.3", toffset)) {
  732. osAndroid43Count.incrementAndGet();
  733. }
  734. return true;
  735. }
  736. return false;
  737. }
  738. public long getOSMacOSXCount() {
  739. return osMacOSXCount.get();
  740. }
  741. public long getOSWindowsCount() {
  742. return osWindowsCount.get();
  743. }
  744. public long getOSLinuxCount() {
  745. return osLinuxCount.get();
  746. }
  747. public long getOSSymbianCount() {
  748. return osSymbianCount.get();
  749. }
  750. public long getOSFreeBSDCount() {
  751. return osFreeBSDCount.get();
  752. }
  753. public long getOSOpenBSDCount() {
  754. return osOpenBSDCount.get();
  755. }
  756. public long getOSAndroidCount() {
  757. return osAndroidCount.get();
  758. }
  759. public long getOSWindows98Count() {
  760. return osWindows98Count.get();
  761. }
  762. public long getOSWindowsXPCount() {
  763. return osWindowsXPCount.get();
  764. }
  765. public long getOSWindows2000Count() {
  766. return osWindows2000Count.get();
  767. }
  768. public long getOSWindowsVistaCount() {
  769. return osWindowsVistaCount.get();
  770. }
  771. public long getOSWindows7Count() {
  772. return osWindows7Count.get();
  773. }
  774. public long getOSWindows8Count() {
  775. return osWindows8Count.get();
  776. }
  777. public long getOSAndroid15Count() {
  778. return osAndroid15Count.get();
  779. }
  780. public long getOSAndroid16Count() {
  781. return osAndroid16Count.get();
  782. }
  783. public long getOSAndroid20Count() {
  784. return osAndroid20Count.get();
  785. }
  786. public long getOSAndroid21Count() {
  787. return osAndroid21Count.get();
  788. }
  789. public long getOSAndroid22Count() {
  790. return osAndroid22Count.get();
  791. }
  792. public long getOSAndroid23Count() {
  793. return osAndroid23Count.get();
  794. }
  795. public long getOSAndroid30Count() {
  796. return osAndroid30Count.get();
  797. }
  798. public long getOSAndroid31Count() {
  799. return osAndroid31Count.get();
  800. }
  801. public long getOSAndroid32Count() {
  802. return osAndroid32Count.get();
  803. }
  804. public long getOSAndroid40Count() {
  805. return osAndroid40Count.get();
  806. }
  807. public long getOSAndroid41Count() {
  808. return osAndroid41Count.get();
  809. }
  810. public long getOSAndroid42Count() {
  811. return osAndroid42Count.get();
  812. }
  813. public long getOSAndroid43Count() {
  814. return osAndroid43Count.get();
  815. }
  816. public long getOSLinuxUbuntuCount() {
  817. return osLinuxUbuntuCount.get();
  818. }
  819. public long getBrowserIECount() {
  820. return browserIECount.get();
  821. }
  822. public long getBrowserFirefoxCount() {
  823. return browserFirefoxCount.get();
  824. }
  825. public long getBrowserChromeCount() {
  826. return browserChromeCount.get();
  827. }
  828. public long getBrowserSafariCount() {
  829. return browserSafariCount.get();
  830. }
  831. public long getBrowserOperaCount() {
  832. return browserOperaCount.get();
  833. }
  834. public long getBrowserIE5Count() {
  835. return browserIE5Count.get();
  836. }
  837. public long getBrowserIE6Count() {
  838. return browserIE6Count.get();
  839. }
  840. public long getBrowserIE7Count() {
  841. return browserIE7Count.get();
  842. }
  843. public long getBrowserIE8Count() {
  844. return browserIE8Count.get();
  845. }
  846. public long getBrowserIE9Count() {
  847. return browserIE9Count.get();
  848. }
  849. public long getBrowserIE10Count() {
  850. return browserIE10Count.get();
  851. }
  852. public long getBrowser360SECount() {
  853. return browser360SECount.get();
  854. }
  855. public long getDeviceAndroidCount() {
  856. return deviceAndroidCount.get();
  857. }
  858. public long getDeviceIpadCount() {
  859. return deviceIpadCount.get();
  860. }
  861. public long getDeviceIphoneCount() {
  862. return deviceIphoneCount.get();
  863. }
  864. public long getDeviceWindowsPhoneCount() {
  865. return deviceWindowsPhoneCount.get();
  866. }
  867. public long getBotCount() {
  868. return botCount.get();
  869. }
  870. public long getBotBaiduCount() {
  871. return botBaiduCount.get();
  872. }
  873. public long getBotYoudaoCount() {
  874. return botYoudaoCount.get();
  875. }
  876. public long getBotGoogleCount() {
  877. return botGoogleCount.get();
  878. }
  879. public long getBotMsnCount() {
  880. return botMsnCount.get();
  881. }
  882. public long getBotBingCount() {
  883. return botBingCount.get();
  884. }
  885. public long getBotSosoCount() {
  886. return botSosoCount.get();
  887. }
  888. public long getBotSogouCount() {
  889. return botSogouCount.get();
  890. }
  891. public long getBotYahooCount() {
  892. return botYahooCount.get();
  893. }
  894. public WebAppStatValue getStatValue(boolean reset) {
  895. WebAppStatValue val = new WebAppStatValue();
  896. val.setContextPath(contextPath);
  897. val.setRunningCount(getRunningCount());
  898. val.concurrentMax = get(concurrentMax, reset);
  899. val.requestCount = get(requestCount, reset);
  900. val.sessionCount = get(sessionCount, reset);
  901. val.jdbcFetchRowCount = get(jdbcFetchRowCount, reset);
  902. val.jdbcUpdateCount = get(jdbcUpdateCount, reset);
  903. val.jdbcExecuteCount = get(jdbcExecuteCount, reset);
  904. val.jdbcExecuteTimeNano = get(jdbcExecuteTimeNano, reset);
  905. val.jdbcCommitCount = get(jdbcCommitCount, reset);
  906. val.jdbcRollbackCount = get(jdbcRollbackCount, reset);
  907. val.osMacOSXCount = get(osMacOSXCount, reset);
  908. val.osWindowsCount = get(osWindowsCount, reset);
  909. val.osLinuxCount = get(osLinuxCount, reset);
  910. val.osSymbianCount = get(osSymbianCount, reset);
  911. val.osFreeBSDCount = get(osFreeBSDCount, reset);
  912. val.osOpenBSDCount = get(osOpenBSDCount, reset);
  913. val.osAndroidCount = get(osAndroidCount, reset);
  914. val.osWindows98Count = get(osWindows98Count, reset);
  915. val.osWindowsXPCount = get(osWindowsXPCount, reset);
  916. val.osWindows2000Count = get(osWindows2000Count, reset);
  917. val.osWindowsVistaCount = get(osWindowsVistaCount, reset);
  918. val.osWindows7Count = get(osWindows7Count, reset);
  919. val.osWindows8Count = get(osWindows8Count, reset);
  920. val.osAndroid15Count = get(osAndroid15Count, reset);
  921. val.osAndroid16Count = get(osAndroid16Count, reset);
  922. val.osAndroid20Count = get(osAndroid20Count, reset);
  923. val.osAndroid21Count = get(osAndroid21Count, reset);
  924. val.osAndroid22Count = get(osAndroid22Count, reset);
  925. val.osAndroid23Count = get(osAndroid23Count, reset);
  926. val.osAndroid30Count = get(osAndroid30Count, reset);
  927. val.osAndroid31Count = get(osAndroid31Count, reset);
  928. val.osAndroid32Count = get(osAndroid32Count, reset);
  929. val.osAndroid40Count = get(osAndroid40Count, reset);
  930. val.osAndroid41Count = get(osAndroid41Count, reset);
  931. val.osAndroid42Count = get(osAndroid42Count, reset);
  932. val.osAndroid43Count = get(osAndroid43Count, reset);
  933. val.osLinuxUbuntuCount = get(osLinuxUbuntuCount, reset);
  934. val.browserIECount = get(browserIECount, reset);
  935. val.browserFirefoxCount = get(browserFirefoxCount, reset);
  936. val.browserChromeCount = get(browserChromeCount, reset);
  937. val.browserSafariCount = get(browserSafariCount, reset);
  938. val.browserOperaCount = get(browserOperaCount, reset);
  939. val.browserIE5Count = get(browserIE5Count, reset);
  940. val.browserIE6Count = get(browserIE6Count, reset);
  941. val.browserIE7Count = get(browserIE7Count, reset);
  942. val.browserIE8Count = get(browserIE8Count, reset);
  943. val.browserIE9Count = get(browserIE9Count, reset);
  944. val.browserIE10Count = get(browserIE10Count, reset);
  945. val.browser360SECount = get(browser360SECount, reset);
  946. val.deviceAndroidCount = get(deviceAndroidCount, reset);
  947. val.deviceIpadCount = get(deviceIpadCount, reset);
  948. val.deviceIphoneCount = get(deviceIphoneCount, reset);
  949. val.deviceWindowsPhoneCount = get(deviceWindowsPhoneCount, reset);
  950. val.botCount = get(botCount, reset);
  951. val.botBaiduCount = get(botBaiduCount, reset);
  952. val.botYoudaoCount = get(botYoudaoCount, reset);
  953. val.botGoogleCount = get(botGoogleCount, reset);
  954. val.botMsnCount = get(botMsnCount, reset);
  955. val.botBingCount = get(botBingCount, reset);
  956. val.botSosoCount = get(botSosoCount, reset);
  957. val.botSogouCount = get(botSogouCount, reset);
  958. val.botYahooCount = get(botYahooCount, reset);
  959. return val;
  960. }
  961. }