PageRenderTime 39ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 0ms

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

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