feat: initial iShare project code

This commit is contained in:
purovps
2026-02-16 23:20:59 +08:00
parent 8c83a6fd46
commit 6f270a972e
1910 changed files with 218015 additions and 0 deletions

View File

@@ -0,0 +1,18 @@
FROM pig4cloud/java:8-jre
MAINTAINER wangiegie@gmail.com
ENV TZ=Asia/Shanghai
ENV JAVA_OPTS="-Xms128m -Xmx256m -Djava.security.egd=file:/dev/./urandom"
RUN ln -sf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN mkdir -p /pigx-monitor
WORKDIR /pigx-monitor
EXPOSE 5001
ADD ./target/pigx-monitor.jar ./
CMD sleep 120;java $JAVA_OPTS -jar pigx-monitor.jar

View File

@@ -0,0 +1,90 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-visual</artifactId>
<version>5.2.0</version>
</parent>
<artifactId>pigx-monitor</artifactId>
<packaging>jar</packaging>
<description>pigx 监控模块,基于 spring boot admin</description>
<dependencies>
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common-core</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-http</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--监控服务端-->
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-server</artifactId>
<version>${spring-boot-admin.version}</version>
</dependency>
<!--注册中心客户端-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--配置中心客户端-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!--web 模块-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--undertow容器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
<!--druid 连接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<!--monitor json 操作-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<groupId>io.fabric8</groupId>
<artifactId>docker-maven-plugin</artifactId>
<configuration>
<skip>false</skip>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,40 @@
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pigx.monitor;
import de.codecentric.boot.admin.server.config.EnableAdminServer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
/**
* @author lengleng
* @date 2019年11月4日 监控中心
*/
@EnableAdminServer
@EnableDiscoveryClient
@SpringBootApplication
public class PigxMonitorApplication {
public static void main(String[] args) {
SpringApplication.run(PigxMonitorApplication.class, args);
}
}

View File

@@ -0,0 +1,42 @@
package com.pig4cloud.pigx.monitor.config;
import com.pig4cloud.pigx.monitor.support.MonitorViewServlet;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* @author lengleng
* @date 2020/10/19
* <p>
* druid 监控配置类
*/
@Configuration
public class DruidMonitorConfigurer {
@Bean
public ServletRegistrationBean statViewServletRegistrationBean() {
ServletRegistrationBean registrationBean = new ServletRegistrationBean();
registrationBean.setServlet(new MonitorViewServlet());
registrationBean.addUrlMappings("/druid/*");
return registrationBean;
}
@Data
@Component
@ConfigurationProperties(prefix = "monitor")
public class MonitorProperties {
/**
* 需要监控的服务
*/
private List<String> applications;
}
}

View File

@@ -0,0 +1,32 @@
package com.pig4cloud.pigx.monitor.controller;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.monitor.service.RedisService;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author lengleng
* @date 2019-05-08
* <p>
* redis 数据
*/
@RestController
@AllArgsConstructor
@RequestMapping("/redis")
public class RedisController {
private final RedisService redisService;
/**
* 查询redis信息
* @return
*/
@GetMapping("/info")
public R memory() {
return R.ok(redisService.getInfo());
}
}

View File

@@ -0,0 +1,20 @@
package com.pig4cloud.pigx.monitor.model;
import lombok.Data;
/**
* @author linchtech
* @date 2020-09-16 14:08
**/
@Data
public class ServiceNode {
private String id;
private Integer port;
private String address;
private String serviceName;
}

View File

@@ -0,0 +1,63 @@
package com.pig4cloud.pigx.monitor.model.dto;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* @author linchtech
* @date 2020-09-21 9:26
**/
@NoArgsConstructor
@Data
public class ConnectionResult {
@JSONField(name = "ResultCode")
private int ResultCode;
@JSONField(name = "Content")
private List<ContentBean> Content;
@NoArgsConstructor
@Data
public static class ContentBean {
@JSONField(name = "id")
private int id;
@JSONField(name = "connectionId")
private int connectionId;
@JSONField(name = "useCount")
private int useCount;
@JSONField(name = "lastActiveTime")
private String lastActiveTime;
@JSONField(name = "connectTime")
private String connectTime;
@JSONField(name = "holdability")
private int holdability;
@JSONField(name = "transactionIsolation")
private int transactionIsolation;
@JSONField(name = "autoCommit")
private boolean autoCommit;
@JSONField(name = "readoOnly")
private boolean readoOnly;
@JSONField(name = "keepAliveCheckCount")
private int keepAliveCheckCount;
@JSONField(name = "pscache")
private List<?> pscache;
}
}

View File

@@ -0,0 +1,235 @@
package com.pig4cloud.pigx.monitor.model.dto;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* @author linchtech
* @date 2020-09-16 18:32
**/
@Data
@NoArgsConstructor
public class DataSourceResult {
@JSONField(name = "ResultCode")
private int ResultCode;
@JSONField(name = "Content")
private List<ContentBean> Content;
@NoArgsConstructor
@Data
public static class ContentBean {
private String serviceId;
@JSONField(name = "Identity")
private int Identity;
@JSONField(name = "Name")
private String Name;
@JSONField(name = "DbType")
private String DbType;
@JSONField(name = "DriverClassName")
private String DriverClassName;
@JSONField(name = "URL")
private String URL;
@JSONField(name = "UserName")
private String UserName;
@JSONField(name = "WaitThreadCount")
private int WaitThreadCount;
@JSONField(name = "NotEmptyWaitCount")
private int NotEmptyWaitCount;
@JSONField(name = "NotEmptyWaitMillis")
private int NotEmptyWaitMillis;
@JSONField(name = "PoolingCount")
private int PoolingCount;
@JSONField(name = "PoolingPeak")
private int PoolingPeak;
@JSONField(name = "PoolingPeakTime")
private String PoolingPeakTime;
@JSONField(name = "ActiveCount")
private int ActiveCount;
@JSONField(name = "ActivePeak")
private int ActivePeak;
@JSONField(name = "ActivePeakTime")
private String ActivePeakTime;
@JSONField(name = "InitialSize")
private int InitialSize;
@JSONField(name = "MinIdle")
private int MinIdle;
@JSONField(name = "MaxActive")
private int MaxActive;
@JSONField(name = "QueryTimeout")
private int QueryTimeout;
@JSONField(name = "TransactionQueryTimeout")
private int TransactionQueryTimeout;
@JSONField(name = "LoginTimeout")
private int LoginTimeout;
@JSONField(name = "ValidConnectionCheckerClassName")
private String ValidConnectionCheckerClassName;
@JSONField(name = "ExceptionSorterClassName")
private String ExceptionSorterClassName;
@JSONField(name = "TestOnBorrow")
private boolean TestOnBorrow;
@JSONField(name = "TestOnReturn")
private boolean TestOnReturn;
@JSONField(name = "TestWhileIdle")
private boolean TestWhileIdle;
@JSONField(name = "DefaultAutoCommit")
private boolean DefaultAutoCommit;
@JSONField(name = "DefaultReadOnly")
private Object DefaultReadOnly;
@JSONField(name = "DefaultTransactionIsolation")
private Object DefaultTransactionIsolation;
@JSONField(name = "LogicConnectCount")
private int LogicConnectCount;
@JSONField(name = "LogicCloseCount")
private int LogicCloseCount;
@JSONField(name = "LogicConnectErrorCount")
private int LogicConnectErrorCount;
@JSONField(name = "PhysicalConnectCount")
private int PhysicalConnectCount;
@JSONField(name = "PhysicalCloseCount")
private int PhysicalCloseCount;
@JSONField(name = "PhysicalConnectErrorCount")
private int PhysicalConnectErrorCount;
@JSONField(name = "ExecuteCount")
private int ExecuteCount;
@JSONField(name = "ExecuteUpdateCount")
private int ExecuteUpdateCount;
@JSONField(name = "ExecuteQueryCount")
private int ExecuteQueryCount;
@JSONField(name = "ExecuteBatchCount")
private int ExecuteBatchCount;
@JSONField(name = "ErrorCount")
private int ErrorCount;
@JSONField(name = "CommitCount")
private int CommitCount;
@JSONField(name = "RollbackCount")
private int RollbackCount;
@JSONField(name = "PSCacheAccessCount")
private int PSCacheAccessCount;
@JSONField(name = "PSCacheHitCount")
private int PSCacheHitCount;
@JSONField(name = "PSCacheMissCount")
private int PSCacheMissCount;
@JSONField(name = "StartTransactionCount")
private int StartTransactionCount;
@JSONField(name = "RemoveAbandoned")
private boolean RemoveAbandoned;
@JSONField(name = "ClobOpenCount")
private int ClobOpenCount;
@JSONField(name = "BlobOpenCount")
private int BlobOpenCount;
@JSONField(name = "KeepAliveCheckCount")
private int KeepAliveCheckCount;
@JSONField(name = "KeepAlive")
private boolean KeepAlive;
@JSONField(name = "FailFast")
private boolean FailFast;
@JSONField(name = "MaxWait")
private int MaxWait;
@JSONField(name = "MaxWaitThreadCount")
private int MaxWaitThreadCount;
@JSONField(name = "PoolPreparedStatements")
private boolean PoolPreparedStatements;
@JSONField(name = "MaxPoolPreparedStatementPerConnectionSize")
private int MaxPoolPreparedStatementPerConnectionSize;
@JSONField(name = "MinEvictableIdleTimeMillis")
private int MinEvictableIdleTimeMillis;
@JSONField(name = "MaxEvictableIdleTimeMillis")
private int MaxEvictableIdleTimeMillis;
@JSONField(name = "LogDifferentThread")
private boolean LogDifferentThread;
@JSONField(name = "RecycleErrorCount")
private int RecycleErrorCount;
@JSONField(name = "PreparedStatementOpenCount")
private int PreparedStatementOpenCount;
@JSONField(name = "PreparedStatementClosedCount")
private int PreparedStatementClosedCount;
@JSONField(name = "UseUnfairLock")
private boolean UseUnfairLock;
@JSONField(name = "InitGlobalVariants")
private boolean InitGlobalVariants;
@JSONField(name = "InitVariants")
private boolean InitVariants;
@JSONField(name = "FilterClassNames")
private List<String> FilterClassNames;
@JSONField(name = "TransactionHistogram")
private List<Integer> TransactionHistogram;
@JSONField(name = "ConnectionHoldTimeHistogram")
private List<Integer> ConnectionHoldTimeHistogram;
}
}

View File

@@ -0,0 +1,170 @@
package com.pig4cloud.pigx.monitor.model.dto;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* @author linchtech
* @date 2020-09-16 16:18
**/
@NoArgsConstructor
@Data
public class SqlDetailResult {
@JSONField(name = "ResultCode")
private int ResultCode;
@JSONField(name = "Content")
private ContentBean Content;
@NoArgsConstructor
@Data
public static class ContentBean {
@JSONField(name = "ExecuteAndResultSetHoldTime")
private int ExecuteAndResultSetHoldTime;
@JSONField(name = "LastErrorMessage")
private Object LastErrorMessage;
@JSONField(name = "InputStreamOpenCount")
private int InputStreamOpenCount;
@JSONField(name = "BatchSizeTotal")
private int BatchSizeTotal;
@JSONField(name = "FetchRowCountMax")
private int FetchRowCountMax;
@JSONField(name = "ErrorCount")
private int ErrorCount;
@JSONField(name = "BatchSizeMax")
private int BatchSizeMax;
@JSONField(name = "URL")
private Object URL;
@JSONField(name = "Name")
private Object Name;
@JSONField(name = "LastErrorTime")
private Object LastErrorTime;
@JSONField(name = "ReaderOpenCount")
private int ReaderOpenCount;
@JSONField(name = "parsedRelationships")
private String parsedRelationships;
@JSONField(name = "EffectedRowCountMax")
private int EffectedRowCountMax;
@JSONField(name = "LastErrorClass")
private Object LastErrorClass;
@JSONField(name = "InTransactionCount")
private int InTransactionCount;
@JSONField(name = "LastErrorStackTrace")
private Object LastErrorStackTrace;
@JSONField(name = "ResultSetHoldTime")
private int ResultSetHoldTime;
@JSONField(name = "TotalTime")
private int TotalTime;
@JSONField(name = "ID")
private int ID;
@JSONField(name = "ConcurrentMax")
private int ConcurrentMax;
@JSONField(name = "RunningCount")
private int RunningCount;
@JSONField(name = "FetchRowCount")
private int FetchRowCount;
@JSONField(name = "parsedFields")
private String parsedFields;
@JSONField(name = "MaxTimespanOccurTime")
private String MaxTimespanOccurTime;
@JSONField(name = "LastSlowParameters")
private Object LastSlowParameters;
@JSONField(name = "ReadBytesLength")
private int ReadBytesLength;
@JSONField(name = "formattedSql")
private String formattedSql;
@JSONField(name = "DbType")
private String DbType;
@JSONField(name = "DataSource")
private Object DataSource;
@JSONField(name = "SQL")
private String SQL;
@JSONField(name = "HASH")
private long HASH;
@JSONField(name = "LastError")
private Object LastError;
@JSONField(name = "MaxTimespan")
private int MaxTimespan;
@JSONField(name = "parsedTable")
private String parsedTable;
@JSONField(name = "parsedOrderbycolumns")
private String parsedOrderbycolumns;
@JSONField(name = "BlobOpenCount")
private int BlobOpenCount;
@JSONField(name = "ExecuteCount")
private int ExecuteCount;
@JSONField(name = "EffectedRowCount")
private int EffectedRowCount;
@JSONField(name = "ReadStringLength")
private int ReadStringLength;
@JSONField(name = "File")
private Object File;
@JSONField(name = "ClobOpenCount")
private int ClobOpenCount;
@JSONField(name = "LastTime")
private String LastTime;
@JSONField(name = "parsedConditions")
private String parsedConditions;
@JSONField(name = "EffectedRowCountHistogram")
private List<Integer> EffectedRowCountHistogram;
@JSONField(name = "Histogram")
private List<Integer> Histogram;
@JSONField(name = "ExecuteAndResultHoldTimeHistogram")
private List<Integer> ExecuteAndResultHoldTimeHistogram;
@JSONField(name = "FetchRowCountHistogram")
private List<Integer> FetchRowCountHistogram;
}
}

View File

@@ -0,0 +1,158 @@
package com.pig4cloud.pigx.monitor.model.dto;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* @author linchtech
* @date 2020-09-16 14:37
**/
@NoArgsConstructor
@Data
public class SqlListResult {
@JSONField(name = "ResultCode")
private int ResultCode;
@JSONField(name = "Content")
private List<ContentBean> Content;
@NoArgsConstructor
@Data
public static class ContentBean {
private String serviceId;
private String address;
private Integer port;
@JSONField(name = "ExecuteAndResultSetHoldTime")
private int ExecuteAndResultSetHoldTime;
@JSONField(name = "LastErrorMessage")
private Object LastErrorMessage;
@JSONField(name = "InputStreamOpenCount")
private int InputStreamOpenCount;
@JSONField(name = "BatchSizeTotal")
private int BatchSizeTotal;
@JSONField(name = "FetchRowCountMax")
private int FetchRowCountMax;
@JSONField(name = "ErrorCount")
private int ErrorCount;
@JSONField(name = "BatchSizeMax")
private int BatchSizeMax;
@JSONField(name = "URL")
private Object URL;
@JSONField(name = "Name")
private Object Name;
@JSONField(name = "LastErrorTime")
private Object LastErrorTime;
@JSONField(name = "ReaderOpenCount")
private int ReaderOpenCount;
@JSONField(name = "EffectedRowCountMax")
private int EffectedRowCountMax;
@JSONField(name = "LastErrorClass")
private Object LastErrorClass;
@JSONField(name = "InTransactionCount")
private int InTransactionCount;
@JSONField(name = "LastErrorStackTrace")
private Object LastErrorStackTrace;
@JSONField(name = "ResultSetHoldTime")
private int ResultSetHoldTime;
@JSONField(name = "TotalTime")
private int TotalTime;
@JSONField(name = "ID")
private int ID;
@JSONField(name = "ConcurrentMax")
private int ConcurrentMax;
@JSONField(name = "RunningCount")
private int RunningCount;
@JSONField(name = "FetchRowCount")
private int FetchRowCount;
@JSONField(name = "MaxTimespanOccurTime")
private String MaxTimespanOccurTime;
@JSONField(name = "LastSlowParameters")
private Object LastSlowParameters;
@JSONField(name = "ReadBytesLength")
private int ReadBytesLength;
@JSONField(name = "DbType")
private String DbType;
@JSONField(name = "DataSource")
private Object DataSource;
@JSONField(name = "SQL")
private String SQL;
@JSONField(name = "HASH")
private long HASH;
@JSONField(name = "LastError")
private Object LastError;
@JSONField(name = "MaxTimespan")
private int MaxTimespan;
@JSONField(name = "BlobOpenCount")
private int BlobOpenCount;
@JSONField(name = "ExecuteCount")
private int ExecuteCount;
@JSONField(name = "EffectedRowCount")
private int EffectedRowCount;
@JSONField(name = "ReadStringLength")
private int ReadStringLength;
@JSONField(name = "File")
private Object File;
@JSONField(name = "ClobOpenCount")
private int ClobOpenCount;
@JSONField(name = "LastTime")
private String LastTime;
@JSONField(name = "EffectedRowCountHistogram")
private List<Integer> EffectedRowCountHistogram;
@JSONField(name = "Histogram")
private List<Integer> Histogram;
@JSONField(name = "ExecuteAndResultHoldTimeHistogram")
private List<Integer> ExecuteAndResultHoldTimeHistogram;
@JSONField(name = "FetchRowCountHistogram")
private List<Integer> FetchRowCountHistogram;
}
}

View File

@@ -0,0 +1,153 @@
package com.pig4cloud.pigx.monitor.model.dto;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* @author linchtech
* @date 2020-09-17 18:18
**/
@Data
@NoArgsConstructor
public class WallResult {
@JSONField(name = "ResultCode")
private int ResultCode;
@JSONField(name = "Content")
private ContentBean Content = new ContentBean();
@NoArgsConstructor
@Data
public static class ContentBean {
@JSONField(name = "checkCount")
private int checkCount;
@JSONField(name = "hardCheckCount")
private int hardCheckCount;
@JSONField(name = "violationCount")
private int violationCount;
@JSONField(name = "violationEffectRowCount")
private int violationEffectRowCount;
@JSONField(name = "blackListHitCount")
private int blackListHitCount;
@JSONField(name = "blackListSize")
private int blackListSize;
@JSONField(name = "whiteListHitCount")
private int whiteListHitCount;
@JSONField(name = "whiteListSize")
private int whiteListSize;
@JSONField(name = "syntaxErrorCount")
private int syntaxErrorCount;
@JSONField(name = "tables")
private List<TablesBean> tables = new ArrayList<>();
@JSONField(name = "functions")
private List<FunctionsBean> functions = new ArrayList<>();
@JSONField(name = "blackList")
private List<Object> blackList = new ArrayList<>();
@JSONField(name = "whiteList")
private List<WhiteListBean> whiteList = new ArrayList<>();
@NoArgsConstructor
@Data
public static class TablesBean {
@JSONField(name = "name")
private String name;
@JSONField(name = "selectCount")
private int selectCount;
@JSONField(name = "fetchRowCount")
private int fetchRowCount;
@JSONField(name = "fetchRowCountHistogram")
private List<Integer> fetchRowCountHistogram;
}
@NoArgsConstructor
@Data
public static class FunctionsBean {
@JSONField(name = "name")
private String name;
@JSONField(name = "invokeCount")
private int invokeCount;
}
@NoArgsConstructor
@Data
public static class WhiteListBean {
@JSONField(name = "sql")
private String sql;
@JSONField(name = "sample")
private String sample;
@JSONField(name = "executeCount")
private int executeCount;
@JSONField(name = "fetchRowCount")
private int fetchRowCount;
}
}
/**
* 累加结果
* @param wallResult 需要累加的对象
* @param sumResult 累加后的对象
*/
public void sum(WallResult wallResult, WallResult sumResult) {
sumResult.getContent()
.setCheckCount(sumResult.getContent().getCheckCount() + wallResult.getContent().getCheckCount());
sumResult.getContent().setHardCheckCount(
sumResult.getContent().getHardCheckCount() + wallResult.getContent().getHardCheckCount());
sumResult.getContent().setViolationCount(
sumResult.getContent().getViolationCount() + wallResult.getContent().getViolationCount());
sumResult.getContent().setViolationEffectRowCount(sumResult.getContent().getViolationEffectRowCount()
+ wallResult.getContent().getViolationEffectRowCount());
sumResult.getContent().setBlackListHitCount(
sumResult.getContent().getBlackListHitCount() + wallResult.getContent().getBlackListHitCount());
sumResult.getContent().setBlackListSize(
sumResult.getContent().getBlackListSize() + wallResult.getContent().getBlackListSize());
sumResult.getContent().setWhiteListHitCount(
sumResult.getContent().getWhiteListHitCount() + wallResult.getContent().getWhiteListHitCount());
sumResult.getContent().setWhiteListSize(
sumResult.getContent().getWhiteListSize() + wallResult.getContent().getWhiteListSize());
sumResult.getContent().setSyntaxErrorCount(
sumResult.getContent().getSyntaxErrorCount() + wallResult.getContent().getSyntaxErrorCount());
sumResult.getContent().getTables().addAll(wallResult.getContent().getTables() == null ? Collections.emptyList()
: wallResult.getContent().getTables());
sumResult.getContent().getFunctions().addAll(wallResult.getContent().getFunctions() == null
? Collections.emptyList() : wallResult.getContent().getFunctions());
sumResult.getContent().getBlackList().addAll(wallResult.getContent().getBlackList() == null
? Collections.emptyList() : wallResult.getContent().getBlackList());
sumResult.getContent().getWhiteList().addAll(wallResult.getContent().getWhiteList() == null
? Collections.emptyList() : wallResult.getContent().getWhiteList());
}
}

View File

@@ -0,0 +1,104 @@
package com.pig4cloud.pigx.monitor.model.dto;
import com.alibaba.fastjson.annotation.JSONField;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* @author linchtech
* @date 2020-09-17 18:27
**/
@NoArgsConstructor
@Data
public class WebResult {
@JSONField(name = "ResultCode")
private int ResultCode;
@JSONField(name = "Content")
private List<ContentBean> Content;
@NoArgsConstructor
@Data
public static class ContentBean {
@JSONField(name = "URI")
private String URI;
@JSONField(name = "RunningCount")
private int RunningCount;
@JSONField(name = "ConcurrentMax")
private int ConcurrentMax;
@JSONField(name = "RequestCount")
private int RequestCount;
@JSONField(name = "RequestTimeMillis")
private int RequestTimeMillis;
@JSONField(name = "ErrorCount")
private int ErrorCount;
@JSONField(name = "LastAccessTime")
private String LastAccessTime;
@JSONField(name = "JdbcCommitCount")
private int JdbcCommitCount;
@JSONField(name = "JdbcRollbackCount")
private int JdbcRollbackCount;
@JSONField(name = "JdbcExecuteCount")
private int JdbcExecuteCount;
@JSONField(name = "JdbcExecuteErrorCount")
private int JdbcExecuteErrorCount;
@JSONField(name = "JdbcExecutePeak")
private int JdbcExecutePeak;
@JSONField(name = "JdbcExecuteTimeMillis")
private int JdbcExecuteTimeMillis;
@JSONField(name = "JdbcFetchRowCount")
private int JdbcFetchRowCount;
@JSONField(name = "JdbcFetchRowPeak")
private int JdbcFetchRowPeak;
@JSONField(name = "JdbcUpdateCount")
private int JdbcUpdateCount;
@JSONField(name = "JdbcUpdatePeak")
private int JdbcUpdatePeak;
@JSONField(name = "JdbcPoolConnectionOpenCount")
private int JdbcPoolConnectionOpenCount;
@JSONField(name = "JdbcPoolConnectionCloseCount")
private int JdbcPoolConnectionCloseCount;
@JSONField(name = "JdbcResultSetOpenCount")
private int JdbcResultSetOpenCount;
@JSONField(name = "JdbcResultSetCloseCount")
private int JdbcResultSetCloseCount;
@JSONField(name = "RequestTimeMillisMax")
private int RequestTimeMillisMax;
@JSONField(name = "RequestTimeMillisMaxOccurTime")
private String RequestTimeMillisMaxOccurTime;
@JSONField(name = "Histogram")
private List<Integer> Histogram;
@JSONField(name = "Profiles")
private List<?> Profiles;
}
}

View File

@@ -0,0 +1,19 @@
package com.pig4cloud.pigx.monitor.service;
import java.util.Map;
/**
* @author lengleng
* @date 2019-05-08
* <p>
* redis 监控
*/
public interface RedisService {
/**
* 获取内存信息
* @return
*/
Map<String, Object> getInfo();
}

View File

@@ -0,0 +1,487 @@
package com.pig4cloud.pigx.monitor.service.impl;
import cn.hutool.http.HttpUtil;
import com.alibaba.druid.stat.DruidStatServiceMBean;
import com.alibaba.druid.support.http.stat.WebAppStatManager;
import com.alibaba.druid.support.json.JSONUtils;
import com.alibaba.druid.support.spring.stat.SpringStatManager;
import com.alibaba.druid.util.MapComparator;
import com.alibaba.druid.util.StringUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.pig4cloud.pigx.monitor.config.DruidMonitorConfigurer;
import com.pig4cloud.pigx.monitor.model.ServiceNode;
import com.pig4cloud.pigx.monitor.model.dto.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.stereotype.Component;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* 分布式环境下 druid 监控数据采集copy from https://u.nu/8-shl
*
* @author linchtech
* @date 2020-09-16 11:12
**/
@Slf4j
@Component
public class MonitorStatService implements DruidStatServiceMBean {
public final static int RESULT_CODE_SUCCESS = 1;
public final static int RESULT_CODE_ERROR = -1;
private final static int DEFAULT_PAGE = 1;
private final static int DEFAULT_PER_PAGE_COUNT = Integer.MAX_VALUE;
private static final String ORDER_TYPE_DESC = "desc";
private static final String ORDER_TYPE_ASC = "asc";
private static final String DEFAULT_ORDER_TYPE = ORDER_TYPE_ASC;
private static final String DEFAULT_ORDERBY = "SQL";
/**
* 以consul注册的服务的id为key,value为某个微服务节点
*/
public static Map<String, ServiceNode> serviceIdMap = new HashMap<>();
@Autowired
private DiscoveryClient discoveryClient;
@Autowired
private DruidMonitorConfigurer.MonitorProperties monitorProperties;
/**
* 获取所有服务信息
* @return
*/
public Map<String, ServiceNode> getAllServiceNodeMap() {
List<String> services = discoveryClient.getServices();
List<ServiceNode> serviceNodes = new ArrayList<>();
for (String service : services) {
List<ServiceInstance> instances = discoveryClient.getInstances(service);
for (ServiceInstance instance : instances) {
String host = instance.getHost();
int port = instance.getPort();
String instanceId = String.format("%s_%s", host, port);
String serviceId = instance.getServiceId();
// 根据前端参数采集指定的服务
if (monitorProperties.getApplications().contains(serviceId)) {
ServiceNode serviceNode = new ServiceNode();
serviceNode.setId(instanceId);
serviceNode.setPort(port);
serviceNode.setAddress(host);
serviceNode.setServiceName(serviceId);
serviceNodes.add(serviceNode);
serviceIdMap.put(instanceId, serviceNode);
}
}
}
return serviceNodes.parallelStream()
.collect(Collectors.toMap(i -> i.getServiceName() + "-" + i.getAddress() + "-" + i.getPort(),
Function.identity(), (v1, v2) -> v2));
}
/**
* 获取指定服务名的所有节点
* @param parameters
* @return
*/
public Map<String, ServiceNode> getServiceAllNodeMap(Map<String, String> parameters) {
String requestServiceName = parameters.get("serviceName");
List<String> services = discoveryClient.getServices();
List<ServiceNode> serviceNodes = new ArrayList<>();
for (String service : services) {
List<ServiceInstance> instances = discoveryClient.getInstances(service);
for (ServiceInstance instance : instances) {
String host = instance.getHost();
int port = instance.getPort();
String serviceId = instance.getServiceId();
String instanceId = String.format("%s_%s", host, port);
// 根据前端参数采集指定的服务
if (serviceId.equals(requestServiceName)) {
ServiceNode serviceNode = new ServiceNode();
serviceNode.setId(instanceId);
serviceNode.setPort(port);
serviceNode.setAddress(host);
serviceNode.setServiceName(serviceId);
serviceNodes.add(serviceNode);
serviceIdMap.put(instanceId, serviceNode);
}
}
}
return serviceNodes.parallelStream()
.collect(Collectors.toMap(i -> i.getServiceName() + "-" + i.getAddress() + "-" + i.getPort(),
Function.identity(), (v1, v2) -> v2));
}
@Override
public String service(String url) {
Map<String, String> parameters = getParameters(url);
if (url.endsWith("serviceList.json")) {
return JSON.toJSONString(monitorProperties.getApplications());
}
if (url.equals("/datasource.json")) {
String serviceName = StringUtils.subString(url, "serviceName=", "&sql-");
Integer id = StringUtils.subStringToInteger(url, "datasource-", ".");
return getDataSourceStatData();
}
if (url.startsWith("/datasource-")) {
String serviceName = StringUtils.subString(url, "serviceName=", "&sql-");
Integer id = StringUtils.subStringToInteger(url, "datasource-", ".");
Object result = getDataSourceStatData();
return returnJSONResult(result == null ? RESULT_CODE_ERROR : RESULT_CODE_SUCCESS, result);
}
// 活跃连接数查看
if (url.startsWith("/connectionInfo-") && url.endsWith(".json")) {
String serviceId = StringUtils.subString(url, "&serviceId=", ".json");
Integer id = StringUtils.subStringToInteger(url, "connectionInfo-", "&");
return getPoolingConnectionInfoByDataSourceId(id, serviceId);
}
// SQL监控列表
if (url.startsWith("/sql.json")) {
return getSqlStatDataList(parameters);
}
// SQL防火墙
if (url.startsWith("/wall.json")) {
return getWallStatMap(parameters);
}
// SQL详情
if (url.startsWith("/serviceId") && url.indexOf(".json") > 0) {
String serviceId = StringUtils.subString(url, "serviceId=", "&");
Integer id = StringUtils.subStringToInteger(url, "sql-", ".json");
return getSqlStat(id, serviceId);
}
if (url.startsWith("/weburi.json")) {
return getWebURIStatDataList(parameters);
}
if (url.startsWith("/weburi-") && url.indexOf(".json") > 0) {
String uri = StringUtils.subString(url, "weburi-", ".json", true);
return returnJSONResult(RESULT_CODE_SUCCESS, getWebURIStatData(uri));
}
if (url.startsWith("/webapp.json")) {
return returnJSONResult(RESULT_CODE_SUCCESS, getWebAppStatDataList(parameters));
}
if (url.startsWith("/websession.json")) {
return returnJSONResult(RESULT_CODE_SUCCESS, getWebSessionStatDataList(parameters));
}
if (url.startsWith("/websession-") && url.indexOf(".json") > 0) {
String id = StringUtils.subString(url, "websession-", ".json");
return returnJSONResult(RESULT_CODE_SUCCESS, getWebSessionStatData(id));
}
if (url.startsWith("/spring.json")) {
return returnJSONResult(RESULT_CODE_SUCCESS, getSpringStatDataList(parameters));
}
if (url.startsWith("/spring-detail.json")) {
String clazz = parameters.get("class");
String method = parameters.get("method");
return returnJSONResult(RESULT_CODE_SUCCESS, getSpringMethodStatData(clazz, method));
}
return returnJSONResult(RESULT_CODE_ERROR, "Do not support this request, please contact with administrator.");
}
public static String returnJSONResult(int resultCode, Object content) {
Map<String, Object> dataMap = new LinkedHashMap<String, Object>();
dataMap.put("ResultCode", resultCode);
dataMap.put("Content", content);
return JSONUtils.toJSONString(dataMap);
}
public String getWallStatMap(Map<String, String> parameters) {
Map<String, ServiceNode> allNodeMap = getServiceAllNodeMap(parameters);
List<WallResult> countResult = new ArrayList<>();
for (String nodeKey : allNodeMap.keySet()) {
ServiceNode serviceNode = allNodeMap.get(nodeKey);
String url = getRequestUrl(parameters, serviceNode, "/druid/wall.json");
WallResult wallResult = JSONObject.parseObject(HttpUtil.get(url), WallResult.class);
countResult.add(wallResult);
}
WallResult lastCount = new WallResult();
for (WallResult wallResult : countResult) {
lastCount.sum(wallResult, lastCount);
}
return JSON.toJSONString(lastCount);
}
private List<Map<String, Object>> getSpringStatDataList(Map<String, String> parameters) {
List<Map<String, Object>> array = SpringStatManager.getInstance().getMethodStatData();
return comparatorOrderBy(array, parameters);
}
@SuppressWarnings("unchecked")
private String getWebURIStatDataList(Map<String, String> parameters) {
Map<String, ServiceNode> allNodeMap = getServiceAllNodeMap(parameters);
List<Map<String, Object>> arrayMap = new ArrayList<>();
for (String nodeKey : allNodeMap.keySet()) {
ServiceNode serviceNode = allNodeMap.get(nodeKey);
String url = getRequestUrl(parameters, serviceNode, "/druid/weburi.json");
WebResult dataSourceResult = JSONObject.parseObject(HttpUtil.get(url), WebResult.class);
if (dataSourceResult != null) {
List<WebResult.ContentBean> nodeContent = dataSourceResult.getContent();
if (nodeContent != null) {
for (WebResult.ContentBean contentBean : nodeContent) {
Map<String, Object> map = JSONObject.parseObject(JSONObject.toJSONString(contentBean),
Map.class);
arrayMap.add(map);
}
}
}
}
List<Map<String, Object>> maps = comparatorOrderBy(arrayMap, parameters);
String jsonString = JSON.toJSONString(maps);
JSONArray objects = JSON.parseArray(jsonString);
JSONObject jsonObject = new JSONObject();
jsonObject.put("ResultCode", RESULT_CODE_SUCCESS);
jsonObject.put("Content", objects);
return jsonObject.toJSONString();
}
private Map<String, Object> getWebURIStatData(String uri) {
return WebAppStatManager.getInstance().getURIStatData(uri);
}
private Map<String, Object> getWebSessionStatData(String sessionId) {
return WebAppStatManager.getInstance().getSessionStat(sessionId);
}
private Map<String, Object> getSpringMethodStatData(String clazz, String method) {
return SpringStatManager.getInstance().getMethodStatData(clazz, method);
}
private List<Map<String, Object>> getWebSessionStatDataList(Map<String, String> parameters) {
List<Map<String, Object>> array = WebAppStatManager.getInstance().getSessionStatData();
return comparatorOrderBy(array, parameters);
}
private List<Map<String, Object>> getWebAppStatDataList(Map<String, String> parameters) {
List<Map<String, Object>> array = WebAppStatManager.getInstance().getWebAppStatData();
return comparatorOrderBy(array, parameters);
}
/**
* 获取sql详情
* @param id
* @param serviceId consul获取的服务id
* @return
*/
private String getSqlStat(Integer id, String serviceId) {
log.info("serviceId:{}", serviceId);
ServiceNode serviceNode = serviceIdMap.get(serviceId);
String url = "http://" + serviceNode.getAddress() + ":" + serviceNode.getPort() + "/druid/sql-" + id + ".json";
SqlDetailResult sqlDetailResult = JSONObject.parseObject(HttpUtil.get(url), SqlDetailResult.class);
return JSON.toJSONString(sqlDetailResult);
}
public String getPoolingConnectionInfoByDataSourceId(Integer id, String serviceId) {
getAllServiceNodeMap();
ServiceNode serviceNode = serviceIdMap.get(serviceId);
String url = "http://" + serviceNode.getAddress() + ":" + serviceNode.getPort() + "/druid/connectionInfo-" + id
+ ".json";
ConnectionResult connectionResult = JSONObject.parseObject(HttpUtil.get(url), ConnectionResult.class);
return JSON.toJSONString(connectionResult);
}
/**
* SQL监控列表
* @param parameters
* @return
*/
@SuppressWarnings("unchecked")
public String getSqlStatDataList(Map<String, String> parameters) {
Map<String, ServiceNode> serviceAllNodeMap = getServiceAllNodeMap(parameters);
List<Map<String, Object>> arrayMap = new ArrayList<>();
for (String nodeKey : serviceAllNodeMap.keySet()) {
ServiceNode serviceNode = serviceAllNodeMap.get(nodeKey);
String serviceName = serviceNode.getServiceName();
String url = getRequestUrl(parameters, serviceNode, "/druid/sql.json");
SqlListResult sqlListResult = JSONObject.parseObject(HttpUtil.get(url), SqlListResult.class);
if (sqlListResult != null) {
List<SqlListResult.ContentBean> nodeContent = sqlListResult.getContent();
if (nodeContent != null) {
for (SqlListResult.ContentBean contentBean : nodeContent) {
contentBean.setName(serviceName);
contentBean.setAddress(serviceNode.getAddress());
contentBean.setPort(serviceNode.getPort());
contentBean.setServiceId(serviceNode.getId());
Map map = JSONObject.parseObject(JSONObject.toJSONString(contentBean), Map.class);
arrayMap.add(map);
}
}
}
}
List<Map<String, Object>> maps = comparatorOrderBy(arrayMap, parameters);
String jsonString = JSON.toJSONString(maps);
JSONArray objects = JSON.parseArray(jsonString);
JSONObject jsonObject = new JSONObject();
jsonObject.put("ResultCode", RESULT_CODE_SUCCESS);
jsonObject.put("Content", objects);
return jsonObject.toJSONString();
}
/**
* 数据源监控
* @param
* @return
*/
public String getDataSourceStatData() {
Map<String, ServiceNode> allNodeMap = getAllServiceNodeMap();
DataSourceResult lastResult = new DataSourceResult();
List<DataSourceResult.ContentBean> contentBeans = new ArrayList<>();
for (String nodeKey : allNodeMap.keySet()) {
ServiceNode serviceNode = allNodeMap.get(nodeKey);
String serviceName = serviceNode.getServiceName();
String url = "http://" + serviceNode.getAddress() + ":" + serviceNode.getPort() + "/druid/datasource.json";
DataSourceResult dataSourceResult = JSONObject.parseObject(HttpUtil.get(url), DataSourceResult.class);
if (dataSourceResult != null) {
List<DataSourceResult.ContentBean> nodeContent = dataSourceResult.getContent();
if (nodeContent != null) {
for (DataSourceResult.ContentBean contentBean : nodeContent) {
contentBean.setName(serviceName);
contentBean.setServiceId(serviceNode.getId());
}
contentBeans.addAll(nodeContent);
}
}
}
lastResult.setContent(contentBeans);
return JSON.toJSONString(lastResult);
}
/**
* 拼接url
* @param parameters
* @param serviceNode
* @param prefix
* @return
*/
private String getRequestUrl(Map<String, String> parameters, ServiceNode serviceNode, String prefix) {
StringBuilder stringBuilder = new StringBuilder("http://");
stringBuilder.append(serviceNode.getAddress());
stringBuilder.append(":");
stringBuilder.append(serviceNode.getPort());
stringBuilder.append(prefix);
stringBuilder.append("?orderBy=");
stringBuilder.append(parameters.get("orderBy"));
stringBuilder.append("&orderType=");
stringBuilder.append(parameters.get("orderType"));
stringBuilder.append("&page=");
stringBuilder.append(parameters.get("page"));
stringBuilder.append("&perPageCount=");
stringBuilder.append(parameters.get("perPageCount"));
stringBuilder.append("&");
return stringBuilder.toString();
}
/**
* 处理请求参数
* @param url
* @return
*/
public static Map<String, String> getParameters(String url) {
if (url == null || (url = url.trim()).length() == 0) {
return Collections.emptyMap();
}
String parametersStr = StringUtils.subString(url, "?", null);
if (parametersStr == null || parametersStr.length() == 0) {
return Collections.<String, String>emptyMap();
}
String[] parametersArray = parametersStr.split("&");
Map<String, String> parameters = new LinkedHashMap<String, String>();
for (String parameterStr : parametersArray) {
int index = parameterStr.indexOf("=");
if (index <= 0) {
continue;
}
String name = parameterStr.substring(0, index);
String value = parameterStr.substring(index + 1);
parameters.put(name, value);
}
return parameters;
}
private List<Map<String, Object>> comparatorOrderBy(List<Map<String, Object>> array,
Map<String, String> parameters) {
// when open the stat page before executing some sql
if (array == null || array.isEmpty()) {
return null;
}
// when parameters is null
String orderBy, orderType = null;
int page = DEFAULT_PAGE;
int perPageCount = DEFAULT_PER_PAGE_COUNT;
if (parameters == null) {
orderBy = DEFAULT_ORDERBY;
orderType = DEFAULT_ORDER_TYPE;
page = DEFAULT_PAGE;
perPageCount = DEFAULT_PER_PAGE_COUNT;
}
else {
orderBy = parameters.get("orderBy");
orderType = parameters.get("orderType");
String pageParam = parameters.get("page");
if (pageParam != null && pageParam.length() != 0) {
page = Integer.parseInt(pageParam);
}
String pageCountParam = parameters.get("perPageCount");
if (pageCountParam != null && pageCountParam.length() > 0) {
perPageCount = Integer.parseInt(pageCountParam);
}
}
// others,such as order
orderBy = orderBy == null ? DEFAULT_ORDERBY : orderBy;
orderType = orderType == null ? DEFAULT_ORDER_TYPE : orderType;
if (!ORDER_TYPE_DESC.equals(orderType)) {
orderType = ORDER_TYPE_ASC;
}
// orderby the statData array
if (orderBy.trim().length() != 0) {
array.sort(new MapComparator<>(orderBy, ORDER_TYPE_DESC.equals(orderType)));
}
// page
int fromIndex = (page - 1) * perPageCount;
int toIndex = page * perPageCount;
if (toIndex > array.size()) {
toIndex = array.size();
}
return array.subList(fromIndex, toIndex);
}
}

View File

@@ -0,0 +1,54 @@
package com.pig4cloud.pigx.monitor.service.impl;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.pig4cloud.pigx.monitor.service.RedisService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.util.*;
/**
* @author lengleng
* @date 2019-05-08
*/
@Slf4j
@Service
@AllArgsConstructor
public class RedisServiceImpl implements RedisService {
private RedisTemplate redisTemplate;
/**
* 获取内存信息
* @return
*/
@Override
public Map<String, Object> getInfo() {
Properties info = (Properties) redisTemplate.execute((RedisCallback) redisConnection -> redisConnection.info());
Properties commandStats = (Properties) redisTemplate
.execute((RedisCallback) redisConnection -> redisConnection.info("commandstats"));
Object dbSize = redisTemplate.execute((RedisCallback) redisConnection -> redisConnection.dbSize());
Map<String, Object> result = new HashMap<>(4);
result.put("info", info);
result.put("dbSize", dbSize);
result.put("time", DateUtil.format(new Date(), DatePattern.NORM_TIME_PATTERN));
List<Map<String, String>> pieList = new ArrayList<>();
commandStats.stringPropertyNames().forEach(key -> {
Map<String, String> data = new HashMap<>(4);
String property = commandStats.getProperty(key);
data.put("name", StrUtil.removePrefix(key, "cmdstat_"));
data.put("value", StrUtil.subBetween(property, "calls=", ",usec"));
pieList.add(data);
});
result.put("commandStats", pieList);
return result;
}
}

View File

@@ -0,0 +1,35 @@
package com.pig4cloud.pigx.monitor.support;
import com.alibaba.druid.support.http.ResourceServlet;
import com.pig4cloud.pigx.common.core.util.SpringContextHolder;
import com.pig4cloud.pigx.monitor.service.impl.MonitorStatService;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.ServletException;
/**
* @author linchtech
* @date 2020-09-16 11:10
**/
@Slf4j
public class MonitorViewServlet extends ResourceServlet {
private MonitorStatService monitorStatService;
public MonitorViewServlet() {
super("druid");
}
@Override
public void init() throws ServletException {
log.info("init MonitorViewServlet");
super.init();
monitorStatService = SpringContextHolder.getBean(MonitorStatService.class);
}
@Override
protected String process(String url) {
return monitorStatService.service(url);
}
}

View File

@@ -0,0 +1,29 @@
package com.pig4cloud.pigx.monitor.support;
import de.codecentric.boot.admin.server.cloud.discovery.DefaultServiceInstanceConverter;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.context.annotation.Configuration;
import java.util.Map;
import java.util.stream.Collectors;
import static java.util.Collections.emptyMap;
/**
* 针对 nacos 2.x 服务注册处理
*
* @author lengleng
* @date 2021/12/20
*/
@Configuration(proxyBeanMethods = false)
public class NacosServiceInstanceConverter extends DefaultServiceInstanceConverter {
@Override
protected Map<String, String> getMetadata(ServiceInstance instance) {
return (instance.getMetadata() != null)
? instance.getMetadata().entrySet().stream().filter((e) -> e.getKey() != null && e.getValue() != null)
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))
: emptyMap();
}
}

View File

@@ -0,0 +1,40 @@
package com.pig4cloud.pigx.monitor.support;
import de.codecentric.boot.admin.server.domain.entities.Instance;
import de.codecentric.boot.admin.server.domain.entities.InstanceRepository;
import de.codecentric.boot.admin.server.domain.events.InstanceEvent;
import de.codecentric.boot.admin.server.domain.events.InstanceStatusChangedEvent;
import de.codecentric.boot.admin.server.notify.AbstractEventNotifier;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;
/**
* @author lengleng
* @date 2019-01-23
* <p>
* 服务状态变化通知
*/
@Slf4j
@Component
public class StatusChangeNotifier extends AbstractEventNotifier {
protected StatusChangeNotifier(InstanceRepository repository) {
super(repository);
}
@Override
protected Mono<Void> doNotify(InstanceEvent event, Instance instance) {
return Mono.fromRunnable(() -> {
if (event instanceof InstanceStatusChangedEvent) {
log.info("Instance {} ({}) is {}", instance.getRegistration().getName(), event.getInstance(),
((InstanceStatusChangedEvent) event).getStatusInfo().getStatus());
}
else {
log.info("Instance {} ({}) {}", instance.getRegistration().getName(), event.getInstance(),
event.getType());
}
});
}
}

View File

@@ -0,0 +1,19 @@
server:
port: 5001
spring:
application:
name: @artifactId@
cloud:
nacos:
username: @nacos.username@
password: @nacos.password@
discovery:
server-addr: ${NACOS_HOST:pigx-register}:${NACOS_PORT:8848}
config:
server-addr: ${spring.cloud.nacos.discovery.server-addr}
config:
import:
- optional:nacos:application-@profiles.active@.yml
- optional:nacos:${spring.application.name}-@profiles.active@.yml

View File

@@ -0,0 +1,69 @@
<!doctype html>
<html>
<head>
<title>Druid ActiveConnection StackTrace</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf8" />
<link href='css/bootstrap.min.css' rel="stylesheet" />
<link href="css/style.css" type="text/css" rel="stylesheet"/>
<script type="text/javascript" src="js/jquery.min.js"></script>
<script src="js/lang.js" type="text/javascript" charset="utf8"></script>
<script src="js/common.js" type="text/javascript" charset="utf8"></script>
</head>
<body onload="init();">
<div class="container-fluid">
<h2>ActiveConnection StackTrace for Datasource
<a href="activeConnectionStackTrace-{datasourceId}.json" target="_blank">[View JSON API]</a>
</h2>
<div id="activeConnectionStackTraceDiv">
</div>
</div>
<script type="text/javascript">
function init() {
druid.common.buildHead(7);
}
$.namespace("druid.activeConnectionStackTrace");
druid.activeConnectionStackTrace = function () {
var datasourceId = druid.common.getUrlVar("datasourceId");
return {
init : function() {
druid.activeConnectionStackTrace.ajaxRequestForActiveConnectionStackTrace();
var time2=setInterval("druid.activeConnectionStackTrace.ajaxRequestForActiveConnectionStackTrace();",8000);
},
ajaxRequestForActiveConnectionStackTrace : function() {
$.ajax({
type: 'POST',
url: 'activeConnectionStackTrace-' + datasourceId + '.json',
success: function(data) {
var conntionStackTraceList = data.Content;
if (conntionStackTraceList == null)
return;
var content = [];
for ( var i = 0; i < conntionStackTraceList.length; i++) {
if (i > 0) {
content.push("<br>");
}
var conntionStackTrace = conntionStackTraceList[i];
content.push("<textarea rows='15' style='width:680px;' >");
content.push(conntionStackTrace);
content.push("</textarea>");
}
$("#activeConnectionStackTraceDiv").html(content.join(""));
},
dataType: "json"
});
}
}
}();
$(document).ready(function() {
druid.activeConnectionStackTrace.init();
});
</script>
</body>
</html>

View File

@@ -0,0 +1,84 @@
<!doctype html>
<html>
<head>
<title>Druid Stat JSON API</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf8" />
<link href='css/bootstrap.min.css' rel="stylesheet" />
<link href="css/style.css" type="text/css" rel="stylesheet"/>
<script type="text/javascript" src="js/jquery.min.js"></script>
<script src="js/lang.js" type="text/javascript" charset="utf8"></script>
<script src="js/common.js" type="text/javascript" charset="utf8"></script>
<script>
function init() {
druid.common.buildHead(8);
}
</script>
</head>
<body onload="init();">
<div class="container">
<h3>
JSON API
</h3>
<table class="table table-bordered responsive-utilities" style="background-color: #fff">
<thead>
<tr>
<th width="250px" class="td_lable">Name</th>
<th>Description</th>
</tr>
</thead>
<tr>
<td class="td_lable"><a href="basic.json" target="_blank">basic.json</a></td>
<td>basic info.</td>
</tr>
<tr>
<td class="td_lable"><a href="datasource.json" target="_blank">datasource.json</a></td>
<td>DatsSourceStat List</td>
</tr>
<tr>
<td class="td_lable">datasource-{id}.json</td>
<td>DatasourceStat for id={id},id is DatsSourceStat.ID<br />
Example: druid/datasource-1.json</td>
</tr>
<tr>
<td class="td_lable">activeConnectionStackTrace-{datasourceId}.json</td>
<td>StrackTrace for activeConnection in datasource which datasource.id={datasourceId},id is DatsSourceStat.ID<br />
Required: set removeAbandoned=true<br />
Example: druid/activeConnectionStackTrace-1.json</td>
</tr>
<tr>
<td class="td_lable"><a href="sql.json" target="_blank">sql.json</a></td>
<td>SqlStat for id={id} ,id is SqlStat.ID<br />
Example: druid/sql-1.json</td>
</tr>
<tr>
<td class="td_lable"><a href="wall.json" target="_blank">WallStat.json</a></td>
<td>WallStat List</td>
</tr>
<tr>
<td class="td_lable">wall-{id}.json</td>
<td>WallStat for id={id},id is DatsSourceStat.ID<br />
Example: druid/wall-1.json</td>
</tr>
<tr>
<td class="td_lable"><a href="basic.json" target="_blank">basic.json</a></td>
<td></td>
</tr>
<tr>
<td class="td_lable"><a href="weburi.json" target="_blank">weburi.json</a></td>
<td>
</td>
</tr>
<tr>
<td class="td_lable"><a href="websession.json" target="_blank">websession.json</a></td>
<td>
</td>
</tr>
<tr>
<td class="td_lable"> <a href="reset-all.json" target="_blank">reset-all.json</a> </td>
<td> Reset all stat </td>
</tr>
</table>
</div>
</body>
</html>

View File

@@ -0,0 +1,145 @@
<!doctype html>
<html>
<head>
<title>Druid Spring Stat</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf8"/>
<link href='css/bootstrap.min.css' rel="stylesheet"/>
<link href="css/style.css" type="text/css" rel="stylesheet"/>
<script type="text/javascript" src="js/jquery.min.js"></script>
<script src="js/lang.js" type="text/javascript" charset="utf8"></script>
<script src="js/common.js" type="text/javascript" charset="utf8"></script>
</head>
<body>
<div class="container-fluid">
<div class="row-fluid">
<div class="span12">
<h3>
Pooling Connection Info List for Datasource-<span id="datasourceId"></span>
<span class="pull-right" style="font-size: 16px; margin-right: 20px;">
<label langkey="ServiceList" class="lang" style="display: inline;" for="refreshServiceSelect">ServiceList</label>
<select id="refreshServiceSelect" class="refresh-seconds-select btn" style="width:200px;"
onchange="javascript:druid.connectionInfo.refreshService=this.options[this.options.selectedIndex].value;">
</select>
</span>
</h3>
<table id="dataTable" class="table table-bordered table-striped">
<thead>
<tr>
<th width="50">ID</th>
<th width="50" title="UseCount">UseCnt</th>
<th width="50" title="KeepAliveCheckCount">KACheckCnt</th>
<th width="150">LastActiveTime</th>
<th width="150">ConnectTime</th>
<th width="50">Holdability</th>
<th width="50" title="Transaction Isolation">TranIsolation</th>
<th width="50">AutoCommit</th>
<th width="50">ReadOnly</th>
<th>
Pscache<br/>
<table>
<thead>
<tr>
<th>sql</th>
<th width="50" title="DefaultRowPrefetch">dfRowPrefetch</th>
<th width="50">rowPrefetch</th>
<th width="50">hitCount</th>
</tr>
</thead>
</table>
</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
</div>
</div>
<script type="text/javascript">
$.namespace("druid.connectionInfo");
druid.connectionInfo = function () {
var datasourceId = druid.common.getUrlVar("datasourceId");
var serviceId = druid.common.getUrlVar("serviceId");
return {
init: function () {
$("#datasourceId").html(datasourceId);
druid.common.buildHead(1);
druid.connectionInfo.ajaxRequestForBasicInfo();
setInterval("druid.connectionInfo.ajaxRequestForBasicInfo();", 10000);
},
refreshService: '',
ajaxRequestForBasicInfo: function () {
$.ajax({
type: 'POST',
url: 'connectionInfo-' + datasourceId + '&serviceId=' + serviceId + '.json',
success: function (data) {
druid.connectionInfo.handleAjaxResult(data);
druid.lang.trigger();
},
dataType: "json"
});
},
handleAjaxResult: function (data) {
var statList = data.Content;
if (statList == null) return;
var sqlStatTable = document.getElementById("dataTable");
while (sqlStatTable.rows.length > 1) {
sqlStatTable.deleteRow(1);
}
var html = "";
for (var i = 0; i < statList.length; i++) {
var stat = statList[i];
var newRow = sqlStatTable.insertRow(-1);
html += "<tr>";
html += "<td>" + stat.connectionId + "</td>";
html += "<td>" + stat.useCount + "</td>";
html += "<td>" + stat.keepAliveCheckCount + "</td>";
if (stat.lastActiveTime)
html += "<td>" + stat.lastActiveTime + "</td>";
else
html += "<td></td>";
html += "<td>" + stat.connectTime + "</td>";
html += "<td>" + stat.holdability + "</td>";
html += "<td>" + stat.transactionIsolation + "</td>";
html += "<td>" + stat.autoCommit + "</td>";
html += "<td>" + stat.readoOnly + "</td>";
if (stat.pscache)
html += "<td>" + druid.connectionInfo.getPsCacheInfo(stat.pscache) + "</td>";
else
html += "<td></td>";
html += "</tr>";
}
$("#dataTable tbody").html(html);
druid.common.stripes();
},
getPsCacheInfo: function (pscache) {
var result = '<table cellspacing="1" cellpadding="5" width="100%">';
for (var i = 0; i < pscache.length; i++) {
var stmt = pscache[i];
result += '<tr>';
result += '<td>' + stmt.sql + "</td>";
result += '<td width="50">' + stmt.defaultRowPrefetch + "</td>";
result += '<td width="50">' + stmt.rowPrefetch + "</td>";
result += '<td width="50">' + stmt.hitCount + "</td>";
result += '</tr>';
}
result += "</table>";
return result;
}
}
}();
$(document).ready(function () {
druid.connectionInfo.init();
});
</script>
</body>
</html>

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,57 @@
body{
font-size:12px;
padding-top: 60px;
padding-bottom: 40px;
}
a {
cursor:pointer;
}
#dataTable th > a {
color: #555555;
}
#dataTable th {
background-color: #E5E5E5;
border-bottom-color: #FFC40D;
color: #555555;
cursor: pointer;
}
.footer {
background-color: #F5F5F5;
border-top: 1px solid #E5E5E5;
margin-top: 10px;
padding: 20px 0;
}
.td_lable {
font-weight: bold;
width: 220px;
background-color: #E5E5E5;
}
.striped {
background-color: #fff;
}
#dataTable1 th > a {
color: #555555;
}
#dataTable1 th {
background-color: #E5E5E5;
border-bottom-color: #FFC40D;
color: #555555;
cursor: pointer;
}
#dataTable2 th > a {
color: #555555;
}
#dataTable2 th {
background-color: #E5E5E5;
border-bottom-color: #FFC40D;
color: #555555;
cursor: pointer;
}

View File

@@ -0,0 +1,448 @@
<!doctype html>
<html>
<head>
<title>Druid DataSourceStat</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf8" />
<link href='css/bootstrap.min.css' rel="stylesheet" />
<link href="css/style.css" type="text/css" rel="stylesheet"/>
<script src="js/doT.js" type="text/javascript" charset="utf8"></script>
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript" src="js/bootstrap.min.js"></script>
<script src="js/lang.js" type="text/javascript" charset="utf8"></script>
<script src="js/common.js" type="text/javascript" charset="utf8"></script>
</head>
<body>
<div class="container-fluid">
<div class="row-fluid">
<div class="span12">
<h3>
DataSourceStat List
<a href="datasource.json" target="_blank">View JSON API</a>
</h3>
<div class="alert alert-error clearfix" style="margin-bottom: 5px;width: 195px; padding: 2px 15px 2px 10px;">(*) property for user to setup</div>
</div>
</div>
</div>
<script id="datasource-tmpl" type="text/template">
<ul class="nav nav-tabs" id="datasourceTab">
{{~ it.Content :datasourceNow:i }}
<li class="{{=i==0?'active':''}}" id="datasourceTab-li-{{=i}}">
<a href="datasource.html#dstab{{=datasourceNow.Identity}}">{{=datasourceNow.Name}}</a>
</li>
{{~ }}
</ul>
<div class="tab-content">
{{~ it.Content :datasourceNow:i }}
<div class="tab-pane {{=i==0?'active':''}}" id="dstab{{=datasourceNow.Identity}}">
<h4>
Basic Info For {{=datasourceNow.Name}}<a href="datasource-{{=datasourceNow.Identity}}.json" target="_blank" >View JSON API</a>
</h4>
<table class="table table-bordered" style="background-color: #fff">
<tbody>
<tr>
<td valign="top" class="td_lable" > * <span class="lang" langKey="UserName">UserName</span></td>
<td>{{=datasourceNow.UserName}}</td>
<td class="lang" langKey="UserNameDesc">Specify the username used when creating a new connection.</td>
</tr>
<tr>
<td valign="top" class="td_lable" > * <span class="lang" langKey="URL">URL</span></td>
<td>{{=datasourceNow.URL}}</td>
<td class="lang" langKey="URLDesc">The JDBC driver connection URL</td>
</tr>
<tr>
<td valign="top" class="td_lable" > * <span class="lang" langKey="DbType">DbType</span></td>
<td>{{=datasourceNow.DbType}}</td>
<td class="lang" langKey="DbTypeDesc">database type</td>
</tr>
<tr>
<td valign="top" class="td_lable" > * <span class="lang" langKey="DriverClassName">DriverClassName</span></td>
<td>{{=datasourceNow.DriverClassName}}</td>
<td class="lang" langKey="DriverClassNameDesc">The fully qualifed name of the JDBC driver class</td>
</tr>
<tr>
<td valign="top" class="td_lable" > * <span class="lang" langKey="FilterClassNames">FilterClassNames</span></td>
<td>{{=datasourceNow.FilterClassNames}}</td>
<td class="lang" langKey="FilterClassNamesDesc">All the fully qualifed name of the filter classes</td>
</tr>
<tr>
<td valign="top" class="td_lable" > * <span class="lang" langKey="TestOnBorrow">TestOnBorrow</span></td>
<td>{{=datasourceNow.TestOnBorrow}}</td>
<td class="lang" langKey="TestOnBorrowDesc"> Test or not when borrow a connection</td>
</tr>
<tr>
<td valign="top" class="td_lable" > * <span class="lang" langKey="TestWhileIdle">TestWhileIdle</span></td>
<td>{{=datasourceNow.TestWhileIdle}}</td>
<td class="lang" langKey="TestWhileIdleDesc">Test or not when a connection is idle for a while</td>
</tr>
<tr>
<td valign="top" class="td_lable" > * <span class="lang" langKey="TestOnReturn">TestOnReturn</span></td>
<td>{{=datasourceNow.TestOnReturn}}</td>
<td class="lang" langKey="TestOnReturnDesc">Test or not when return a connection</td>
</tr>
<tr>
<td valign="top" class="td_lable" > * <span class="lang" langKey="InitialSize">InitialSize</span></td>
<td>{{=datasourceNow.InitialSize}}</td>
<td class="lang" langKey="InitialSizeDesc">The size of datasource connections to create when initial a datasource</td>
</tr>
<tr>
<td valign="top" class="td_lable" > * <span class="lang" langKey="MinIdle">MinIdle</span></td>
<td>{{=datasourceNow.MinIdle}}</td>
<td class="lang" langKey="MinIdleDesc">The minimum number of connections a pool should hold. </td>
</tr>
<tr>
<td valign="top" class="td_lable" > * <span class="lang" langKey="MaxActive">MaxActive</span></td>
<td>{{=datasourceNow.MaxActive}}</td>
<td class="lang" langKey="MaxActiveDesc">The maximum number of connections for a pool</td>
</tr>
<tr>
<td valign="top" class="td_lable" > * <span class="lang" langKey="QueryTimeout">QueryTimeout</span></td>
<td>{{=datasourceNow.QueryTimeout}}</td>
<td class="lang" langKey="QueryTimeoutDesc"></td>
</tr>
<tr>
<td valign="top" class="td_lable" > * <span class="lang" langKey="TransactionQueryTimeout">TransactionQueryTimeout</span></td>
<td>{{=datasourceNow.TransactionQueryTimeout}}</td>
<td class="lang" langKey="TransactionQueryTimeoutDesc"></td>
</tr>
<tr>
<td valign="top" class="td_lable" > * <span class="lang" langKey="LoginTimeout">LoginTimeout</span></td>
<td>{{=datasourceNow.LoginTimeout}}</td>
<td class="lang" langKey="LoginTimeoutDesc"></td>
</tr>
<tr>
<td valign="top" class="td_lable" > * <span class="lang" langKey="ValidConnectionCheckerClassName">ValidConnectionCheckerClassName</span></td>
<td>{{=datasourceNow.ValidConnectionCheckerClassName}}</td>
<td class="lang" langKey="ValidConnectionCheckerClassNameDesc"></td>
</tr>
<tr>
<td valign="top" class="td_lable" > * <span class="lang" langKey="ExceptionSorterClassName">ExceptionSorterClassName</span></td>
<td>{{=datasourceNow.ExceptionSorterClassName}}</td>
<td class="lang" langKey="ExceptionSorterClassNameDesc"></td>
</tr>
<tr>
<td valign="top" class="td_lable" > * <span class="lang" langKey="DefaultAutoCommit">DefaultAutoCommit</span></td>
<td>{{=datasourceNow.DefaultAutoCommit}}</td>
<td class="lang" langKey="DefaultAutoCommitDesc"></td>
</tr>
<tr>
<td valign="top" class="td_lable" > * <span class="lang" langKey="DefaultReadOnly">DefaultReadOnly</span></td>
<td>{{=datasourceNow.DefaultReadOnly}}</td>
<td class="lang" langKey="DefaultReadOnlyDesc"></td>
</tr>
<tr>
<td valign="top" class="td_lable" > * <span class="lang" langKey="DefaultTransactionIsolation">DefaultTransactionIsolation</span></td>
<td>{{=datasourceNow.DefaultTransactionIsolation}}</td>
<td class="lang" langKey="DefaultTransactionIsolationDesc"></td>
</tr>
<tr>
<td valign="top" class="td_lable" > * <span class="lang" langKey="MinEvictableIdleTimeMillis">MinEvictableIdleTimeMillis</span></td>
<td>{{=datasourceNow.MinEvictableIdleTimeMillis}}</td>
<td class="lang" langKey="MinEvictableIdleTimeMillis"></td>
</tr>
<tr>
<td valign="top" class="td_lable" > * <span class="lang" langKey="MaxEvictableIdleTimeMillis">MaxEvictableIdleTimeMillis</span></td>
<td>{{=datasourceNow.MaxEvictableIdleTimeMillis}}</td>
<td class="lang" langKey="MaxEvictableIdleTimeMillis"></td>
</tr>
<tr>
<td valign="top" class="td_lable" > * <span class="lang" langKey="KeepAlive">KeepAlive</span></td>
<td>{{=datasourceNow.KeepAlive}}</td>
<td class="lang" langKey="KeepAlive"></td>
</tr>
<tr>
<td valign="top" class="td_lable" > * <span class="lang" langKey="FailFast">FailFast</span></td>
<td>{{=datasourceNow.FailFast}}</td>
<td class="lang" langKey="FailFast"></td>
</tr>
<tr>
<td valign="top" class="td_lable" > * <span class="lang" langKey="PoolPreparedStatements">PoolPreparedStatements</span></td>
<td>{{=datasourceNow.PoolPreparedStatements}}</td>
<td class="lang" langKey="PoolPreparedStatements"></td>
</tr>
<tr>
<td valign="top" class="td_lable" > * <span class="lang" langKey="MaxPoolPreparedStatementPerConnectionSize">MaxPoolPreparedStatementPerConnectionSize</span></td>
<td>{{=datasourceNow.MaxPoolPreparedStatementPerConnectionSize}}</td>
<td class="lang" langKey="MaxPoolPreparedStatementPerConnectionSize"></td>
</tr>
<tr>
<td valign="top" class="td_lable" > * <span class="lang" langKey="MaxWait">MaxWait</span></td>
<td>{{=datasourceNow.MaxWait}}</td>
<td class="lang" langKey="MaxWait"></td>
</tr>
<tr>
<td valign="top" class="td_lable" > * <span class="lang" langKey="MaxWaitThreadCount">MaxWaitThreadCount</span></td>
<td>{{=datasourceNow.MaxWaitThreadCount}}</td>
<td class="lang" langKey="MaxWaitThreadCount"></td>
</tr>
<tr>
<td valign="top" class="td_lable" > * <span class="lang" langKey="LogDifferentThread">LogDifferentThread</span></td>
<td>{{=datasourceNow.LogDifferentThread}}</td>
<td class="lang" langKey="LogDifferentThread"></td>
</tr>
<tr>
<td valign="top" class="td_lable" > * <span class="lang" langKey="UseUnfairLock">UseUnfairLock</span></td>
<td>{{=datasourceNow.UseUnfairLock}}</td>
<td class="lang" langKey="UseUnfairLock"></td>
</tr>
<tr>
<td valign="top" class="td_lable" > * <span class="lang" langKey="InitGlobalVariants">InitGlobalVariants</span></td>
<td>{{=datasourceNow.InitGlobalVariants}}</td>
<td class="lang" langKey="InitGlobalVariants"></td>
</tr>
<tr>
<td valign="top" class="td_lable" > * <span class="lang" langKey="InitVariants">InitVariants</span></td>
<td>{{=datasourceNow.InitVariants}}</td>
<td class="lang" langKey="InitVariants"></td>
</tr>
<tr>
<td valign="top" class="td_lable" > <span class="lang" langKey="NotEmptyWaitCount">NotEmptyWaitCount</span></td>
<td>{{=datasourceNow.NotEmptyWaitCount}}</td>
<td class="lang" langKey="NotEmptyWaitCountDesc">Total times for wait to get a connection</td>
</tr>
<tr>
<td valign="top" class="td_lable" > <span class="lang" langKey="NotEmptyWaitMillis">NotEmptyWaitMillis</span></td>
<td>{{=datasourceNow.NotEmptyWaitMillis}}</td>
<td class="lang" langKey="NotEmptyWaitMillisDesc">Total millins for wait to get a connection</td>
</tr>
<tr>
<td valign="top" class="td_lable" > <span class="lang" langKey="WaitThreadCount">WaitThreadCount</span></td>
<td>{{=datasourceNow.WaitThreadCount}}</td>
<td class="lang" langKey="WaitThreadCountDesc">The current waiting thread count</td>
</tr>
<tr>
<td valign="top" class="td_lable" > <span class="lang" langKey="StartTransactionCount">StartTransactionCount</span></td>
<td>{{=datasourceNow.StartTransactionCount}}</td>
<td class="lang" langKey="StartTransactionCountDesc">The count of start transaction</td>
</tr>
<tr>
<td valign="top" class="td_lable" > <span class="lang" langKey="TransactionHistogram">TransactionHistogram</span></td>
<td>{{=datasourceNow.TransactionHistogram}}</td>
<td class="lang" langKey="TransactionHistogramDesc">The histogram values of transaction time, [0-1 ms, 1-10 ms, 10-100 ms, 100-1 s, 1-10 s, 10-100 s, >100 s]</td>
</tr>
<tr>
<td valign="top" class="td_lable" > <span class="lang" langKey="PoolingCount">PoolingCount</span></td>
<td>{{=datasourceNow.PoolingCount}}</td>
<td class="lang" langKey="PoolingCountDesc">The current usefull connection count</td>
</tr>
<tr>
<td valign="top" class="td_lable" > <span class="lang" langKey="PoolingPeak">PoolingPeak</span></td>
<td>{{=datasourceNow.PoolingPeak}}</td>
<td class="lang" langKey="PoolingPeakDesc">The usefull connection peak count</td>
</tr>
<tr>
<td valign="top" class="td_lable" > <span class="lang" langKey="PoolingPeakTime">PoolingPeakTime</span></td>
<td>{{=datasourceNow.PoolingPeakTime}}</td>
<td class="lang" langKey="PoolingPeakTimeDesc">The usefull connection peak time</td>
</tr>
<tr>
<td valign="top" class="td_lable" > <span class="lang" langKey="ActiveCount">ActiveCount</span></td>
<td>{{=datasourceNow.ActiveCount}}</td>
<td class="lang" langKey="ActiveCountDesc">The current active connection count</td>
</tr>
<tr>
<td valign="top" class="td_lable" > <span class="lang" langKey="ActivePeak">ActivePeak</span></td>
<td>{{=datasourceNow.ActivePeak}}</td>
<td class="lang" langKey="ActivePeakDesc">The current active connection peak count</td>
</tr>
<tr>
<td valign="top" class="td_lable" > <span class="lang" langKey="ActivePeakTime">ActivePeakTime</span></td>
<td>{{=datasourceNow.ActivePeakTime}}</td>
<td class="lang" langKey="ActivePeakTimeDesc">The active connection peak time</td>
</tr>
<tr>
<td valign="top" class="td_lable" > <span class="lang" langKey="LogicConnectCount">LogicConnectCount</span></td>
<td>{{=datasourceNow.LogicConnectCount}}</td>
<td class="lang" langKey="LogicConnectCountDesc">Total connect times from datasource</td>
</tr>
<tr>
<td valign="top" class="td_lable" > <span class="lang" langKey="LogicCloseCount">LogicCloseCount</span></td>
<td>{{=datasourceNow.LogicCloseCount}}</td>
<td class="lang" langKey="LogicCloseCountDesc">Total close connect times from datasource</td>
</tr>
<tr>
<td valign="top" class="td_lable" > <span class="lang" langKey="LogicConnectErrorCount">LogicConnectErrorCount</span></td>
<td>{{=datasourceNow.LogicConnectErrorCount}}</td>
<td class="lang" langKey="LogicConnectErrorCountDesc">Total connect error times</td>
</tr>
<tr>
<td valign="top" class="td_lable" > <span class="lang" langKey="DiscardCount">DiscardCount</span></td>
<td>{{=datasourceNow.DiscardCount}}</td>
<td class="lang" langKey="DiscardCountDesc">Discard connection count with validate fail </td>
</tr>
<tr>
<td valign="top" class="td_lable" > <span class="lang" langKey="RecycleErrorCount">RecycleErrorCount</span></td>
<td>{{=datasourceNow.RecycleErrorCount}}</td>
<td class="lang" langKey="RecycleErrorCount">Total connect error times</td>
</tr>
<tr>
<td valign="top" class="td_lable" > <span class="lang" langKey="PhysicalConnectCount">PhysicalConnectCount</span></td>
<td>{{=datasourceNow.PhysicalConnectCount}}</td>
<td class="lang" langKey="PhysicalConnectCountDesc">Create physical connnection count</td>
</tr>
<tr>
<td valign="top" class="td_lable" > <span class="lang" langKey="PhysicalCloseCount">PhysicalCloseCount</span></td>
<td>{{=datasourceNow.PhysicalCloseCount}}</td>
<td class="lang" langKey="PhysicalCloseCountDesc">Close physical connnection count</td>
</tr>
<tr>
<td valign="top" class="td_lable" > <span class="lang" langKey="PhysicalConnectErrorCount">PhysicalConnectErrorCount</span></td>
<td>{{=datasourceNow.PhysicalConnectErrorCount}}</td>
<td class="lang" langKey="PhysicalConnectErrorCountDesc">Total physical connect error times</td>
</tr>
<tr>
<td valign="top" class="td_lable" > <span class="lang" langKey="ExecuteCount">ExecuteCount</span></td>
<td>{{=datasourceNow.ExecuteCount}}</td>
<td class="lang" langKey="ExecuteCountDesc">Total Execute Count</td>
</tr>
<tr>
<td valign="top" class="td_lable" > <span class="lang" langKey="ExecuteQueryCount">ExecuteQueryCount</span></td>
<td>{{=datasourceNow.ExecuteQueryCount}}</td>
<td class="lang" langKey="ExecuteQueryCountDesc"></td>
</tr>
<tr>
<td valign="top" class="td_lable" > <span class="lang" langKey="ExecuteUpdateCount">ExecuteUpdateCount</span></td>
<td>{{=datasourceNow.ExecuteUpdateCount}}</td>
<td class="lang" langKey="ExecuteUpdateCountDesc"></td>
</tr>
<tr>
<td valign="top" class="td_lable" > <span class="lang" langKey="ExecuteBatchCount">ExecuteBatchCount</span></td>
<td>{{=datasourceNow.ExecuteBatchCount}}</td>
<td class="lang" langKey="ExecuteBatchCountDesc"></td>
</tr>
<tr>
<td valign="top" class="td_lable" > <span class="lang" langKey="ErrorCount">ErrorCount</span></td>
<td>{{=datasourceNow.ErrorCount}}</td>
<td class="lang" langKey="ErrorCountDesc"></td>
</tr>
<tr>
<td valign="top" class="td_lable" > <span class="lang" langKey="CommitCount">CommitCount</span></td>
<td>{{=datasourceNow.CommitCount}}</td>
<td class="lang" langKey="CommitCountDesc"></td>
</tr>
<tr>
<td valign="top" class="td_lable" > <span class="lang" langKey="RollbackCount">RollbackCount</span></td>
<td>{{=datasourceNow.RollbackCount}}</td>
<td class="lang" langKey="RollbackCountDesc"></td>
</tr>
<tr>
<td valign="top" class="td_lable" > <span class="lang" langKey="PreparedStatementOpenCount">PSOpenCount</span></td>
<td>{{=datasourceNow.PreparedStatementOpenCount}}</td>
<td class="lang" langKey="PreparedStatementOpenCount"></td>
</tr>
<tr>
<td valign="top" class="td_lable" > <span class="lang" langKey="PreparedStatementClosedCount">PSClosedCount</span></td>
<td>{{=datasourceNow.PreparedStatementClosedCount}}</td>
<td class="lang" langKey="PreparedStatementClosedCount"></td>
</tr>
<tr>
<td valign="top" class="td_lable" > <span class="lang" langKey="PSCacheAccessCount">PSCacheAccessCount</span></td>
<td>{{=datasourceNow.PSCacheAccessCount}}</td>
<td class="lang" langKey="PSCacheAccessCountDesc">PerpareStatement access count</td>
</tr>
<tr>
<td valign="top" class="td_lable" > <span class="lang" langKey="PSCacheHitCount">PSCacheHitCount</span></td>
<td>{{=datasourceNow.PSCacheHitCount}}</td>
<td class="lang" langKey="PSCacheHitCountDesc">PerpareStatement hit count</td>
</tr>
<tr>
<td valign="top" class="td_lable" > <span class="lang" langKey="PSCacheMissCount">PSCacheMissCount</span></td>
<td>{{=datasourceNow.PSCacheMissCount}}</td>
<td class="lang" langKey="PSCacheMissCountDesc">PerpareStatement miss count</td>
</tr>
<tr>
<td valign="top" class="td_lable" > <span class="lang" langKey="ConnectionHoldTimeHistogram">ConnectionHoldTimeHistogram</span></td>
<td>{{=datasourceNow.ConnectionHoldTimeHistogram}}</td>
<td class="lang" langKey="ConnectionHoldTimeHistogramDesc">The histogram values of connection hold time, [0-1 ms, 1-10 ms, 10-100 ms, 100ms-1s, 1-10 s, 10-100 s, 100-1000 s, >1000 s]</td>
</tr>
<tr>
<td valign="top" class="td_lable" > <span class="lang" langKey="ClobOpenCount">ClobOpenCount</span></td>
<td>{{=datasourceNow.ClobOpenCount}}</td>
<td class="lang" langKey="ClobOpenCountDesc"></td>
</tr>
<tr>
<td valign="top" class="td_lable" > <span class="lang" langKey="BlobOpenCount">BlobOpenCount</span></td>
<td>{{=datasourceNow.BlobOpenCount}}</td>
<td class="lang" langKey="BlobOpenCountDesc"></td>
</tr>
<tr>
<td valign="top" class="td_lable" > <span class="lang" langKey="KeepAliveCheckCount">KeepAliveCheckCount</span></td>
<td>{{=datasourceNow.KeepAliveCheckCount}}</td>
<td class="lang" langKey="KeepAliveCheckCount"></td>
</tr>
<tr>
<td valign="top" class="td_lable"><span class="lang" langKey="ActiveConnectionStackTrace">ActiveConnection StackTrace</span></td>
<td>
<a href="activeConnectionStackTrace.html?datasourceId={{=datasourceNow.Identity}}">View</a>
</td>
<td>
StackTrace for active Connection.
<a href="activeConnectionStackTrace-{{=datasourceNow.Identity}}.json" target="_blank">[View JSON API]</a>
</td>
</tr>
<tr>
<td valign="top" class="td_lable"><span class="lang" langKey="PollingConnectionInfo">PollingConnection Info</span></td>
<td>
<a href="connectionInfo.html?datasourceId={{=datasourceNow.Identity}}&serviceId={{=datasourceNow.serviceId}}">View</a>
</td>
<td>
Info for polling connection.
<a href="connectionInfo-{{=datasourceNow.Identity}}.json" target="_blank">[View JSON API]</a>
</td>
</tr>
<tr>
<td valign="top" class="td_lable"><span class="lang" langKey="SQLList">SQL List</span></td>
<td>
<a href="sql.html?dataSourceId={{=datasourceNow.Identity}}">View</a>
</td>
<td>
Info for SQL.
<a href="sql.json?dataSourceId={{=datasourceNow.Identity}}" target="_blank">[View JSON API]</a>
</td>
</tr>
</tbody>
</table>
</div>
{{~ }}
</div>
</script>
<script type="text/javascript">
$.namespace("druid.datasource");
druid.datasource = function () {
return {
init : function() {
druid.common.buildHead(1);
this.ajaxRequestForBasicInfo();
},
ajaxRequestForBasicInfo : function() {
$.ajax({
type: 'POST',
url: "datasource.json",
success: function(data) {
var tmpl = $('#datasource-tmpl').html();
var doTtmpl = doT.template(tmpl);
var contentHtml = doTtmpl(data);
$(".span12 h3").after(contentHtml);
$('#datasourceTab a').click(function (e) {
e.preventDefault();
$(this).tab('show');
});
druid.lang.trigger();
},
dataType: "json"
});
}
}
}();
$(document).ready(function() {
druid.datasource.init();
});
</script>
</body>
</html>

View File

@@ -0,0 +1,25 @@
<div style="float:right;margin-right:20px;">
<a class="langSelector" langNow="0">English</a> | <a class="langSelector" langNow="1">中文</a>
</div>
<div class="navbar navbar-fixed-top">
<div class="navbar-inner">
<div class="container">
<a href="https://github.com/alibaba/druid/wiki" target="_blank" class="brand lang" langKey="">Druid Monitor</a>
<div class="nav-collapse">
<ul class="nav">
<li><a href="index.html" class="lang" langKey="Index">Index</a></li>
<li><a href="datasource.html" class="lang" langKey="DataSource">DataSource</a></li>
<li><a href="sql.html" class="lang" langKey="SQL">SQL</a></li>
<li><a href="wall.html" class="lang" langKey="Wall">Wall</a></li>
<li><a href="webapp.html" class="lang" langKey="WebApp">WebApp</a></li>
<li><a href="weburi.html" class="lang" langKey="WebURI">WebURI</a></li>
<li><a href="websession.html" class="lang" langKey="Web Session">Web Session</a></li>
<li><a href="spring.html" class="lang" langKey="Spring">Spring</a></li>
<li><a href="api.html" class="lang" langKey="JSON API">JSON API</a></li>
</ul>
<a langKey="ResetAll" class="btn btn-primary lang" href="javascript:druid.common.ajaxRequestForReset();">Reset All</a>
<a langKey="LogAndReset" class="btn btn-primary lang" href="javascript:druid.common.ajaxRequestForLogAndReset();">Log And Reset</a>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,100 @@
<!doctype html>
<html>
<head>
<title class="lang" langKey="xxxx">Druid Stat Index</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf8" />
<link href='css/bootstrap.min.css' rel="stylesheet" />
<link href="css/style.css" type="text/css" rel="stylesheet"/>
<script type="text/javascript" src="js/jquery.min.js"></script>
<script src="js/lang.js" type="text/javascript" charset="utf8"></script>
<script src="js/common.js" type="text/javascript" charset="utf8"></script>
</head>
<body>
<div class="container">
<h3>
Stat Index
<a href="basic.json" target="_blank" class="lang" langKey="ViewJSONAPI">View JSON API</a>
</h3>
<table id="dataTable" style="background-color: #fff" class="table table-bordered responsive-utilities">
<tr >
<td valign="top" width="100" class="td_lable lang" langKey="Version">
Version
</td>
<td id="DruidVersion" width="95%"></td>
</tr>
<tr >
<td valign="top" class="td_lable lang" langKey="Drivers"> Drivers </td>
<td id="DruidDrivers"> </td>
</tr>
<tr >
<td valign="top" class="td_lable lang" langKey="ResetEnable"> ResetEnable </td>
<td id="ResetEnable"></td>
</tr>
<tr >
<td valign="top" class="td_lable lang" langKey="ResetCount"> ResetCount </td>
<td id="ResetCount"></td>
</tr>
<tr >
<td valign="top" class="td_lable lang" langKey="JavaVersion"> JavaVersion </td>
<td id="JavaVersion"></td>
</tr>
<tr >
<td valign="top" class="td_lable lang" langKey="JavaVMName"> JavaVMName </td>
<td id="JavaVMName"></td>
</tr>
<tr>
<td valign="top" class="td_lable lang" langKey="JavaClassPath"> JavaClassPath </td>
<td id="JavaClassPath"></td>
</tr>
<tr >
<td valign="top" class="td_lable lang" langKey="StartTime"> StartTime </td>
<td id="StartTime"></td>
</tr>
</table>
</div>
<script type="text/javascript">
$.namespace("druid.index");
druid.index = function () {
return {
init : function() {
druid.common.buildHead(0);
this.ajaxRequestForBasicInfo();
},
ajaxRequestForBasicInfo : function() {
$.ajax({
type: 'POST',
url: "basic.json",
success: function(data) {
$("#DruidVersion").text(data.Content.Version)
var driversList = data.Content.Drivers;
if (driversList) {
var driverHtml = '';
for ( var i = 0; i < driversList.length; i++) {
var driver = driversList[i];
driverHtml += driver + '<br/>';
}
$("#DruidDrivers").html(driverHtml);
}
$("#ResetEnable").text(data.Content.ResetEnable)
$("#ResetCount").text(data.Content.ResetCount)
$("#JavaVersion").text(data.Content.JavaVersion)
$("#JavaVMName").text(data.Content.JavaVMName)
$("#JavaClassPath").html(data.Content.JavaClassPath.split(/;|:/).join("<br/>"))
$("#StartTime").text(data.Content.StartTime)
druid.lang.trigger();
},
dataType: "json"
});
}
}
}();
$(document).ready(function() {
druid.index.init();
});
</script>
</body>
</html>

View File

@@ -0,0 +1,7 @@
/**
* Bootstrap.js by @fat & @mdo
* plugins: bootstrap-tab.js
* Copyright 2012 Twitter, Inc.
* http://www.apache.org/licenses/LICENSE-2.0.txt
*/
!function(a){var b=function(b){this.element=a(b)};b.prototype={constructor:b,show:function(){var b=this.element,c=b.closest("ul:not(.dropdown-menu)"),d=b.attr("data-target"),e,f,g;d||(d=b.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,""));if(b.parent("li").hasClass("active"))return;e=c.find(".active a").last()[0],g=a.Event("show",{relatedTarget:e}),b.trigger(g);if(g.isDefaultPrevented())return;f=a(d),this.activate(b.parent("li"),c),this.activate(f,f.parent(),function(){b.trigger({type:"shown",relatedTarget:e})})},activate:function(b,c,d){function g(){e.removeClass("active").find("> .dropdown-menu > .active").removeClass("active"),b.addClass("active"),f?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu")&&b.closest("li.dropdown").addClass("active"),d&&d()}var e=c.find("> .active"),f=d&&a.support.transition&&e.hasClass("fade");f?e.one(a.support.transition.end,g):g(),e.removeClass("in")}},a.fn.tab=function(c){return this.each(function(){var d=a(this),e=d.data("tab");e||d.data("tab",e=new b(this)),typeof c=="string"&&e[c]()})},a.fn.tab.Constructor=b,a(function(){a("body").on("click.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"]',function(b){b.preventDefault(),a(this).tab("show")})})}(window.jQuery)

View File

@@ -0,0 +1,216 @@
$.namespace("druid.common");
druid.common = function () {
var statViewOrderBy = '';
var statViewOrderBy_old = '';
var statViewOrderType = 'asc';
var isOrderRequest = false;
// only one page for now
var sqlViewPage = 1;
var sqlViewPerPageCount = 1000000;
return {
init: function () {
this.buildFooter();
druid.lang.init();
},
buildHead: function (index) {
$.get('header.html', function (html) {
$(document.body).prepend(html);
druid.lang.trigger();
$(".navbar .nav li").eq(index).addClass("active");
}, "html");
},
getService: function () {
$.ajax({
type: "GET",
url: "serviceList.json",
async:false,
success: function (data) {
let serviceList = JSON.parse(data);
for (var i in serviceList) {
$("#refreshServiceSelect").append("<option value="+serviceList[i]+">" + serviceList[i] + "</option>");
}
$("#refreshServiceSelect option").first().attr("selected",true);
}
});
},
buildFooter: function () {
var html = '<footer class="footer">' +
' <div class="container">' +
' </div>' +
' </footer>';
$(document.body).append(html);
},
ajaxRequestForReset: function () {
if (!confirm("Are you sure to reset all stat? It'll clear all stat data !")) {
return;
}
$.ajax({
type: 'POST',
url: "reset-all.json",
success: function (data) {
if (data.ResultCode == 1) {
alert("already reset all stat");
}
},
dataType: "json"
});
},
ajaxRequestForLogAndReset: function () {
if (!confirm("Are you sure to reset data source stat? It'll clear and log all stat data !")) {
return;
}
$.ajax({
type: 'POST',
url: "log-and-reset.json",
success: function (data) {
if (data.ResultCode == 1) {
alert("already reset all stat");
}
},
dataType: "json"
});
},
getAjaxUrl: function (uri) {
var result = uri;
if (statViewOrderBy != undefined)
result += 'orderBy=' + statViewOrderBy + '&';
if (statViewOrderType != undefined)
result += 'orderType=' + statViewOrderType + '&';
if (sqlViewPage != undefined)
result += 'page=' + sqlViewPage + '&';
if (sqlViewPerPageCount != undefined)
result += 'perPageCount=' + sqlViewPerPageCount + '&';
return result;
},
resetSortMark: function () {
var divObj = document.getElementById('th-' + statViewOrderBy);
var old_divObj = document.getElementById('th-' + statViewOrderBy_old);
var replaceToStr = '';
if (old_divObj) {
var html = old_divObj.innerHTML;
if (statViewOrderBy_old.indexOf('[') > 0)
replaceToStr = '-';
html = html.replace('▲', replaceToStr);
html = html.replace('▼', replaceToStr);
old_divObj.innerHTML = html
}
if (divObj) {
var html = divObj.innerHTML;
if (statViewOrderBy.indexOf('[') > 0)
html = '';
if (statViewOrderType == 'asc') {
html += '▲';
} else if (statViewOrderType == 'desc') {
html += '▼';
}
divObj.innerHTML = html;
}
isOrderRequest = true;
this.ajaxRequestForBasicInfo();
return false;
},
setOrderBy: function (orderBy) {
if (statViewOrderBy != orderBy) {
statViewOrderBy_old = statViewOrderBy;
statViewOrderBy = orderBy;
statViewOrderType = 'desc';
druid.common.resetSortMark();
return;
}
statViewOrderBy_old = statViewOrderBy;
if (statViewOrderType == 'asc')
statViewOrderType = 'desc'
else
statViewOrderType = 'asc';
druid.common.resetSortMark();
},
ajaxuri: "",
handleCallback: null,
handleAjaxResult: function (data) {
druid.common.handleCallback(data);
if (!isOrderRequest) {
druid.lang.trigger();
}
},//ajax 处理函数
ajaxRequestForBasicInfo: function () {
$.ajax({
type: 'POST',
url: druid.common.getAjaxUrl(druid.common.ajaxuri),
success: function (data) {
druid.common.handleAjaxResult(data);
},
dataType: "json"
});
},
subSqlString: function (sql, len) {
if (sql == undefined || sql == null) {
return '';
}
if (sql.length <= len)
return sql;
return sql.substr(0, len) + '...';
},
stripes: function () {
$("#dataTable tbody tr").each(function () {
$(this).removeClass("striped");
});
$("#dataTable tbody tr:even").each(function () {
$(this).addClass("striped");
});
},
getUrlVar: function (name) {
var vars = {};
var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function (m, key, value) {
vars[key] = value;
});
return vars[name];
}
}
}();
$(document).ready(function () {
druid.common.init();
});
function replace(data) {
if ((!data) || data === undefined) {
return '';
} else {
return format(data);
}
}
function format(s) {
var str = s += '';
return str.replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,");
}

View File

@@ -0,0 +1,135 @@
// doT.js
// 2011, Laura Doktorova, https://github.com/olado/doT
// Licensed under the MIT license.
(function() {
"use strict";
var doT = {
version: '1.0.17',
templateSettings: {
evaluate: /\{\{([\s\S]+?\}?)\}\}/g,
interpolate: /\{\{=([\s\S]+?)\}\}/g,
encode: /\{\{!([\s\S]+?)\}\}/g,
use: /\{\{#([\s\S]+?)\}\}/g,
useParams: /(^|[^\w$])def(?:\.|\[[\'\"])([\w$\.]+)(?:[\'\"]\])?\s*\:\s*([\w$\.]+|\"[^\"]+\"|\'[^\']+\'|\{[^\}]+\})/g,
define: /\{\{##\s*([\w\.$]+)\s*(\:|=)([\s\S]+?)#\}\}/g,
defineParams:/^\s*([\w$]+):([\s\S]+)/,
conditional: /\{\{\?(\?)?\s*([\s\S]*?)\s*\}\}/g,
iterate: /\{\{~\s*(?:\}\}|([\s\S]+?)\s*\:\s*([\w$]+)\s*(?:\:\s*([\w$]+))?\s*\}\})/g,
varname: 'it',
strip: true,
append: true,
selfcontained: false
},
template: undefined, //fn, compile template
compile: undefined //fn, for express
};
if (typeof module !== 'undefined' && module.exports) {
module.exports = doT;
} else if (typeof define === 'function' && define.amd) {
define(function(){return doT;});
} else {
(function(){ return this || (0,eval)('this'); }()).doT = doT;
}
function encodeHTMLSource() {
var encodeHTMLRules = { "&": "&#38;", "<": "&#60;", ">": "&#62;", '"': '&#34;', "'": '&#39;', "/": '&#47;' },
matchHTML = /&(?!#?\w+;)|<|>|"|'|\//g;
return function() {
return this ? this.replace(matchHTML, function(m) {return encodeHTMLRules[m] || m;}) : this;
};
}
String.prototype.encodeHTML = encodeHTMLSource();
var startend = {
append: { start: "'+(", end: ")+'", endencode: "||'').toString().encodeHTML()+'" },
split: { start: "';out+=(", end: ");out+='", endencode: "||'').toString().encodeHTML();out+='"}
}, skip = /$^/;
function resolveDefs(c, block, def) {
return ((typeof block === 'string') ? block : block.toString())
.replace(c.define || skip, function(m, code, assign, value) {
if (code.indexOf('def.') === 0) {
code = code.substring(4);
}
if (!(code in def)) {
if (assign === ':') {
if (c.defineParams) value.replace(c.defineParams, function(m, param, v) {
def[code] = {arg: param, text: v};
});
if (!(code in def)) def[code]= value;
} else {
new Function("def", "def['"+code+"']=" + value)(def);
}
}
return '';
})
.replace(c.use || skip, function(m, code) {
if (c.useParams) code = code.replace(c.useParams, function(m, s, d, param) {
if (def[d] && def[d].arg && param) {
var rw = (d+":"+param).replace(/'|\\/g, '_');
def.__exp = def.__exp || {};
def.__exp[rw] = def[d].text.replace(new RegExp("(^|[^\\w$])" + def[d].arg + "([^\\w$])", "g"), "$1" + param + "$2");
return s + "def.__exp['"+rw+"']";
}
});
var v = new Function("def", "return " + code)(def);
return v ? resolveDefs(c, v, def) : v;
});
}
function unescape(code) {
return code.replace(/\\('|\\)/g, "$1").replace(/[\r\t\n]/g, ' ');
}
doT.template = function(tmpl, c, def) {
c = c || doT.templateSettings;
var cse = c.append ? startend.append : startend.split, needhtmlencode, sid = 0, indv,
str = (c.use || c.define) ? resolveDefs(c, tmpl, def || {}) : tmpl;
str = ("var out='" + (c.strip ? str.replace(/(^|\r|\n)\t* +| +\t*(\r|\n|$)/g,' ')
.replace(/\r|\n|\t|\/\*[\s\S]*?\*\//g,''): str)
.replace(/'|\\/g, '\\$&')
.replace(c.interpolate || skip, function(m, code) {
return cse.start + unescape(code) + cse.end;
})
.replace(c.encode || skip, function(m, code) {
needhtmlencode = true;
return cse.start + unescape(code) + cse.endencode;
})
.replace(c.conditional || skip, function(m, elsecase, code) {
return elsecase ?
(code ? "';}else if(" + unescape(code) + "){out+='" : "';}else{out+='") :
(code ? "';if(" + unescape(code) + "){out+='" : "';}out+='");
})
.replace(c.iterate || skip, function(m, iterate, vname, iname) {
if (!iterate) return "';} } out+='";
sid+=1; indv=iname || "i"+sid; iterate=unescape(iterate);
return "';var arr"+sid+"="+iterate+";if(arr"+sid+"){var "+vname+","+indv+"=-1,l"+sid+"=arr"+sid+".length-1;while("+indv+"<l"+sid+"){"
+vname+"=arr"+sid+"["+indv+"+=1];out+='";
})
.replace(c.evaluate || skip, function(m, code) {
return "';" + unescape(code) + "out+='";
})
+ "';return out;")
.replace(/\n/g, '\\n').replace(/\t/g, '\\t').replace(/\r/g, '\\r')
.replace(/(\s|;|\}|^|\{)out\+='';/g, '$1').replace(/\+''/g, '')
.replace(/(\s|;|\}|^|\{)out\+=''\+/g,'$1out+=');
if (needhtmlencode && c.selfcontained) {
str = "String.prototype.encodeHTML=(" + encodeHTMLSource.toString() + "());" + str;
}
try {
return new Function(c.varname, str);
} catch (e) {
if (typeof console !== 'undefined') console.log("Could not create a template function: " + str);
throw e;
}
};
doT.compile = function(tmpl, def) {
return doT.template(tmpl, null, def);
};
}());

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,380 @@
$.namespace("druid.lang");
druid.lang = function() {
var LANG_EN = 0;
var LANG_CN = 1;
var lang = {
'Index' : ['Index','首页'],
'DataSource' : ['DataSource', '数据源'],
'SQL' : ['SQL','SQL监控'],
'Wall' : ['Wall' , 'SQL防火墙'],
'WebApp' : ['WebApp' , 'Web应用'],
'WebURI' : ['WebURI' , 'URI监控'],
'Web Session' : ['Web Session' , 'Session监控'],
'Spring' : ['Spring' , 'Spring监控'],
'JSON API' : ['JSON API' , 'JSON API'],
'ResetAll' : ['Reset All' , '重置'],
'LogAndReset' : ['Log And Reset' , '记录日志并重置'],
'StatIndex' : ['Stat Index', '统计索引'],
'ViewJSONAPI' : ['View JSON API','查看JSON API'],
'Version' : ['Version' , '版本'],
'Drivers' : ['Drivers' , '驱动'],
'ResetEnable' : ['ResetEnable' , '是否允许重置'],
'ResetCount' : ['ResetCount' , '重置次数'],
'JavaVersion' : ['JavaVersion' , 'Java版本'],
'JavaVMName' : ['JavaVMName' , 'JVM名称'],
'JavaClassPath' : ['JavaClassPath' , 'classpath路径'],
'StartTime' : ['StartTime' , '启动时间'],
'DataSourceStatList' : ['DataSourceStat List' , '数据源列表'],
'UserName' : ['UserName', '用户名'],
'URL' : ['URL', '连接地址'],
'DbType' : ['DbType', '数据库类型'],
'DriverClassName' : ['DriverClassName', '驱动类名'],
'FilterClassNames' : ['FilterClassNames', 'filter类名'],
'TestOnBorrow' : ['TestOnBorrow', '获取连接时检测'],
'TestWhileIdle' : ['TestWhileIdle', '空闲时检测'],
'TestOnReturn' : ['TestOnReturn', '连接放回连接池时检测'],
'InitialSize' : ['InitialSize', '初始化连接大小'],
'MinIdle' : ['MinIdle', '最小空闲连接数'],
'MaxActive' : ['MaxActive', '最大连接数'],
'QueryTimeout' : ['QueryTimeout', '查询超时时间'],
'TransactionQueryTimeout' : ['TransactionQueryTimeout', '事务查询超时时间'],//
'LoginTimeout' : ['LoginTimeout', '登录超时时间'],//
'ValidConnectionCheckerClassName' : ['ValidConnectionCheckerClassName', '连接有效性检查类名'],
'ExceptionSorterClassName' : ['ExceptionSorterClassName', 'ExceptionSorter类名'],//
'DefaultAutoCommit' : ['DefaultAutoCommit', '默认autocommit设置'],
'DefaultReadOnly' : ['DefaultReadOnly', '默认只读设置'],
'DefaultTransactionIsolation' : ['DefaultTransactionIsolation', '默认事务隔离'],//
'NotEmptyWaitCount' : ['NotEmptyWaitCount', '累计总次数'],//
'NotEmptyWaitMillis' : ['NotEmptyWaitMillis', '等待总时长'],//
'WaitThreadCount' : ['WaitThreadCount', '等待线程数量'],
'StartTransactionCount' : ['StartTransactionCount', '事务启动数'],//
'TransactionHistogram' : ['TransactionHistogram', '事务时间分布'],//
'PoolingCount' : ['PoolingCount', '池中连接数'],//
'PoolingPeak' : ['PoolingPeak', '池中连接数峰值'],//
'PoolingPeakTime' : ['PoolingPeakTime', '池中连接数峰值时间'],////
'ActiveCount' : ['ActiveCount', '活跃连接数'],
'ActivePeak' : ['ActivePeak', '活跃连接数峰值'],//
'ActivePeakTime' : ['ActivePeakTime', '活跃连接数峰值时间'],
'LogicConnectCount' : ['LogicConnectCount', '逻辑连接打开次数'],
'LogicCloseCount' : ['LogicCloseCount', '逻辑连接关闭次数'],
'LogicConnectErrorCount' : ['LogicConnectErrorCount', '逻辑连接错误次数'],
'PhysicalConnectCount' : ['PhysicalConnectCount', '物理连接打开次数'],
'PhysicalCloseCount' : ['PhysicalCloseCount', '物理关闭数量'],
'PhysicalConnectErrorCount' : ['PhysicalConnectErrorCount', '物理连接错误次数'],
'DiscardCount' : ['DiscardCount', '校验失败废弃连接数'],
'ExecuteCount' : ['ExecuteCount (Total)', '执行数(总共)'],
'ErrorCount' : ['ErrorCount', '错误数'],
'CommitCount' : ['CommitCount', '提交数'],
'RollbackCount' : ['RollbackCount', '回滚数'],
'PSCacheAccessCount' : ['PSCacheAccessCount', 'PSCache访问次数'],
'PSCacheHitCount' : ['PSCacheHitCount', 'PSCache命中次数'],
'PSCacheMissCount' : ['PSCacheMissCount', 'PSCache不命中次数'],//
'ConnectionHoldTimeHistogram' : ['ConnectionHoldTimeHistogram', '连接持有时间分布'],
'ClobOpenCount' : ['ClobOpenCount', 'Clob打开次数'],
'BlobOpenCount' : ['BlobOpenCount', 'Blob打开次数'],
'KeepAliveCheckCount' : ['KeepAliveCheckCount', 'KeepAlive检测次数'],
'ActiveConnectionStackTrace' : ['ActiveConnection StackTrace', '活跃连接堆栈查看'],
'PollingConnectionInfo' : ['PollingConnection Info', '连接池中连接信息'],
'SQLList' : ['SQL List', 'sql列表'],
'UserNameDesc' : ['Specify the username used when creating a new connection.', '指定建立连接时使用的用户名'],
'URLDesc' : ['The JDBC driver connection URL', 'JDBC连接字符串'],
'DbTypeDesc' : ['database type', '数据库类型'],
'DriverClassNameDesc' : ['The fully qualifed name of the JDBC driver class', 'JDBC驱动的类名'],
'FilterClassNamesDesc' : ['All the fully qualifed name of the filter classes', 'filter的类名'],
'TestOnBorrowDesc' : [' Test or not when borrow a connection', '是否在获得连接后检测其可用性'],
'TestWhileIdleDesc' : ['Test or not when a connection is idle for a while', '是否在连接空闲一段时间后检测其可用性'],
'TestOnReturnDesc' : ['Test or not when return a connection', '是否在连接放回连接池后检测其可用性'],
'InitialSizeDesc' : ['The size of datasource connections to create when initial a datasource', '连接池建立时创建的初始化连接数'],
'MinIdleDesc' : ['The minimum number of connections a pool should hold. ', '连接池中最小的活跃连接数'],
'MaxActiveDesc' : ['The maximum number of connections for a pool', '连接池中最大的活跃连接数'],
'QueryTimeoutDesc' : ['', '查询超时时间'],
'TransactionQueryTimeoutDesc' : ['', '事务查询超时时间'],
'LoginTimeoutDesc' : ['', ''],///
'ValidConnectionCheckerClassNameDesc' : ['', ''],
'ExceptionSorterClassNameDesc' : ['', ''],
'DefaultAutoCommitDesc' : ['', ''],
'DefaultReadOnlyDesc' : ['', ''],
'DefaultTransactionIsolationDesc' : ['', ''],
'NotEmptyWaitCountDesc' : ['Total times for wait to get a connection', '获取连接时累计等待多少次'],//
'NotEmptyWaitMillisDesc' : ['Total millis for wait to get a connection', '获取连接时累计等待多长时间'],
'WaitThreadCountDesc' : ['The current waiting thread count', '当前等待获取连接的线程数'],
'StartTransactionCountDesc' : ['The count of start transaction', '事务开始的个数'],
'TransactionHistogramDesc' : ['The histogram values of transaction time, [0-1 ms, 1-10 ms, 10-100 ms, 100-1 s, 1-10 s, 10-100 s, >100 s]', '事务运行时间分布,分布区间为[0-1 ms, 1-10 ms, 10-100 ms, 100-1 s, 1-10 s, 10-100 s, >100 s]'],
'PoolingCountDesc' : ['The current usefull connection count', '当前连接池中的数目'],//
'PoolingPeakDesc' : ['The usefull connection peak count', '连接池中数目的峰值'],
'PoolingPeakTimeDesc' : ['The usefull connection peak time', '连接池数目峰值出现的时间'],
'ActiveCountDesc' : ['The current active connection count', '当前连接池中活跃连接数'],
'ActivePeakDesc' : ['The current active connection peak count', '连接池中活跃连接数峰值'],
'ActivePeakTimeDesc' : ['The active connection peak time', '活跃连接池峰值出现的时间'],
'LogicConnectCountDesc' : ['Total connect times from datasource', '产生的逻辑连接建立总数'],
'LogicCloseCountDesc' : ['Total close connect times from datasource', '产生的逻辑连接关闭总数'],
'LogicConnectErrorCountDesc' : ['Total connect error times', '产生的逻辑连接出错总数'],
'RecycleErrorCount' : ['Logic Connection Recycle Count', '逻辑连接回收重用次数'],
'PhysicalConnectCountDesc' : ['Create physical connnection count', '产生的物理连接建立总数'],
'PhysicalCloseCountDesc' : ['Close physical connnection count', '产生的物理关闭总数'],
'DiscardCountDesc' : ['Discard connection count with validate fail', '校验连接失败丢弃连接次数'],
'PhysicalConnectErrorCountDesc' : ['Total physical connect error times', '产生的物理连接失败总数'],
'ExecuteCountDesc' : ['', ''],
'ErrorCountDesc' : ['', ''],
'CommitCountDesc' : ['', '事务提交次数'],
'RollbackCountDesc' : ['', '事务回滚次数'],
'PSCacheAccessCountDesc' : ['PerpareStatement access count', 'PSCache访问总数'],
'PSCacheHitCountDesc' : ['PerpareStatement hit count', 'PSCache命中次数'],
'PSCacheMissCountDesc' : ['PerpareStatement miss count', 'PSCache不命中次数'],//
'PreparedStatementOpenCount' : ['Real PreparedStatement Open Count', '真实PreparedStatement打开次数'],//
'PreparedStatementClosedCount' : ['Real PreparedStatement Closed Count', '真实PreparedStatement关闭次数'],//
'ConnectionHoldTimeHistogramDesc' : ['The histogram values of connection hold time, [0-1 ms, 1-10 ms, 10-100 ms, 100ms-1s, 1-10 s, 10-100 s, 100-1000 s, >1000 s]', '连接持有时间分布,分布区间为[0-1 ms, 1-10 ms, 10-100 ms, 100ms-1s, 1-10 s, 10-100 s, 100-1000 s, >1000 s]'],
'ClobOpenCountDesc' : ['', 'Clob打开数'],
'BlobOpenCountDesc' : ['', 'Blob打开数'],
/**spring-detail*/
'Class' : ['Class', 'Class'],
'Method' : ['Method', 'Method'],
'ExecuteErrorCount' : ['ExecuteErrorCount', '执行出错数'],
'ExecuteTimeMillis' : ['ExecuteTimeMillis', '执行时间'],
'RunningCount' : ['RunningCount', '执行中'],
'ConcurrentMax' : ['ConcurrentMax', '最大并发'],
'JdbcExecuteCount' : ['JdbcExecuteCount', 'Jdbc执行数'],
'JdbcExecuteErrorCount' : ['JdbcExecErrorCount', 'Jdbc出错数'],
'JdbcExecuteTimeMillis' : ['JdbcExecTimeMillis', 'Jdbc时间'],
'JdbcCommitCount' : ['CommitCount', '事务提交数'],
'JdbcRollbackCount' : ['RollbackCount', '事务回滚数'],
'JdbcFetchRowCount' : ['FetchRowCount', '读取行数'],
'JdbcUpdateCount' : ['UpdateCount', '更新行数'],
'JdbcPoolConnectionOpenCount' : ['JdbcPoolConnectionOpenCount', '连接池获取连接次数'],
'JdbcPoolConnectionCloseCount' : ['JdbcPoolConnectionCloseCount', '连接池关闭连接次数'],
'JdbcResultSetOpenCount' : ['JdbcResultSetOpenCount', 'ResultSet打开次数'],
'JdbcResultSetCloseCount' : ['JdbcResultSetCloseCount', 'ResultSet关闭次数'],
/**sql-detail*/
'ParseView' : ['ParseView', '解析信息'],//
'Tables' : [' Tables', '表'],
'Fields' : ['Fields', '字段'],
'Coditions' : ['Coditions', '条件'],
'Relationships' : ['Relationships', '关联'],
'OrderByColumns' : ['OrderByColumns', '排序字段'],
'LastSlowView' : ['LastSlowView', '最后慢查询'],
'MaxTimespan' : ['MaxTimespan', '最慢'],
'MaxTimespanOccurTime' : ['MaxTimespanOccurTime', '最慢发生时间'],
'LastSlowParameters' : ['LastSlowParameters', '最后慢查询参数'],
'LastErrorView' : ['LastErrorView', '最后错误视图'],
'LastErrorMessage' : ['LastErrorMessage', '最后错误信息'],
'LastErrorClass' : ['LastErrorClass', '最后错误类'],
'LastErrorTime' : ['LastErrorTime', '最后错误时间'],
'LastErrorStackTrace' : ['LastErrorStackTrace', '最后错误堆栈'],
'OtherView' : ['OtherView', '其他信息'],
'BatchSizeMax' : ['BatchSizeMax', '批处理最大值'],////
'BatchSizeTotal' : ['BatchSizeTotal', '批处理总数'],//
'ReaderOpenCount' : ['ReaderOpenCount', 'reader打开次数'],//
'InputStreamOpenCount' : ['InputStreamOpenCount', 'inputstream打开次数'],
'ReadStringLength' : ['ReadStringLength', '读取字符串长度'],//
'ReadBytesLength' : ['ReadBytesLength', '读取字节长度'],//
'ExecHisto':['ExecHisto','执行时间分布'],
'ExecRsHisto':['ExecRsHisto','执行+RS时分布'],
'FetchRowHisto':['FetchRowHisto','读取行分布'],
'UpdateHisto':['UpdateHisto','更新行分布'],
'InTransactionCount' : ['Txn','事务执行'],
'MaxTimespanDesc' : ['Execute Time Millis Max','最慢的执行耗时'],
'InTransactionCountDesc' : ['Execute In Transaction Count','在事务中运行的次数'],
'count1ms':['count of 0-1 ms','0-1毫秒次数'],
'count10ms':['count of 1-10 ms','1-10毫秒次数'],
'count100ms':['count of 10-100 ms','10-100毫秒次数'],
'count1s':['count of 100ms-1s','100-1000毫秒次数'],
'count10s':['count of 1-10 s','1-10秒次数'],
'count100s':['count of 10-100 s','10-100秒次数'],
'count1000s':['count of 100-1000 s','100-1000秒次数'],
'countBg1000s':['count of >1000 s','大于1000秒次数'],
'fetch0':['count of 0 FetchRow','读取行数为0'],
'fetch9':['count of 1-9 FetchRow','读取行数1-9'],
'fetch99':['count of 10-99 FetchRow','读取行数10-99'],
'fetch999':['count of 100-999 FetchRow','读取行数100-999'],
'fetch9999':['count of 1000-9999 FetchRow','读取行数1000-9999'],
'fetch99999':['count of >9999 FetchRow','读取行数大于9999'],
'update0':['count of 0 UpdateCount','更新行数为0'],
'update9':['count of 1-9 UpdateCount','更新行数1-9'],
'update99':['count of 10-99 UpdateCount','更新行数10-99'],
'update999':['count of 100-999 UpdateCount','更新行数100-999'],
'update9999':['count of 1000-9999 UpdateCount','更新行数1000-9999'],
'update99999':['count of >9999 UpdateCount','更新行数大于9999'],
/**wall*/
'CheckCount':['CheckCount', '检查次数'],
'HardCheckCount':['HardCheckCount', '硬检查次数'],
'ViolationCount':['ViolationCount', '非法次数'],
'BlackListHitCount':['BlackListHitCount', '黑名单命中次数'],
'BlackListSize':['BlackListSize', '黑名单长度'],
'WhiteListHitCount':['WhiteListHitCount', '白名单命中次数'],
'WhiteListSize':['WhiteListSize', '白名单长度'],
'SyntaxErrrorCount':['SyntaxErrrorCount', '语法错误次数'],
'TableName':['TableName', '表名'],
'TableNumber':['Number','序号'],
'Sample':['Sample','样本'],
'ExecuteCount':['ExecuteCount','执行数'],
'FetchRowCount':['FetchRowCount','读取行数'],
'SQLUpdateCount':['UpdateCount','更新行数'],
'SelectCount':['SelectCount', 'Select数'],
'SelectIntoCount':['SelectIntoCount', 'SelectInto数'],
'InsertCount':['InsertCount', 'Insert数'],
'UpdateCount':['UpdateCount', 'Update数'],
'DeleteCount':['DeleteCount', 'Delete数'],
'TruncateCount':['TruncateCount', 'Truncate数'],
'CreateCount':['CreateCount', 'Create数'],
'AlterCount':['AlterCount', 'Alter数'],
'DropCount':['DropCount', 'Drop数'],
'ReplaceCount':['ReplaceCount', 'Replace数'],
'DeleteDataCount':['DeleteDataCount', '删除数据行数'],
'UpdateDataCount':['UpdateDataCount', '更新数据行数'],
'FetchRowCount':['FetchRowCount', '读取行数'],
'WallStat':['Wall Stat', '防御统计'],
'TableStat':['Table Stat', '表访问统计'],
'FunctionStat':['Function Stat', '函数调用统计'],
'SQLStatWhiteList':['SQL Stat - White List', 'SQL防御统计 - 白名单'],
'SQLStatBlackList':['SQL Stat - Black List', 'SQL防御统计 - 黑名单'],
/**session-detail*/
'PrincipalOnly':['Principal Only', 'Principal过滤'],
'SESSIONID':['SESSIONID', 'SESSIONID'],
'UserAgent':['UserAgent', 'UserAgent'],
'Principal':['Principal', 'Principal'],
'CreateTime':['CreateTime', '创建时间'],
'LastAccessTime':['LastAccessTime', '最后访问时间'],
'RemoteAddress':['RemoteAddress', '访问ip地址'],
'RequestCount':['RequestCount', '请求次数'],
'RequestTimeMillisTotal':['RequestTimeMillisTotal', '总共请求时间'],
'RequestInterval':['RequestInterval', '请求间隔'],
/**weburi-detail*/
'RefreshPeriod':['Refresh Period', '刷新时间'],
'ServiceList':['ServiceList', '服务名称'],
'SuspendRefresh':['Suspend Refresh', '暂停刷新'],
'RequestTimeMillis':['RequestTimeMillisTotal', '请求时间(和)'],
'RequestTimeMillisMax':['RequestTimeMillisMax', '请求最慢(单次)'],
'RequestTimeMillisMaxOccurTime':['RequestTimeMillisMaxOccurTime', '请求最慢发生时间'],
'JdbcExecutePeak':['JdbcExecutePeak', 'jdbc执行峰值'],
'JdbcFetchRowPeak':['JdbcFetchRowPeak', 'jdbc查询取回行数峰值'],
'JdbcUpdatePeak':['JdbcUpdatePeak', 'jdbc更新峰值'],
'Histogram':['Histogram','区间分布']
};
var COOKIE_LANG_NAME = "cookie_lang";
function log(str) {
if (typeof (console) != 'undefined' && typeof(console.log) != 'undefined') {
console.log(str);
} else {
$('body').append('<input type="hidden" value="' + str + " />");
}
}
function setCookie(name,value,expires,path,domain,secure)
{
var expDays = expires*24*60*60*1000;
var expDate = new Date();
expDate.setTime(expDate.getTime()+expDays);
var expString = ((expires==null) ? "": (";expires="+expDate.toGMTString()));
var pathString = ((path==null) ? "": (";path="+path));
var domainString = ((domain==null) ? "": (";domain="+domain));
var secureString = ((secure==true) ? ";secure": "");
document.cookie = name + "="+ escape(value) + expString + pathString + domainString + secureString;
}
function getCookie(name)
{
var result = null;
var myCookie = document.cookie + ";";
var searchName = name + "=";
var startOfCookie = myCookie.indexOf(searchName);
var endOfCookie;
if (startOfCookie != -1)
{
startOfCookie += searchName.length;
endOfCookie = myCookie.indexOf(";",startOfCookie);
result = unescape(myCookie.substring(startOfCookie,endOfCookie));
}
return result;
}
function setText($obj) {
var key = $obj.attr('langKey');
if (typeof(lang[key]) != 'undefined') {
var text = lang[key][druid.lang.langNow];
$obj.text(lang[key][druid.lang.langNow]);
} else {
log('key [' + key + '] not found');
}
}
function setTitle($obj) {
var key = $obj.attr('langKey');
if (typeof(lang[key]) != 'undefined') {
var title = lang[key][druid.lang.langNow];
$obj.attr('title', title);
} else {
log('key [' + key + '] not found');
}
}
return {
langNow : LANG_CN,
EVENT_LOAD_FINISHED : 'loadFinished',
init : function(langNow) {
if (typeof(langNow) != 'undefined') {
this.setLangType(langNow);
} else {
var langInCookie = getCookie(COOKIE_LANG_NAME);
if (langInCookie == LANG_CN || langInCookie == LANG_EN) {
this.setLangType(langInCookie);
}
}
$(document).on(this.EVENT_LOAD_FINISHED, '.lang', function() {
log('load lang');
setText($(this));
});
$(document).on(this.EVENT_LOAD_FINISHED, '.langTitle', function() {
log('load title');
setTitle($(this));
});
this.trigger();
$(document).on('click','.langSelector',function() {
var langSelected = $(this).attr('langNow');
druid.lang.setLangType(langSelected);
druid.lang.trigger();
return false;
});
},
setLangType : function (langNow) {
this.langNow = langNow;
setCookie(COOKIE_LANG_NAME,langNow,30,'/');
},
getLangType : function () {
return this.langNow;
},
show : function($parent) {
var $obj;
var $objTitle;
if ($parent) {
$obj = $parent.find('.lang');
$objTitle = $parent.find('.langTitle');
} else {
$obj = $('.lang');
$objTitle = $('.langTitle');
}
$obj.each(function() {
setText($(this));
});
$objTitle.each(function() {
setTitle($(this));
});
},
trigger : function() {
log('to load lang now');
$('.lang').trigger(this.EVENT_LOAD_FINISHED);//触发语言显示事件
$('.langTitle').trigger(this.EVENT_LOAD_FINISHED);//触发语言显示事件
}
}
}();

View File

@@ -0,0 +1,112 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>druid monitor</title>
<link href='css/bootstrap.min.css' rel="stylesheet" >
<script type="text/javascript" src="js/jquery.min.js"></script>
<style type="text/css">
/* Override some defaults */
html, body {
background-color: #eee;
}
body {
padding-top: 40px;
}
.container {
width: 300px;
}
/* The white background content wrapper */
.container > .content {
background-color: #fff;
padding: 20px;
margin: 0 -20px;
-webkit-border-radius: 10px 10px 10px 10px;
-moz-border-radius: 10px 10px 10px 10px;
border-radius: 10px 10px 10px 10px;
-webkit-box-shadow: 0 1px 2px rgba(0,0,0,.15);
-moz-box-shadow: 0 1px 2px rgba(0,0,0,.15);
box-shadow: 0 1px 2px rgba(0,0,0,.15);
}
.login-form {
margin-left: 65px;
}
legend {
margin-right: -50px;
font-weight: bold;
color: #404040;
}
</style>
</head>
<body>
<div class="container">
<div class="content">
<div class="row">
<div class="login-form">
<h2>Login</h2>
<form id="loginForm" method="post" autocomplete="off" >
<fieldset>
<div id="alertInfo" class="alert alert-error clearfix" style="margin-bottom: 5px;width: 195px; padding: 2px 15px 2px 10px;display: none;">
The username or password you entered is incorrect.
</div>
<div class="clearfix">
<input type="text" placeholder="用户名" name="loginUsername" autofocus="autofocus">
</div>
<div class="clearfix">
<input type="password" placeholder="密码" name="loginPassword">
</div>
<button id="loginBtn" class="btn btn-primary" type="button">Sign in</button>
<button class="btn" type="reset">Reset</button>
</fieldset>
</form>
</div>
</div>
</div>
</div> <!-- /container -->
<script type="text/javascript">
$.namespace("druid.login");
druid.login = function () {
return {
login : function() {
$.ajax({
type: 'POST',
url: "submitLogin",
data: $("#loginForm").serialize(),
success: function(data) {
if("success" == data)
location.href = "index.html";
else {
$("#alertInfo").show();
$("#loginForm")[0].reset();
$("input[name=loginUsername]").focus();
}
},
dataType: "text"
});
},
unamecr : function(e) {
if(e.which == 13) { // enter key event
$("input[name=loginPassword]").focus();
}
},
upasscr : function(e) {
if(e.which == 13) { // enter key event
$("#loginBtn").click();
}
}
}
}();
$(document).ready(function() {
$("#loginBtn").click(druid.login.login);
$("input[name=loginUsername]").keypress(druid.login.unamecr);
$("input[name=loginPassword]").keypress(druid.login.upasscr);
});
</script>
</body>
</html>

View File

@@ -0,0 +1,14 @@
<!doctype html>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf8" />
<link href="css/style.css" type="text/css" rel="stylesheet"/>
</head>
<body >
<br/>
<div id="main">
<h2>Sorry, you are not permitted to view this page.</h2>
</div>
</body>
</html>

View File

@@ -0,0 +1,153 @@
<!doctype html>
<html>
<head>
<title>Druid Spring Stat</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf8" />
<link href='css/bootstrap.min.css' rel="stylesheet" />
<link href="css/style.css" type="text/css" rel="stylesheet"/>
<script type="text/javascript" src="js/jquery.min.js"></script>
<script src="js/lang.js" type="text/javascript" charset="utf8"></script>
<script src="js/common.js" type="text/javascript" charset="utf8"></script>
</head>
<body>
<div class="container-fluid">
<div class="row-fluid">
<div class="span12">
<h3>
Spring View
<a id="viewJsonApi" target="_blank">View JSON API</a>
</h3>
<table id="dataTable" class="table table-bordered" style="background-color: #fff">
<tr>
<td class='td_lable lang' langKey="Class"> Class</td>
<td id="Class"></td>
</tr>
<tr>
<td class='td_lable lang' langKey="Method"> Method</td>
<td id="Method"></td>
</tr>
<tr>
<td class='td_lable lang' langKey="ExecuteCount"> ExecuteCount</td>
<td id="ExecuteCount"></td>
</tr>
<tr>
<td class='td_lable lang' langKey="ExecuteErrorCount"> ExecuteErrorCount</td>
<td id="ExecuteErrorCount"></td>
</tr>
<tr>
<td class='td_lable lang' langKey="ExecuteTimeMillis"> ExecuteTimeMillis</td>
<td id="ExecuteTimeMillis"></td>
</tr>
<tr>
<td class='td_lable lang' langKey="RunningCount"> RunningCount</td>
<td id="RunningCount"></td>
</tr>
<tr>
<td class='td_lable lang' langKey="ConcurrentMax"> ConcurrentMax</td>
<td id="ConcurrentMax"></td>
</tr>
<tr>
<td class='td_lable lang' langKey="JdbcExecuteCount"> JdbcExecuteCount</td>
<td id="JdbcExecuteCount"></td>
</tr>
<tr>
<td class='td_lable lang' langKey="JdbcExecuteErrorCount"> JdbcExecuteErrorCount</td>
<td id="JdbcExecuteErrorCount"></td>
</tr>
<tr>
<td class='td_lable lang' langKey="JdbcExecuteTimeMillis"> JdbcExecuteTimeMillis</td>
<td id="JdbcExecuteTimeMillis"></td>
</tr>
<tr>
<td class='td_lable lang' langKey="JdbcCommitCount"> JdbcCommitCount</td>
<td id="JdbcCommitCount"></td>
</tr>
<tr>
<td class='td_lable lang' langKey="JdbcRollbackCount"> JdbcRollbackCount</td>
<td id="JdbcRollbackCount"></td>
</tr>
<tr>
<td class='td_lable lang' langKey="JdbcFetchRowCount"> JdbcFetchRowCount</td>
<td id="JdbcFetchRowCount"></td>
</tr>
<tr>
<td class='td_lable lang' langKey="JdbcUpdateCount"> JdbcUpdateCount</td>
<td id="JdbcUpdateCount"></td>
</tr>
<tr>
<td class='td_lable lang' langKey="JdbcPoolConnectionOpenCount"> JdbcPoolConnectionOpenCount</td>
<td id="JdbcPoolConnectionOpenCount"></td>
</tr>
<tr>
<td class='td_lable lang' langKey="JdbcPoolConnectionCloseCount"> JdbcPoolConnectionCloseCount</td>
<td id="JdbcPoolConnectionCloseCount"></td>
</tr>
<tr>
<td class='td_lable lang' langKey="JdbcResultSetOpenCount"> JdbcResultSetOpenCount</td>
<td id="JdbcResultSetOpenCount"></td>
</tr>
<tr>
<td class='td_lable lang' langKey="JdbcResultSetCloseCount"> JdbcResultSetCloseCount</td>
<td id="JdbcResultSetCloseCount"></td>
</tr>
</table>
<div class="container">
<a class="btn btn-primary" href="javascript:window.close();">Close</a>
</div>
</div>
</div>
</div>
<script type="text/javascript">
$.namespace("druid.springdetail");
druid.springdetail = function () {
var clazz = druid.common.getUrlVar("class");
var method = druid.common.getUrlVar("method");
return {
init : function() {
druid.common.buildHead(7);
this.ajaxRequestForBasicInfo();
$("#viewJsonApi").attr("href", 'spring-detail.json?class=' + clazz + '&method=' + method);
},
ajaxRequestForBasicInfo : function() {
$.ajax({
type: 'POST',
url: 'spring-detail.json?class=' + clazz + '&method=' + method,
success: function(data) {
var stat = data.Content;
if (stat == null)
return;
$("#Class").text(stat.Class)
$("#Method").text(stat.Method)
$("#ExecuteCount").text(stat.ExecuteCount)
$("#ExecuteErrorCount").text(stat.ExecuteErrorCount)
$("#ExecuteTimeMillis").text(stat.ExecuteTimeMillis)
$("#RunningCount").text(stat.RunningCount)
$("#ConcurrentMax").text(stat.ConcurrentMax)
$("#JdbcExecuteCount").text(stat.JdbcExecuteCount)
$("#JdbcExecuteErrorCount").text(stat.JdbcExecuteErrorCount)
$("#JdbcExecuteTimeMillis").text(stat.JdbcExecuteTimeMillis)
$("#JdbcCommitCount").text(stat.JdbcCommitCount)
$("#JdbcRollbackCount").text(stat.JdbcRollbackCount)
$("#JdbcFetchRowCount").text(stat.JdbcFetchRowCount)
$("#JdbcUpdateCount").text(stat.JdbcUpdateCount)
$("#JdbcPoolConnectionOpenCount").text(stat.JdbcPoolConnectionOpenCount)
$("#JdbcPoolConnectionCloseCount").text(stat.JdbcPoolConnectionCloseCount)
$("#JdbcResultSetOpenCount").text(stat.JdbcResultSetOpenCount)
$("#JdbcResultSetCloseCount").text(stat.JdbcResultSetCloseCount)
},
dataType: "json"
});
}
}
}();
$(document).ready(function() {
druid.springdetail.init();
});
</script>
</body>
</html>

View File

@@ -0,0 +1,110 @@
<!doctype html>
<html>
<head>
<title>Druid Spring Stat</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf8" />
<link href='css/bootstrap.min.css' rel="stylesheet" />
<link href="css/style.css" type="text/css" rel="stylesheet"/>
<script type="text/javascript" src="js/jquery.min.js"></script>
<script src="js/lang.js" type="text/javascript" charset="utf8"></script>
<script src="js/common.js" type="text/javascript" charset="utf8"></script>
</head>
<body>
<div class="container-fluid">
<div class="row-fluid">
<div class="span12">
<h3>
Spring Stat
<a href="spring.json" target="_blank">View JSON API</a>
</h3>
<table id="dataTable" class="table table-bordered table-striped responsive-utilities">
<thead>
<tr>
<th>N</th>
<th><a id="th-Class" href="javascript:void(0);" class="lang" langKey="Class">Class</a></th>
<th><a id="th-Method" href="javascript:void(0);" class="lang" langKey="Method">Method</a></th>
<th><a id="th-ExecuteCount" href="javascript:void(0);" class="lang" langKey="ExecuteCount">ExecuteCount</a></th>
<th><a id="th-ExecuteTimeMillis" href="javascript:void(0);" class="lang" langKey="ExecuteTimeMillis">ExecuteTimeMillis</a></th>
<th><a id="th-RunningCount" href="javascript:void(0);" class="lang" langKey="RunningCount">RunningCount</a></th>
<th><a id="th-ConcurrentMax" href="javascript:void(0);" class="lang" langKey="ConcurrentMax">ConcurrentMax</a></th>
<th><a id="th-JdbcExecuteCount" href="javascript:void(0);" class="lang" langKey="JdbcExecuteCount">JdbcExecuteCount</a></th>
<th><a id="th-JdbcExecuteTimeMillis" href="javascript:void(0);" class="lang" langKey="JdbcExecuteTimeMillis">JdbcExecuteTimeMillis</a></th>
<th><a id="th-JdbcCommitCount" href="javascript:void(0);" class="lang" langKey="JdbcCommitCount">JdbcCommitCount</a></th>
<th><a id="th-JdbcRollbackCount" href="javascript:void(0);" class="lang" langKey="JdbcRollbackCount">JdbcRollbackCount</a></th>
<th><a id="th-JdbcFetchRowCount" href="javascript:void(0);" class="lang" langKey="JdbcFetchRowCount">JdbcFetchRowCount</a></th>
<th><a id="th-JdbcUpdateCount" href="javascript:void(0);" class="lang" langKey="JdbcUpdateCount">JdbcUpdateCount</a></th>
<th align="left" width="100"><span class="lang" langKey="Histogram">Histogram</span> <br />[
<a id="th-Histogram[0]" class="langTitle" langKey="count1ms" title="count of '0-1 ms'" >-</a>
<a id="th-Histogram[1]" class="langTitle" langKey="count10ms" title="count of '1-10 ms'" >-</a>
<a id="th-Histogram[2]" class="langTitle" langKey="count100ms" title="count of '10-100 ms'" >-</a>
<a id="th-Histogram[3]" class="langTitle" langKey="count1s" title="count of '100ms-1 s'" >-</a>
<a id="th-Histogram[4]" class="langTitle" langKey="count10s" title="count of '1-10 s'" >-</a>
<a id="th-Histogram[5]" class="langTitle" langKey="count100s" title="count of '10-100 s'" >-</a>
<a id="th-Histogram[6]" class="langTitle" langKey="count1000s" title="count of '100-1000 s'" >-</a>
<a id="th-Histogram[7]" class="langTitle" langKey="countBg1000s" title="count of '> 1000 s'" >-</a> ]
</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
</div>
</div>
<script type="text/javascript">
$.namespace("druid.spring");
druid.spring = function () {
return {
init : function() {
$("#dataTable th a").click(function(obj) {
druid.common.setOrderBy(obj.target.id.substring(3))
})
druid.common.buildHead(7);
druid.common.ajaxuri = 'spring.json?';
druid.common.handleAjaxResult = druid.spring.handleAjaxResult;
druid.common.ajaxRequestForBasicInfo();
setInterval("druid.common.ajaxRequestForBasicInfo();",5000);
},
handleAjaxResult : function(data) {
var statList = data.Content;
if(statList==null) return;
var sqlStatTable = document.getElementById("dataTable");
while (sqlStatTable.rows.length > 1) {
sqlStatTable.deleteRow(1);
}
var html = "";
for ( var i = 0; i < statList.length; i++) {
var stat = statList[i];
var newRow = sqlStatTable.insertRow(-1);
html += "<tr>";
html += "<td>" + (i + 1) + "</td>";
html += "<td>" + stat.Class + "</td>";
html += "<td>" + '<a target="_blank" href="spring-detail.html?class=' + stat.Class + '&method=' + stat.Method + '">' + stat.Method + '</a>' + "</td>";
html += "<td>" + replace(stat.ExecuteCount) + "</td>";
html += "<td>" + replace(stat.ExecuteTimeMillis) + "</td>";
html += "<td>" + replace(stat.RunningCount) + "</td>";
html += "<td>" + replace(stat.ConcurrentMax) + "</td>";
html += "<td>" + replace(stat.JdbcExecuteCount) + "</td>";
html += "<td>" + replace(stat.JdbcExecuteTimeMillis) + "</td>";
html += "<td>" + replace(stat.JdbcCommitCount) + "</td>";
html += "<td>" + replace(stat.JdbcRollbackCount) + "</td>";
html += "<td>" + replace(stat.JdbcFetchRowCount) + "</td>";
html += "<td>" + replace(stat.JdbcUpdateCount) + "</td>";
html += "<td>" + '[' + stat.Histogram + ']' + "</td>";
html += "</tr>";
}
$("#dataTable tbody").html(html);
druid.common.stripes();
}
}
}();
$(document).ready(function() {
druid.spring.init();
});
</script>
</body>
</html>

View File

@@ -0,0 +1,191 @@
<!doctype html>
<html>
<head>
<title>Druid SQL Stat</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf8" />
<link href='css/bootstrap.min.css' rel="stylesheet" />
<link href="css/style.css" type="text/css" rel="stylesheet"/>
<script type="text/javascript" src="js/jquery.min.js"></script>
<script src="js/lang.js" type="text/javascript" charset="utf8"></script>
<script src="js/common.js" type="text/javascript" charset="utf8"></script>
</head>
<body>
<div class="container-fluid">
<div class="row-fluid">
<div class="span12">
<h3>
FULL SQL
<a id="viewJsonApi" target="_blank">View JSON API</a>
</h3>
<h5 id="fullSql"></h5>
<h2> Format View:</h2>
<textarea style='width:99%;height:120px;;border:1px #A8C7CE solid;line-height:20px;font-size:12px;' id="formattedSql">
</textarea>
<br/>
<br/>
<h3>ParseView:</h3>
<table class="table table-bordered" style="background-color: #fff"> <tr>
<td class='td_lable' width='130' class="lang" langKey=" Tables"> Tables</td>
<td id="parsedtable"></td>
</tr>
<tr>
<td class='td_lable' width='130' class="lang" langKey="Fields">Fields</td>
<td id="parsedfields"></td>
</tr>
<tr>
<td class='td_lable' width='130' class="lang" langKey="Coditions">Coditions</td>
<td id="parsedConditions"></td>
</tr>
<tr>
<td class='td_lable' width='130' class="lang" langKey="Relationships">Relationships</td>
<td id="parsedRelationships"></td>
</tr>
<tr>
<td class='td_lable' width='130' class="lang" langKey="OrderByColumns">OrderByColumns</td>
<td id="parsedOrderbycolumns"></td>
</tr>
</table>
<h3>LastSlowView:</h3>
<table class="table table-bordered" style="background-color: #fff"> <tr>
<td class='td_lable' width='130' class="lang" langKey="MaxTimespan">MaxTimespan</td>
<td id="MaxTimespan"></td>
</tr>
<tr>
<td class='td_lable' width='130' class="lang" langKey="MaxTimespanOccurTime">MaxTimespanOccurTime</td>
<td id="MaxTimespanOccurTime"></td>
</tr>
<tr>
<td class='td_lable' width='130' class="lang" langKey="LastSlowParameters">LastSlowParameters</td>
<td id="LastSlowParameters"></td>
</tr>
</table>
<h3>LastErrorView:</h3>
<table class="table table-bordered" style="background-color: #fff"> <tr>
<td class='td_lable' width='130' class="lang" langKey="LastErrorMessage">LastErrorMessage</td>
<td id="LastErrorMessage"></td>
</tr>
<tr>
<td class='td_lable' width='130' class="lang" langKey="LastErrorClass">LastErrorClass</td>
<td id="LastErrorClass"></td>
</tr>
<tr>
<td class='td_lable' width='130' class="lang" langKey="LastErrorTime">LastErrorTime</td>
<td id="LastErrorTime"></td>
</tr>
<tr>
<td class='td_lable' width='130' class="lang" langKey="LastErrorStackTrace">LastErrorStackTrace</td>
<td id="LastErrorStackTrace"></td>
</tr>
</table>
<h3>OtherView:</h3>
<table class="table table-bordered" style="background-color: #fff"> <tr>
<td class='td_lable' width='130' class="lang" langKey="BatchSizeMax">BatchSizeMax</td>
<td id="BatchSizeMax"></td>
</tr>
<tr>
<td class='td_lable' width='130' class="lang" langKey="BatchSizeTotal">BatchSizeTotal</td>
<td id="BatchSizeTotal"></td>
</tr>
<tr>
<td class='td_lable' width='130' class="lang" langKey="BlobOpenCount">BlobOpenCount</td>
<td id="BlobOpenCount"></td>
</tr>
<tr>
<td class='td_lable' width='130' class="lang" langKey="ClobOpenCount">ClobOpenCount</td>
<td id="ClobOpenCount"></td>
</tr>
<tr>
<td class='td_lable' width='130' class="lang" langKey="ReaderOpenCount">ReaderOpenCount</td>
<td id="ReaderOpenCount"></td>
</tr>
<tr>
<td class='td_lable' width='130' class="lang" langKey="InputStreamOpenCount">InputStreamOpenCount</td>
<td id="InputStreamOpenCount"></td>
</tr>
<tr>
<td class='td_lable' width='130' class="lang" langKey="ReadStringLength">ReadStringLength</td>
<td id="ReadStringLength"></td>
</tr>
<tr>
<td class='td_lable' width='130' class="lang" langKey="ReadBytesLength">ReadBytesLength</td>
<td id="ReadBytesLength"></td>
</tr>
</table>
<div class="container">
<a class="btn btn-primary" href="javascript:window.close();">Close</a>
</div>
</div>
</div>
</div>
<script type="text/javascript">
$.namespace("druid.sqlDetail");
druid.sqlDetail = function () {
var sqlId = druid.common.getUrlVar("sqlId");
var serviceId = druid.common.getUrlVar("serviceId");
return {
init : function() {
druid.common.buildHead(2);
this.ajaxRequestForBasicInfo();
$("#viewJsonApi").attr("href", 'sql-' + sqlId + '.json');
},
ajaxRequestForBasicInfo : function() {
$.ajax({
type: 'POST',
url: 'serviceId='+serviceId+'&sql-' + sqlId + '.json',
success: function(data) {
console.log("--------------");
console.log(data);
var sqlInfo = data.Content;
console.log("sqlInfo:" + sqlInfo.SQL);
if (sqlInfo == null)
return;
var sql = sqlInfo.SQL;
if (sql != null) {
sql = sql.replace(/</g,"&lt;").replace(/>/g,"&gt;");
} else {
sql = '';
}
$("#fullSql").text(sql)
$("#formattedSql").text(sqlInfo.formattedSql)
$("#parsedtable").text(sqlInfo.parsedTable)
$("#parsedfields").text(sqlInfo.parsedFields)
$("#parsedConditions").text(sqlInfo.parsedConditions)
$("#parsedRelationships").text(sqlInfo.parsedRelationships)
$("#parsedOrderbycolumns").text(sqlInfo.parsedOrderbycolumns)
$("#MaxTimespanOccurTime").text(sqlInfo.MaxTimespanOccurTime)
$("#LastSlowParameters").text(sqlInfo.LastSlowParameters)
$("#MaxTimespan").text(sqlInfo.MaxTimespan)
$("#LastErrorMessage").text(sqlInfo.LastErrorMessage)
$("#LastErrorClass").text(sqlInfo.LastErrorClass)
$("#LastErrorTime").text(sqlInfo.LastErrorTime)
$("#LastErrorStackTrace").text(sqlInfo.LastErrorStackTrace)
$("#BatchSizeMax").text(sqlInfo.BatchSizeMax)
$("#BatchSizeTotal").text(sqlInfo.BatchSizeTotal)
$("#BlobOpenCount").text(sqlInfo.BlobOpenCount)
$("#ClobOpenCount").text(sqlInfo.ClobOpenCount)
$("#InputStreamOpenCount").text(sqlInfo.InputStreamOpenCount)
$("#ReaderOpenCount").text(sqlInfo.ReaderOpenCount)
$("#ReadStringLength").text(sqlInfo.ReadStringLength)
$("#ReadBytesLength").text(sqlInfo.ReadBytesLength)
druid.lang.trigger();
},
dataType: "json"
});
}
}
}();
$(document).ready(function() {
druid.sqlDetail.init();
});
</script>
</body>
</html>

View File

@@ -0,0 +1,222 @@
<!doctype html>
<html>
<head>
<title>Druid SQL Stat</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf8"/>
<link href='css/bootstrap.min.css' rel="stylesheet"/>
<link href="css/style.css" type="text/css" rel="stylesheet"/>
<script type="text/javascript" src="js/jquery.min.js"></script>
<script src="js/lang.js" type="text/javascript" charset="utf8"></script>
<script src="js/common.js" type="text/javascript" charset="utf8"></script>
<script src="js/bootstrap.min.js" type="text/javascript" charset="utf8"></script>
</head>
<body>
<div class="container-fluid">
<div class="row-fluid">
<div class="span12">
<h3>
SQL Stat
<a href="sql.json" target="_blank">View JSON API</a>
<span class="pull-right" style="font-size: 16px; margin-right: 20px;">
<label langkey="RefreshPeriod" class="lang" style="display: inline;" for="refreshSecondsSelect">Refresh Period</label>
<select id="refreshSecondsSelect" class="refresh-seconds-select btn" style="width:80px;"
onchange="javascript:druid.sql.refreshSeconds=parseInt(this.options[this.options.selectedIndex].value);">
<option value="5" selected="selected">5s</option>
<option value="10">10s</option>
<option value="20">20s</option>
<option value="30">30s</option>
<option value="60">60s</option>
</select>
<a id="btnSuspendRefresh" langkey="SuspendRefresh" class="btn btn-primary lang"
href="javascript:druid.sql.switchSuspendRefresh();">Suspend Refresh</a>
</span>
<span class="pull-right" style="font-size: 16px; margin-right: 20px;">
<label langkey="ServiceList" class="lang" style="display: inline;" for="refreshServiceSelect">ServiceList</label>
<select id="refreshServiceSelect" class="refresh-seconds-select btn" style="width:200px;"
onchange="javascript:druid.sql.refreshService=this.options[this.options.selectedIndex].value;">
</select>
</span>
</h3>
<table id="dataTable" class="table table-bordered table-striped responsive-utilities">
<thead>
<tr>
<th>N</th>
<th><a id="th-SQL">SQL</a></th>
<th><a id="th-ServiceName">ServiceName</a></th>
<th><a id="th-address">address</a></th>
<th width="50"><a id="th-ExecuteCount" class="lang" langKey="ExecuteCount">ExecCount</a></th>
<th width="50"><a id="th-TotalTime" class="lang" langKey="ExecuteTimeMillis">ExecTime</a></th>
<th width="50" class="langTitle" langKey="MaxTimespanDesc" title="Execute Time Millis Max"><a id="th-MaxTimespan" class="lang"
langKey="MaxTimespan">ExecMax</a></th>
<th width="50" class="langTitle" langKey="InTransactionCountDesc" title="Execute In Transaction Count"><a id="th-InTransactionCount"
class="lang"
langKey="InTransactionCount">Txn</a>
</th>
<th width="50"><a id="th-ErrorCount" class="lang" langKey="ErrorCount">Error</a></th>
<th width="50"><a id="th-EffectedRowCount" class="lang" langKey="JdbcUpdateCount">Update</a></th>
<th width="50"><a id="th-FetchRowCount" class="lang" langKey="JdbcFetchRowCount">FetchRow</a></th>
<th width="50"><a id="th-RunningCount" class="lang" langKey="RunningCount">Running</a></th>
<th width="50"><a id="th-ConcurrentMax" class="lang" langKey="ConcurrentMax">Concurrent</a></th>
<th align="left" width="100"><span class="lang" langKey="ExecHisto">ExecHisto</span> <br/>[
<a id="th-Histogram[0]" class="langTitle" langKey="count1ms" title="count of '0-1 ms'">-</a>
<a id="th-Histogram[1]" class="langTitle" langKey="count10ms" title="count of '1-10 ms'">-</a>
<a id="th-Histogram[2]" class="langTitle" langKey="count100ms" title="count of '10-100 ms'">-</a>
<a id="th-Histogram[3]" class="langTitle" langKey="count1s" title="count of '100ms-1 s'">-</a>
<a id="th-Histogram[4]" class="langTitle" langKey="count10s" title="count of '1-10 s'">-</a>
<a id="th-Histogram[5]" class="langTitle" langKey="count100s" title="count of '10-100 s'">-</a>
<a id="th-Histogram[6]" class="langTitle" langKey="count1000s" title="count of '100-1000 s'">-</a>
<a id="th-Histogram[7]" class="langTitle" langKey="countBg1000s" title="count of '> 1000 s'">-</a> ]
</th>
<th align="left" width="100"><span class="lang" langKey="ExecRsHisto">ExecRsHisto</span> <br/>[
<a id="th-ExecuteAndResultHoldTimeHistogram[0]" class="langTitle" langKey="count1ms" title="count of '0-1 ms'">-</a>
<a id="th-ExecuteAndResultHoldTimeHistogram[1]" class="langTitle" langKey="count10ms" title="count of '1-10 ms'">-</a>
<a id="th-ExecuteAndResultHoldTimeHistogram[2]" class="langTitle" langKey="count100ms" title="count of '10-100 ms'">-</a>
<a id="th-ExecuteAndResultHoldTimeHistogram[3]" class="langTitle" langKey="count1s" title="count of '100ms-1s'">-</a>
<a id="th-ExecuteAndResultHoldTimeHistogram[4]" class="langTitle" langKey="count10s" title="count of '1-10 s'">-</a>
<a id="th-ExecuteAndResultHoldTimeHistogram[5]" class="langTitle" langKey="count100s" title="count of '10-100 s'">-</a>
<a id="th-ExecuteAndResultHoldTimeHistogram[6]" class="langTitle" langKey="count1000s" title="count of '100-1000 s'">-</a>
<a id="th-ExecuteAndResultHoldTimeHistogram[7]" class="langTitle" langKey="countBg1000s" title="count of '> 1000 s'">-</a> ]
</th>
<th align="left" width="100"><span class="lang" langKey="FetchRowHisto">FetchRowHisto</span> <br/>[
<a id="th-FetchRowCountHistogram[0]" class="langTitle" langKey="fetch0" title="count of '0 FetchRow'">-</a>
<a id="th-FetchRowCountHistogram[1]" class="langTitle" langKey="fetch9" title="count of '1-9 FetchRow'">-</a>
<a id="th-FetchRowCountHistogram[2]" class="langTitle" langKey="fetch99" title="count of '10-99 FetchRow'">-</a>
<a id="th-FetchRowCountHistogram[3]" class="langTitle" langKey="fetch999" title="count of '100-999 FetchRow'">-</a>
<a id="th-FetchRowCountHistogram[4]" class="langTitle" langKey="fetch9999" title="count of '1000-9999 FetchRow'">-</a>
<a id="th-FetchRowCountHistogram[5]" class="langTitle" langKey="fetch99999" title="count of '> 9999 FetchRow'">-</a> ]
</th>
<th align="left" width="100"><span class="lang" langKey="UpdateHisto">UpdateHisto</span> <br/>[
<a id="th-EffectedRowCountHistogram[0]" class="langTitle" langKey="update0" title="count of '0 UpdateCount'">-</a>
<a id="th-EffectedRowCountHistogram[1]" class="langTitle" langKey="update9" title="count of '1-9 UpdateCount'">-</a>
<a id="th-EffectedRowCountHistogram[2]" class="langTitle" langKey="update99" title="count of '10-99 UpdateCount'">-</a>
<a id="th-EffectedRowCountHistogram[3]" class="langTitle" langKey="update999" title="count of '100-999 UpdateCount'">-</a>
<a id="th-EffectedRowCountHistogram[4]" class="langTitle" langKey="update9999" title="count of '1000-9999 UpdateCount'">-</a>
<a id="th-EffectedRowCountHistogram[5]" class="langTitle" langKey="update99999" title="count of '> 9999 UpdateCount'">-</a> ]
</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
</div>
</div>
<script type="text/javascript">
$.namespace("druid.sql");
druid.sql = function () {
var dataSourceId = druid.common.getUrlVar("dataSourceId");
return {
init: function () {
druid.sql.refreshService= $("#refreshServiceSelect option").first().val();
var serviceName = druid.sql.refreshService;
$("#dataTable th a").click(function (obj) {
druid.common.setOrderBy(obj.target.id.substring(3))
})
druid.common.buildHead(2);
druid.common.ajaxuri = dataSourceId ? 'sql.json?dataSourceId=' + dataSourceId + '&serviceName=' + serviceName + '&'
: 'sql.json?serviceName=' + serviceName + '&';
druid.common.handleCallback = druid.sql.handleAjaxResult;
druid.common.setOrderBy("SQL");
druid.sql.controlRefresh();
},
controlRefresh: function () {
console.log("serviceName:" + druid.sql.refreshService);
var serviceName = druid.sql.refreshService;
druid.common.ajaxuri = dataSourceId ? 'sql.json?dataSourceId=' + dataSourceId + '&serviceName=' + serviceName + '&'
: 'sql.json?serviceName=' + serviceName + '&';
var FIVE = 5;
if (!druid.sql.refreshSeconds) {
druid.sql.refreshSeconds = FIVE;
}
if (!druid.sql.suspendedSeconds) {
druid.sql.suspendedSeconds = 0;
}
druid.sql.suspendedSeconds += FIVE;
if (!druid.sql.disableAutoRefresh) {
if (druid.sql.suspendedSeconds >= druid.sql.refreshSeconds) {
druid.sql.suspendedSeconds = 0;
druid.common.ajaxRequestForBasicInfo();
}
}
setTimeout(druid.sql.controlRefresh, FIVE * 1000);
},
switchSuspendRefresh: function () {
druid.sql.disableAutoRefresh = !druid.sql.disableAutoRefresh;
if (druid.sql.disableAutoRefresh) {
$("#btnSuspendRefresh").addClass("btn-warning").removeClass("btn-primary");
} else {
$("#btnSuspendRefresh").addClass("btn-primary").removeClass("btn-warning");
}
},
disableAutoRefresh: false,
refreshSeconds: 5,
refreshService: '',
suspendedSeconds: 0,
handleAjaxResult: function (data) {
var sqlStatList = data.Content;
if (sqlStatList == null) return;
var sqlStatTable = document.getElementById("dataTable");
while (sqlStatTable.rows.length > 1) {
sqlStatTable.deleteRow(1);
}
var html = "";
for (var i = 0; i < sqlStatList.length; i++) {
var stat = sqlStatList[i], statSQL = stat.SQL;
var serviceName = stat.Name;
var serviceId = stat.serviceId;
console.log("==========" + serviceId);
var port = stat.port;
var address = stat.address;
var newStatSQL = statSQL.replace(/\"/g, "'").replace(/</g, "&lt;").replace(/>/g, "&gt;");
var newRow = sqlStatTable.insertRow(-1);
html += "<tr>";
html += "<td>" + (i + 1) + "</td>";
// html += "<td>" + '<a data-dismiss="alert" title="'+newStatSQL+'" target="_blank" href="sql-detail.html?sqlId=' + stat.ID + '">' + druid.common.subSqlString(stat.SQL, 25) + '</a>' + "</td>";
html += "<td>" + '<a data-dismiss="alert" title="' + newStatSQL + '" target="_blank" href="sql-detail.html?serviceId=' + serviceId + '&sqlId=' + stat.ID + '">' + druid.common.subSqlString(stat.SQL, 25) + '</a>' + "</td>";
html += "<td>" + '<a data-dismiss="alert" title="' + serviceName + '">' + serviceName + '</a>' + "</td>";
html += "<td>" + address +':'+port+ "</td>";
html += "<td>" + replace(stat.ExecuteCount) + "</td>";
html += "<td>" + replace(stat.TotalTime) + "</td>";
var lastSlowHtml = stat.MaxTimespan;
if (stat.LastSlowParameters != null && stat.LastSlowParameters.length > 0) {
lastSlowHtml = '<a target="_blank" style="color:red" href="sql-detail.html?sqlId=' + stat.ID + '">' + stat.MaxTimespan + '</a>';
}
html += "<td>" + replace(lastSlowHtml) + "</td>";
html += "<td>" + replace(stat.InTransactionCount) + "</td>";
html += "<td>" + replace(stat.ErrorCount) + "</td>";
html += "<td>" + replace(stat.EffectedRowCount) + "</td>";
html += "<td>" + replace(stat.FetchRowCount) + "</td>";
html += "<td>" + replace(stat.RunningCount) + "</td>";
html += "<td>" + replace(stat.ConcurrentMax) + "</td>";
html += "<td>" + '[' + stat.Histogram + ']' + "</td>";
html += "<td>" + '[' + stat.ExecuteAndResultHoldTimeHistogram + ']' + "</td>";
html += "<td>" + '[' + stat.FetchRowCountHistogram + ']' + "</td>";
html += "<td>" + '[' + stat.EffectedRowCountHistogram + ']' + "</td>";
html += "</tr>";
}
$("#dataTable tbody").html(html);
druid.common.stripes();
}
}
}();
$(document).ready(function () {
druid.common.getService();
druid.sql.init();
});
$("#refreshServiceSelect").on("change",function(){
var dataSourceId = druid.common.getUrlVar("dataSourceId");
druid.sql.refreshService = $("#refreshServiceSelect option:selected").val();
druid.common.ajaxuri = dataSourceId ? 'sql.json?dataSourceId=' + dataSourceId + '&serviceName=' + druid.sql.refreshService + '&'
: 'sql.json?serviceName=' + druid.sql.refreshService + '&';
druid.common.ajaxRequestForBasicInfo();
druid.common.handleCallback = druid.sql.handleAjaxResult;
});
</script>
</body>
</html>

View File

@@ -0,0 +1,405 @@
<!doctype html>
<html>
<head>
<title>Druid DataSourceStat</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf8" />
<link href='css/bootstrap.min.css' rel="stylesheet" />
<link href="css/style.css" type="text/css" rel="stylesheet" />
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript" src="js/bootstrap.min.js"></script>
<script src="js/lang.js" type="text/javascript" charset="utf8"></script>
<script src="js/common.js" type="text/javascript" charset="utf8"></script>
</head>
<body>
<div class="container-fluid">
<div class="row-fluid">
<div class="span12">
<h3>
Wall Stat
<a href="wall.json" target="_blank">View JSON API</a>
<span class="pull-right" style="font-size: 16px; margin-right: 20px;">
<label langkey="ServiceList" class="lang" style="display: inline;" for="refreshServiceSelect">ServiceList</label>
<select id="refreshServiceSelect" class="refresh-seconds-select btn" style="width:200px;"
onchange="javascript:druid.wall.refreshService=this.options[this.options.selectedIndex].value;">
</select>
</span>
</h3>
<table id="dataTable" style="background-color: #fff"
class="table table-bordered responsive-utilities">
<tr>
<td valign="top" class="td_lable lang" langKey="CheckCount">
CheckCount</td>
<td id="CheckCount"></td>
<td></td>
</tr>
<tr>
<td valign="top" class="td_lable lang" langKey="HardCheckCount">
HardCheckCount</td>
<td id="HardCheckCount"></td>
<td></td>
</tr>
<tr>
<td valign="top" class="td_lable lang" langKey="ViolationCount">
ViolationCount</td>
<td id="ViolationCount"></td>
<td></td>
</tr>
<tr>
<td valign="top" class="td_lable lang" langKey="BlackListHitCount">
BlackListHitCount</td>
<td id="BlackListHitCount"></td>
<td></td>
</tr>
<tr>
<td valign="top" class="td_lable lang" langKey="BlackListSize">
BlackListSize</td>
<td id="BlackListSize"></td>
<td></td>
</tr>
<tr>
<td valign="top" class="td_lable lang" langKey="WhiteListHitCount">
WhiteListHitCount</td>
<td id="WhiteListHitCount"></td>
<td></td>
</tr>
<tr>
<td valign="top" class="td_lable lang" langKey="WhiteListSize">
WhiteListSize</td>
<td id="WhiteListSize"></td>
<td></td>
</tr>
<tr>
<td valign="top" class="td_lable lang" langKey="SyntaxErrrorCount">
SyntaxErrrorCount</td>
<td id="SyntaxErrrorCount"></td>
<td></td>
</tr>
</table>
<h3 class="lang" langKey="TableStat">Table Stat</h3>
<table id="dataTable1" style="background-color: #fff"
class="table table-bordered table-striped responsive-utilities">
<thead>
<tr>
<th class="td_lable"><a id="th-TableNumber" class="lang"
langKey="TableNumber">TableNumber</a></th>
<th class="td_lable"><a id="th-tableName" class="lang"
langKey="TableName">TableName</a></th>
<th class="td_lable"><a id="th-selectCount" class="lang"
langKey="SelectCount">SelectCount</a></th>
<th class="td_lable"><a id="th-selectIntoCount" class="lang"
langKey="SelectIntoCount">SelectCount</a></th>
<th class="td_lable"><a id="th-insertCount" class="lang"
langKey="InsertCount">InsertCount</a></th>
<th class="td_lable"><a id="th-updateCount" class="lang"
langKey="UpdateCount">UpdateCount</a></th>
<th class="td_lable"><a id="th-deleteCount" class="lang"
langKey="DeleteCount">DeleteCount</a></th>
<th class="td_lable"><a id="th-truncateCount" class="lang"
langKey="TruncateCount">TruncateCount</a></th>
<th class="td_lable"><a id="th-createCount" class="lang"
langKey="CreateCount">CreateCount</a></th>
<th class="td_lable"><a id="th-alterCount" class="lang"
langKey="AlterCount">AlterCount</a></th>
<th class="td_lable"><a id="th-dropCount" class="lang"
langKey="DropCount">DropCount</a></th>
<th class="td_lable"><a id="th-replaceCount" class="lang"
langKey="ReplaceCount">ReplaceCount</a></th>
<th class="td_lable"><a id="th-deleteDataCount" class="lang"
langKey="DeleteDataCount">DeleteDataCount</a></th>
<th align="left" width="100"><span class="lang" langKey="UpdateHisto">DeleteDataHisto</span> <br />[
<a id="th-deleteDataCountHistogram[0]" class="langTitle" langKey="delete0" title="count of '0 DeleteCount'" >-</a>
<a id="th-deleteDataCountHistogram[1]" class="langTitle" langKey="delete9" title="count of '1-9 DeleteCount'" >-</a>
<a id="th-deleteDataCountHistogram[2]" class="langTitle" langKey="delete99" title="count of '10-99 DeleteCount'" >-</a>
<a id="th-deleteDataCountHistogram[3]" class="langTitle" langKey="delete999" title="count of '100-999 DeleteCount'" >-</a>
<a id="th-deleteDataCountHistogram[4]" class="langTitle" langKey="delete9999" title="count of '1000-9999 DeleteCount'" >-</a>
<a id="th-deleteDataCountHistogram[5]" class="langTitle" langKey="delete99999" title="count of '> 9999 DeleteCount'" >-</a> ]
</th>
<th class="td_lable"><a id="th-UpdateDataCount" class="lang"
langKey="UpdateDataCount">UpdateDataCount</a></th>
<th align="left" width="100"><span class="lang" langKey="UpdateHisto">UpdateDataHisto</span> <br />[
<a id="th-updateDataCountHistogram[0]" class="langTitle" langKey="update0" title="count of '0 UpdateCount'" >-</a>
<a id="th-updateDataCountHistogram[1]" class="langTitle" langKey="update9" title="count of '1-9 UpdateCount'" >-</a>
<a id="th-updateDataCountHistogram[2]" class="langTitle" langKey="update99" title="count of '10-99 UpdateCount'" >-</a>
<a id="th-updateDataCountHistogram[3]" class="langTitle" langKey="update999" title="count of '100-999 UpdateCount'" >-</a>
<a id="th-updateDataCountHistogram[4]" class="langTitle" langKey="update9999" title="count of '1000-9999 UpdateCount'" >-</a>
<a id="th-updateDataCountHistogram[5]" class="langTitle" langKey="update99999" title="count of '> 9999 UpdateCount'" >-</a> ]
</th>
<th class="td_lable"><a id="th-FetchRowCount" class="lang"
langKey="FetchRowCount">FetchRowCount</a></th>
<th align="left" width="100"><span class="lang" langKey="FetchRowHisto">FetchRowHisto</span> <br />[
<a id="th-fetchRowCountHistogram[0]" class="langTitle" langKey="fetch0" title="count of '0 FetchRow'" >-</a>
<a id="th-fetchRowCountHistogram[1]" class="langTitle" langKey="fetch9" title="count of '1-9 FetchRow'" >-</a>
<a id="th-fetchRowCountHistogram[2]" class="langTitle" langKey="fetch99" title="count of '10-99 FetchRow'" >-</a>
<a id="th-fetchRowCountHistogram[3]" class="langTitle" langKey="fetch999" title="count of '100-999 FetchRow'" >-</a>
<a id="th-fetchRowCountHistogram[4]" class="langTitle" langKey="fetch9999" title="count of '1000-9999 FetchRow'" >-</a>
<a id="th-fetchRowCountHistogram[5]" class="langTitle" langKey="fetch99999" title="count of '> 9999 FetchRow'" >-</a> ]
</th>
</tr>
</thead>
<tbody></tbody>
</table>
<h3 class="lang" langKey="FunctionStat">Function Stat</h3>
<table id="dataTable2" style="background-color: #fff"
class="table table-bordered responsive-utilities">
<thead>
<tr>
<th class="td_lable">Function Name</th>
<th class="td_lable"><a id="th-invokeCount"
href="javascript:void(0);">InvokeCount</a></th>
</tr>
</thead>
<tbody></tbody>
</table>
<h3 class="lang" langKey="SQLStatWhiteList">SQL Stat - White List</h3>
<table id="dataTable3" style="background-color: #fff"
class="table table-bordered responsive-utilities">
<thead>
<tr>
<th class="td_lable" style="width: 50px;"><span id="WhiteListNumber" class="lang" langKey="TableNumber">TableNumber</span></th>
<th class="td_lable">SQL</th>
<th class="td_lable" ><span id="WhiteListSample" class="lang" langKey="Sample">Sample</span></th>
<th class="td_lable" style="width: 50px;"><span id="WhiteListExecuteCount" class="lang" langKey="ExecuteCount">ExecuteCount</span></th>
<th class="td_lable" style="width: 50px;"><span id="WhiteListExecuteErrorCount" class="lang" langKey="ExecuteErrorCount">ExecuteErrorCount</span></th>
<th class="td_lable" style="width: 50px;"><span id="WhiteListFetchRowCount" class="lang" langKey="FetchRowCount">FetchRowCount</span></th>
<th class="td_lable" style="width: 50px;"><span id="WhiteListUpdateCount" class="lang" langKey="SQLUpdateCount">UpdateCount</span></th>
</tr>
</thead>
<tbody></tbody>
</table>
<h3 class="lang" langKey="SQLStatBlackList">SQL Stat - Black List</h3>
<table id="dataTable4" style="background-color: #fff"
class="table table-bordered responsive-utilities">
<thead>
<tr>
<th class="td_lable" style="width: 50px;"><span id="BlackListNumber" class="lang" langKey="TableNumber">TableNumber</span></th>
<th class="td_lable">SQL</th>
<th class="td_lable" ><span id="BlackListSample" class="lang" langKey="Sample">Sample</span></th>
<th class="td_lable" style="width: 50px;"><span id="violationMessage" class="lang" langKey="violationMessage">violationMessage</span></th>
<th class="td_lable" style="width: 50px;"><span id="BlackListExecuteCount" class="lang" langKey="ExecuteCount">ExecuteCount</span></th>
<th class="td_lable" style="width: 50px;"><span id="BlackListFetchRowCount" class="lang" langKey="FetchRowCount">FetchRowCount</span></th>
<th class="td_lable" style="width: 50px;"><span id="BlackListUpdateCount" class="lang" langKey="SQLUpdateCount">UpdateCount</span></th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
</div>
</div>
<script type="text/javascript">
$.namespace("druid.wall");
druid.wall = function() {
return {
init : function() {
druid.wall.refreshService= $("#refreshServiceSelect option").first().val();
var serviceName = druid.wall.refreshService;
$("#dataTable1 th a").click(function(obj) {
druid.common.setOrderBy(obj.target.id.substring(3))
})
$("#dataTable2 th a").click(function(obj) {
druid.common.setOrderBy(obj.target.id.substring(3))
})
druid.common.buildHead(3);
druid.common.ajaxuri = 'wall.json?serviceName=' + serviceName + '&';
druid.common.handleCallback = druid.wall.handleAjaxResult;
druid.common.ajaxRequestForBasicInfo();
setInterval("druid.common.ajaxRequestForBasicInfo();", 5000);
},
refreshService: '',
handleAjaxResult : function(data) {
$("#CheckCount").text(replace(data.Content.checkCount))
$("#HardCheckCount").text(replace(data.Content.hardCheckCount))
$("#ViolationCount").text(replace(data.Content.violationCount))
$("#BlackListHitCount")
.text(replace(data.Content.blackListHitCount))
$("#BlackListSize").text(replace(data.Content.blackListSize))
$("#WhiteListHitCount")
.text(replace(data.Content.whiteListHitCount))
$("#WhiteListSize").text(replace(data.Content.whiteListSize))
$("#SyntaxErrrorCount")
.text(replace(data.Content.syntaxErrrorCount))
var html = "";
var tables = data.Content.tables;
if (tables) {
for ( var i = 0; i < tables.length; i++) {
var table = tables[i];
html += "<tr>";
html += "<td>" + (i+1) + "</td>";
html += "<td>" + table.name + "</td>";
html += "<td>"
+ replace(table.selectCount) + "</td>";
html += "<td>"
+ replace(table.selectIntoCount) + "</td>";
html += "<td>"
+ replace(table.insertCount) + "</td>";
html += "<td>"
+ replace(table.updateCount) + "</td>";
html += "<td>"
+ replace(table.deleteCount) + "</td>";
html += "<td>"
+ replace(table.truncateCount) + "</td>";
html += "<td>"
+ replace(table.createCount) + "</td>";
html += "<td>"
+ replace(table.alterCount)
+ "</td>";
html += "<td>"
+ replace(table.dropCount)
+ "</td>";
html += "<td>"
+ replace(table.replaceCount) + "</td>";
html += "<td>" + replace(table.deleteDataCount) + "</td>";
if (table.deleteDataCountHistogram === undefined) {
html += "<td></td>";
} else {
html += "<td>" + '[' + table.deleteDataCountHistogram + ']' + "</td>";
}
html += "<td>" + replace(table.updateDataCount) + "</td>";
if (table.updateDataCountHistogram === undefined) {
html += "<td></td>";
} else {
html += "<td>" + '[' + table.updateDataCountHistogram + ']' + "</td>";
}
html += "<td>" + replace(table.fetchRowCount)+ "</td>";
if (table.fetchRowCountHistogram === undefined) {
html += "<td></td>";
} else {
html += "<td>" + '[' + table.fetchRowCountHistogram + ']' + "</td>";
}
html += "</tr>";
}
$("#dataTable1 tbody").html(html);
}
html = "";
var functions = data.Content.functions;
if (functions) {
for ( var i = 0; i < functions.length; i++) {
var fun = functions[i];
html += "<tr>";
html += "<td>" + fun.name + "</td>";
html += "<td>" + fun.invokeCount + "</td>";
html += "</tr>";
}
$("#dataTable2 tbody").html(html);
}
html = "";
var whiteList = data.Content.whiteList;
if (whiteList) {
for ( var i = 0; i < whiteList.length; ++i) {
var white = whiteList[i];
if (white.sql != null) {
white.sql = white.sql.replace(/</g,"&lt;").replace(/>/g,"&gt;");
}
html += "<tr>";
html += "<td>"+ (i+1) +"</td>";
html += '<td style="word-break:break-all">' + white.sql + "</td>";
if (white.sample === undefined) {
html += "<td></td>";
} else {
html += '<td style="word-break:break-all">'
+ white.sample + "</td>";
}
if (white.executeCount === undefined) {
html += "<td></td>";
} else {
html += "<td>" + white.executeCount + "</td>";
}
if (white.executeErrorCount === undefined) {
html += "<td></td>";
} else {
html += "<td>" + white.executeErrorCount + "</td>";
}
if (white.fetchRowCount === undefined) {
html += "<td></td>";
} else {
html += "<td>" + white.fetchRowCount + "</td>";
}
if (white.updateCount === undefined) {
html += "<td></td>";
} else {
html += "<td>" + white.updateCount + "</td>";
}
html += "</tr>";
}
$("#dataTable3 tbody").html(html);
}
html = "";
var blackList = data.Content.blackList;
if (blackList) {
for ( var i = 0; i < blackList.length; ++i) {
var black = blackList[i];
if (black.sql != null) {
black.sql = black.sql.replace(/</g,"&lt;").replace(/>/g,"&gt;");
}
html += "<tr>";
html += "<td>"+ (i+1) +"</td>";
html += '<td style="word-break:break-all">' + black.sql + "</td>";
if (black.sample === undefined) {
html += "<td></td>";
} else {
html += '<td style="word-break:break-all">'
+ black.sample + "</td>";
}
if (black.violationMessage === undefined) {
html += "<td></td>";
} else {
html += "<td>" + black.violationMessage + "</td>";
}
if (black.executeCount === undefined) {
html += "<td></td>";
} else {
html += "<td>" + black.executeCount + "</td>";
}
if (black.fetchRowCount === undefined) {
html += "<td></td>";
} else {
html += "<td>" + black.fetchRowCount + "</td>";
}
if (black.updateCount === undefined) {
html += "<td></td>";
} else {
html += "<td>" + black.updateCount + "</td>";
}
}
$("#dataTable4 tbody").html(html);
}
}
}
}();
$(document).ready(function() {
druid.common.getService();
druid.wall.init();
});
$("#refreshServiceSelect").on("change",function(){
druid.wall.refreshService = $("#refreshServiceSelect option:selected").val();
druid.common.ajaxuri = 'wall.json?serviceName=' + druid.wall.refreshService + '&';
druid.common.ajaxRequestForBasicInfo();
druid.common.handleCallback = druid.wall.handleAjaxResult;
});
</script>
</body>
</html>

View File

@@ -0,0 +1,92 @@
<!doctype html>
<html>
<head>
<title>Druid WebApp Stat</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf8" />
<link href='css/bootstrap.min.css' rel="stylesheet" />
<link href="css/style.css" type="text/css" rel="stylesheet"/>
<script src="js/doT.js" type="text/javascript" charset="utf8"></script>
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript" src="js/bootstrap.min.js"></script>
<script src="js/lang.js" type="text/javascript" charset="utf8"></script>
<script src="js/common.js" type="text/javascript" charset="utf8"></script>
</head>
<body>
<div class="container-fluid">
<div class="row-fluid">
<div class="span12">
<h3>
WebAppStat List
<a href="webapp.json" target="_blank">View JSON API</a>
</h3>
</div>
</div>
</div>
<script type="text/template" id="webapp-template">
{{~ it.content :contextNow:i }}
<ul class="nav nav-tabs" id="datasourceTab{{=i}}">
<li class="active">
<a href="webapp.html#dstab/{{=contextNow.ContextPath}}">WebApp-{{=contextNow.ContextPath}}</a>
</li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="dstab/{{=contextNow.ContextPath}}">
<table class="table table-bordered" style="background-color: #fff">
<tbody>
{{ for(var key in contextNow ) { }}
<tr>
<td valign="top" class="td_lable lang" langKey="{{=key}}">{{=key}}</td>
<td>{{=contextNow[key]}}</td>
</tr>
{{ } }}
</tbody>
</table>
</div>
</div>
{{~ }}
</script>
<script type="text/javascript">
$.namespace("druid.datasource");
druid.datasource = function () {
return {
init : function() {
druid.common.buildHead(4);
this.ajaxRequestForBasicInfo();
},
ajaxRequestForBasicInfo : function() {
$.ajax({
type: 'POST',
url: "webapp.json",
success: function(data) {
var datasourceList = data.Content;
var tmpl = $('#webapp-template').html();
var contents = {'content' : datasourceList};
var doTtmpl = doT.template(tmpl);
var contentHtml = doTtmpl(contents);
$(".span12 h3").after(contentHtml);
$('#datasourceTab a').click(function (e) {
e.preventDefault();
$(this).tab('show');
});
druid.lang.trigger();
},
dataType: "json"
});
}
}
}();
$(document).ready(function() {
druid.datasource.init();
});
</script>
</body>
</html>

View File

@@ -0,0 +1,175 @@
<!doctype html>
<html>
<head>
<title>Druid Web Session Stat</title>
<link href='css/bootstrap.min.css' rel="stylesheet" />
<link href="css/style.css" type="text/css" rel="stylesheet"/>
<script type="text/javascript" src="js/jquery.min.js"></script>
<script src="js/lang.js" type="text/javascript" charset="utf8"></script>
<script src="js/common.js" type="text/javascript" charset="utf8"></script>
</head>
<body>
<div class="container-fluid">
<div class="row-fluid">
<div class="span12">
<h3>
Web Session View
<a id="viewJsonApi" target="_blank">View JSON API</a>
</h3>
<table id="dataTable" class="table table-bordered" style="background-color: #fff">
<tr>
<td class="td_lable lang" langKey="SESSIONID" width='130'> SESSIONID </td>
<td id="SESSIONID"></td>
<td></td>
</tr>
<tr>
<td class="td_lable lang" langKey="UserAgent"> UserAgent </td>
<td id="UserAgent"></td>
<td></td>
</tr>
<tr>
<td class="td_lable lang" langKey="Principal"> Principal </td>
<td id="Principal"></td>
<td></td>
</tr>
<tr>
<td class="td_lable lang" langKey="CreateTime"> CreateTime </td>
<td id="CreateTime"></td>
<td></td>
</tr>
<tr>
<td class="td_lable lang" langKey="LastAccessTime"> LastAccessTime </td>
<td id="LastAccessTime"></td>
<td></td>
</tr>
<tr>
<td class="td_lable lang" langKey="RemoteAddress"> RemoteAddress </td>
<td id="RemoteAddress"></td>
<td></td>
</tr>
<tr>
<td class="td_lable lang" langKey="RequestCount"> RequestCount </td>
<td id="RequestCount"></td>
<td></td>
</tr>
<tr>
<td class="td_lable lang" langKey="RequestTimeMillisTotal"> RequestTimeMillisTotal </td>
<td id="RequestTimeMillisTotal"></td>
<td></td>
</tr>
<tr>
<td class="td_lable lang" langKey="RequestInterval"> RequestInterval </td>
<td id="RequestInterval"></td>
<td></td>
</tr>
<tr>
<td class="td_lable lang" langKey="RunningCount"> RunningCount </td>
<td id="RunningCount"></td>
<td></td>
</tr>
<tr>
<td class="td_lable lang" langKey="ConcurrentMax"> ConcurrentMax </td>
<td id="ConcurrentMax"></td>
<td></td>
</tr>
<tr>
<td class="td_lable lang" langKey="JdbcExecuteCount"> JdbcExecuteCount </td>
<td id="JdbcExecuteCount"></td>
<td></td>
</tr>
<tr>
<td class="td_lable lang" langKey="JdbcExecuteTimeMillis"> JdbcExecuteTimeMillis </td>
<td id="JdbcExecuteTimeMillis"></td>
<td></td>
</tr>
<tr>
<td class="td_lable lang" langKey="JdbcCommitCount"> JdbcCommitCount </td>
<td id="JdbcCommitCount"></td>
<td></td>
</tr>
<tr>
<td class="td_lable lang" langKey="JdbcRollbackCount"> JdbcRollbackCount </td>
<td id="JdbcRollbackCount"></td>
<td></td>
</tr>
<tr>
<td class="td_lable lang" langKey="JdbcFetchRowCount"> JdbcFetchRowCount </td>
<td id="JdbcFetchRowCount"></td>
<td></td>
</tr>
<tr>
<td class="td_lable lang" langKey="JdbcUpdateCount"> JdbcUpdateCount </td>
<td id="JdbcUpdateCount"></td>
<td></td>
</tr>
</table>
<div class="container">
<a class="btn btn-primary" href="javascript:window.close();">Close</a>
</div>
</div>
</div>
</div>
<script type="text/javascript">
$.namespace("druid.websessiondetail");
druid.websessiondetail = function () {
var sessionId = druid.common.getUrlVar("sessionId");
return {
init : function() {
druid.common.buildHead(6);
this.ajaxRequestForBasicInfo();
$("#viewJsonApi").attr("href", 'websession-' + sessionId + '.json');
},
ajaxRequestForBasicInfo : function() {
$.ajax({
type: 'POST',
url: 'websession-' + sessionId + '.json',
success: function(data) {
if (data.Content == null)
return;
$("#SESSIONID").text(data.Content.SESSIONID)
if (data.Content.Principal) {
$("#Principal").text(data.Content.Principal)
}
$("#CreateTime").text(data.Content.CreateTime)
$("#LastAccessTime").text(data.Content.LastAccessTime)
$("#UserAgent").text(data.Content.UserAgent)
$("#RemoteAddress").text(data.Content.RemoteAddress)
$("#RequestCount").text(data.Content.RequestCount)
$("#RequestTimeMillisTotal").text(data.Content.RequestTimeMillisTotal)
$("#RunningCount").text(data.Content.RunningCount)
$("#ConcurrentMax").text(data.Content.ConcurrentMax)
$("#JdbcExecuteCount").text(data.Content.JdbcExecuteCount)
$("#JdbcExecuteTimeMillis").text(data.Content.JdbcExecuteTimeMillis)
$("#JdbcCommitCount").text(data.Content.JdbcCommitCount)
$("#JdbcRollbackCount").text(data.Content.JdbcRollbackCount)
$("#JdbcFetchRowCount").text(data.Content.JdbcFetchRowCount)
$("#JdbcUpdateCount").text(data.Content.JdbcUpdateCount)
var html = '[';
html += '<a title="count of < 1 ms">' + data.Content.RequestInterval[0] + '</a>';
html += ', <a title="count of 1 - 10 ms">' + data.Content.RequestInterval[1] + '</a>';
html += ', <a title="count of 10 - 100 ms">' + data.Content.RequestInterval[2] + '</a>';
html += ', <a title="count of 100 - 1000 ms">' + data.Content.RequestInterval[3] + '</a>';
html += ', <a title="count of 1 - 10 s">' + data.Content.RequestInterval[4] + '</a>';
html += ', <a title="count of 10 - 100 s">' + data.Content.RequestInterval[5] + '</a>';
html += ', <a title="count of 100 - 1000 s">' + data.Content.RequestInterval[6] + '</a>';
html += ', <a title="count of 1000 - 10000 s">' + data.Content.RequestInterval[7] + '</a>';
html += ', <a title="count of > 10000 s">' + data.Content.RequestInterval[8] + '</a>';
html += ']';
$("#RequestInterval").html(html);
},
dataType: "json"
});
}
}
}();
$(document).ready(function() {
druid.websessiondetail.init();
});
</script>
</body>
</html>

View File

@@ -0,0 +1,159 @@
<!doctype html>
<html>
<head>
<title>Druid Web Session Stat</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf8" />
<link href='css/bootstrap.min.css' rel="stylesheet" />
<link href="css/style.css" type="text/css" rel="stylesheet"/>
<script type="text/javascript" src="js/jquery.min.js"></script>
<script src="js/lang.js" type="text/javascript" charset="utf8"></script>
<script src="js/common.js" type="text/javascript" charset="utf8"></script>
</head>
<body>
<div class="container-fluid">
<div class="row-fluid">
<div class="span12">
<h3>
Web Session Stat
<a href="websession.json" target="_blank">View JSON API</a>
<span class="pull-right" style="font-size: 16px; margin-right: 20px;">
<label class="lang" style="display: inline; cursor: pointer;">
<input type="checkbox" id="principalOnlyCheck" style="margin-top: 0px;">
<span langkey="PrincipalOnly" class="lang">Principal Only</span>
<span> | </span>
</label>
<label langkey="RefreshPeriod" class="lang" style="display: inline;" for="refreshSecondsSelect">Refresh Period</label>
<select id="refreshSecondsSelect" class="refresh-seconds-select btn" style="width:80px;" onchange="javascript:druid.websession.refreshSeconds=parseInt(this.options[this.options.selectedIndex].value);">
<option value="5"selected="selected">5s</option>
<option value="10">10s</option>
<option value="20">20s</option>
<option value="30">30s</option>
<option value="60">60s</option>
</select>
<a id="btnSuspendRefresh" langkey="SuspendRefresh" class="btn btn-primary lang" href="javascript:druid.websession.switchSuspendRefresh();">Suspend Refresh</a>
</span>
</h3>
<table id="dataTable" class="table table-bordered table-striped">
<thead>
<tr>
<th>N</th>
<th><a id="th-SESSIONID" class="lang" langKey="SESSIONID">SESSIONID</a></th>
<th><a id="th-Principal" class="lang" langKey="Principal">Principal</a></th>
<th><a id="th-CreateTime" class="lang" langKey="CreateTime">CreateTime</a></th>
<th><a id="th-LastAccessTime" class="lang" langKey="LastAccessTime">LastAccessTime</a></th>
<th><a id="th-RemoteAddress" class="lang" langKey="RemoteAddress">RemoteAddress</a></th>
<th><a id="th-RequestCount" class="lang" langKey="RequestCount">RequestCount</a></th>
<th><a id="th-RequestTimeMillisTotal" class="lang" langKey="RequestTimeMillisTotal">RequestTimeMillisTotal</a></th>
<th><a id="th-RunningCount" class="lang" langKey="RunningCount">RunningCount</a></th>
<th><a id="th-ConcurrentMax" class="lang" langKey="ConcurrentMax">ConcurrentMax</a></th>
<th><a id="th-JdbcExecuteCount" class="lang" langKey="JdbcExecuteCount">JdbcExecuteCount</a></th>
<th><a id="th-JdbcExecuteTimeMillis" class="lang" langKey="JdbcExecuteTimeMillis">JdbcExecuteTimeMillis</a></th>
<th><a id="th-JdbcCommitCount" class="lang" langKey="JdbcCommitCount">JdbcCommitCount</a></th>
<th><a id="th-JdbcRollbackCount" class="lang" langKey="JdbcRollbackCount">JdbcRollbackCount</a></th>
<th><a id="th-JdbcFetchRowCount" class="lang" langKey="JdbcFetchRowCount">JdbcFetchRowCount</a></th>
<th><a id="th-JdbcUpdateCount" class="lang" langKey="JdbcUpdateCount">JdbcUpdateCount</a></th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
</div>
</div>
<script type="text/javascript">
$.namespace("druid.websession");
druid.websession = function () {
return {
init : function() {
$("#dataTable th a").click(function(obj) {
druid.common.setOrderBy(obj.target.id.substring(3))
})
$("#principalOnlyCheck").change(function(obj) {
druid.common.ajaxRequestForBasicInfo();
});
druid.common.buildHead(6);
druid.common.ajaxuri = 'websession.json?';
druid.common.handleCallback = druid.websession.handleAjaxResult;
druid.websession.controlRefresh();
},
controlRefresh : function() {
var FIVE = 5;
if(!druid.websession.refreshSeconds){
druid.websession.refreshSeconds=FIVE;
}
if(!druid.websession.suspendedSeconds){
druid.websession.suspendedSeconds=0;
}
druid.websession.suspendedSeconds += FIVE;
if(!druid.websession.disableAutoRefresh){
if(druid.websession.suspendedSeconds >= druid.websession.refreshSeconds){
druid.websession.suspendedSeconds = 0;
druid.common.ajaxRequestForBasicInfo();
}
}
setTimeout(druid.websession.controlRefresh, FIVE * 1000);
},
switchSuspendRefresh : function() {
druid.websession.disableAutoRefresh = !druid.websession.disableAutoRefresh;
if(druid.websession.disableAutoRefresh){
$("#btnSuspendRefresh").addClass("btn-warning").removeClass("btn-primary");
} else {
$("#btnSuspendRefresh").addClass("btn-primary").removeClass("btn-warning");
}
},
disableAutoRefresh : false,
refreshSeconds : 5,
suspendedSeconds : 0,
handleAjaxResult : function(data) {
var statList = data.Content;
if(statList == null) return;
var sqlStatTable = document.getElementById("dataTable");
while (sqlStatTable.rows.length > 1) {
sqlStatTable.deleteRow(1);
}
var html = "";
var principalOnlyChecked = document.getElementById("principalOnlyCheck").checked;
for ( var i = 0; i < statList.length; i++) {
var stat = statList[i];
if(principalOnlyChecked && !stat.Principal) {
continue;
}
var newRow = sqlStatTable.insertRow(-1);
html += "<tr>";
html += "<td>" + (i + 1) + "</td>";
html += "<td>" + '<a target="_blank" href="websession-detail.html?sessionId=' + stat.SESSIONID + '">' + stat.SESSIONID + '</a>';
if (stat.Principal) {
html += "<td>" + stat.Principal + "</td>";
} else {
html += "<td></td>";
}
html += "<td>" + replace(stat.CreateTime) + "</td>";
html += "<td>" + replace(stat.LastAccessTime) + "</td>";
html += "<td>" + replace(stat.RemoteAddress) + "</td>";
html += "<td>" + replace(stat.RequestCount) + "</td>";
html += "<td>" + replace(stat.RequestTimeMillisTotal) + "</td>";
html += "<td>" + replace(stat.RunningCount) + "</td>";
html += "<td>" + replace(stat.ConcurrentMax) + "</td>";
html += "<td>" + replace(stat.JdbcExecuteCount) + "</td>";
html += "<td>" + replace(stat.JdbcExecuteTimeMillis) + "</td>";
html += "<td>" + replace(stat.JdbcCommitCount) + "</td>";
html += "<td>" + replace(stat.JdbcRollbackCount) + "</td>";
html += "<td>" + replace(stat.JdbcFetchRowCount) + "</td>";
html += "<td>" + replace(stat.JdbcUpdateCount) + "</td>";
html += "</tr>";
}
$("#dataTable tbody").html(html);
druid.common.stripes();
}
}
}();
$(document).ready(function() {
druid.websession.init();
});
</script>
</body>
</html>

View File

@@ -0,0 +1,226 @@
<!doctype html>
<html>
<head>
<title>Druid Web URI Stat</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf8" />
<link href='css/bootstrap.min.css' rel="stylesheet" />
<link href="css/style.css" type="text/css" rel="stylesheet"/>
<script type="text/javascript" src="js/jquery.min.js"></script>
<script src="js/lang.js" type="text/javascript" charset="utf8"></script>
<script src="js/common.js" type="text/javascript" charset="utf8"></script>
</head>
<body>
<div class="container-fluid">
<div class="row-fluid">
<div class="span12">
<h3>
Web URI View
<a id="viewJsonApi" target="_blank">View JSON API</a>
</h3>
<table id="dataTable" class="table table-bordered" style="background-color: #fff">
<tr>
<td class="td_lable lang" langKey="URI"> URI </td>
<td id="URI"></td>
<td></td>
</tr>
<tr>
<td class="td_lable lang" langKey="RequestCount"> RequestCount </td>
<td id="RequestCount"></td>
<td></td>
</tr>
<tr>
<td class="td_lable lang" langKey="RequestTimeMillis"> RequestTimeMillis </td>
<td id="RequestTimeMillis"></td>
<td></td>
</tr>
<tr>
<td class="td_lable lang" langKey="LastAccessTime"> LastAccessTime </td>
<td id="LastAccessTime"></td>
<td></td>
</tr>
<tr>
<td class="td_lable lang" langKey="RunningCount"> RunningCount </td>
<td id="RunningCount"></td>
<td></td>
</tr>
<tr>
<td class="td_lable lang" langKey="ConcurrentMax"> ConcurrentMax </td>
<td id="ConcurrentMax"></td>
<td></td>
</tr>
<tr>
<td class="td_lable lang" langKey="JdbcExecuteCount"> JdbcExecuteCount </td>
<td id="JdbcExecuteCount"></td>
<td></td>
</tr>
<tr>
<td class="td_lable lang" langKey="JdbcExecuteErrorCount"> JdbcExecuteErrorCount </td>
<td id="JdbcExecuteErrorCount"></td>
<td></td>
</tr>
<tr>
<td class="td_lable lang" langKey="JdbcExecutePeak"> JdbcExecutePeak </td>
<td id="JdbcExecutePeak"></td>
<td></td>
</tr>
<tr>
<td class="td_lable lang" langKey="JdbcExecuteTimeMillis"> JdbcExecuteTimeMillis </td>
<td id="JdbcExecuteTimeMillis"></td>
<td></td>
</tr>
<tr>
<td class="td_lable lang" langKey="JdbcCommitCount"> JdbcCommitCount </td>
<td id="JdbcCommitCount"></td>
<td></td>
</tr>
<tr>
<td class="td_lable lang" langKey="JdbcRollbackCount"> JdbcRollbackCount </td>
<td id="JdbcRollbackCount"></td>
<td></td>
</tr>
<tr>
<td class="td_lable lang" langKey="JdbcFetchRowCount"> JdbcFetchRowCount </td>
<td id="JdbcFetchRowCount"></td>
<td></td>
</tr>
<tr>
<td class="td_lable lang" langKey="JdbcFetchRowPeak"> JdbcFetchRowPeak </td>
<td id="JdbcFetchRowPeak"></td>
<td></td>
</tr>
<tr>
<td class="td_lable lang" langKey="JdbcUpdateCount"> JdbcUpdateCount </td>
<td id="JdbcUpdateCount"></td>
<td></td>
</tr>
<tr>
<td class="td_lable lang" langKey="JdbcUpdatePeak"> JdbcUpdatePeak </td>
<td id="JdbcUpdatePeak"></td>
<td></td>
</tr>
<tr>
<td class="td_lable lang" langKey="JdbcPoolConnectionOpenCount"> JdbcPoolConnectionOpenCount </td>
<td id="JdbcPoolConnectionOpenCount"></td>
<td></td>
</tr>
<tr>
<td class="td_lable lang" langKey="JdbcPoolConnectionCloseCount"> JdbcPoolConnectionCloseCount </td>
<td id="JdbcPoolConnectionCloseCount"></td>
<td></td>
</tr>
<tr>
<td class="td_lable lang" langKey="JdbcResultSetOpenCount"> JdbcResultSetOpenCount </td>
<td id="JdbcResultSetOpenCount"></td>
<td></td>
</tr>
<tr>
<td class="td_lable lang" langKey="JdbcResultSetCloseCount"> JdbcResultSetCloseCount </td>
<td id="JdbcResultSetCloseCount"></td>
<td></td>
</tr>
</table>
<h3>Profiles</h3>
<table id="profileDataTable" class="table table-bordered table-striped responsive-utilities">
<thead>
<tr>
<th>N</th>
<th><a id="th-Name" >Name</a></th>
<th>ParentName</th>
<th>Type</th>
<th>ExecuteCount</th>
<th>ExecuteTimeMillis</th>
</tr>
</thead>
<tbody></tbody>
</table>
<div class="container">
<a class="btn btn-primary" href="javascript:window.close();">Close</a>
</div>
</div>
</div>
</div>
<script type="text/javascript">
$.namespace("druid.weburidetail");
druid.weburidetail = function () {
var uri = druid.common.getUrlVar("uri");
return {
init : function() {
druid.common.buildHead(5);
this.ajaxRequestForBasicInfo();
$("#viewJsonApi").attr("href", 'weburi-' + encodeURI(uri) + '.json');
},
ajaxRequestForBasicInfo : function() {
$.ajax({
type: 'POST',
url: 'weburi-' + encodeURI(uri) + '.json',
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);
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 += "<tr>";
html += "<td>" + (i + 1) + "</td>";
html += "<td>" + stat.Name + "</td>";
if (stat.Parent == null) {
html += "<td> </td>";
} else {
html += "<td>" + stat.Parent + "</td>";
}
html += "<td>" + stat.Type + "</td>";
html += "<td>" + stat.ExecuteCount + "</td>";
html += "<td>" + stat.ExecuteTimeMillis + "</td>";
html += "</tr>";
}
$("#profileDataTable tbody").html(html);
druid.lang.trigger();
},
dataType: "json"
});
}
}
}();
$(document).ready(function() {
druid.weburidetail.init();
});
</script>
</body>
</html>

View File

@@ -0,0 +1,175 @@
<!doctype html>
<html>
<head>
<title>Druid Web URI Stat</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf8"/>
<link href='css/bootstrap.min.css' rel="stylesheet"/>
<link href="css/style.css" type="text/css" rel="stylesheet"/>
<script type="text/javascript" src="js/jquery.min.js"></script>
<script src="js/lang.js" type="text/javascript" charset="utf8"></script>
<script src="js/common.js" type="text/javascript" charset="utf8"></script>
</head>
<body>
<div class="container-fluid">
<div class="row-fluid">
<div class="span12">
<h3>
Web URI Stat
<a href="weburi.json" target="_blank">View JSON API</a>
<span class="pull-right" style="font-size: 16px; margin-right: 20px;">
<label langkey="RefreshPeriod" class="lang" style="display: inline;" for="refreshSecondsSelect">Refresh Period</label>
<select id="refreshSecondsSelect" class="refresh-seconds-select btn" style="width:80px;"
onchange="javascript:druid.weburi.refreshSeconds=parseInt(this.options[this.options.selectedIndex].value);">
<option value="5" selected="selected">5s</option>
<option value="10">10s</option>
<option value="20">20s</option>
<option value="30">30s</option>
<option value="60">60s</option>
</select>
<a id="btnSuspendRefresh" langkey="SuspendRefresh" class="btn btn-primary lang"
href="javascript:druid.weburi.switchSuspendRefresh();">Suspend Refresh</a>
</span>
<span class="pull-right" style="font-size: 16px; margin-right: 20px;">
<label langkey="ServiceList" class="lang" style="display: inline;" for="refreshServiceSelect">ServiceList</label>
<select id="refreshServiceSelect" class="refresh-seconds-select btn" style="width:200px;"
onchange="javascript:druid.weburi.refreshService=this.options[this.options.selectedIndex].value;">
</select>
</span>
</h3>
<table id="dataTable" class="table table-bordered table-striped responsive-utilities">
<thead>
<tr>
<th>N</th>
<th><a id="th-URI" class="lang" langKey="URI">URI</a></th>
<th><a id="th-RequestCount" class="lang" langKey="RequestCount">RequestCount</a></th>
<th><a id="th-RequestTimeMillis" class="lang" langKey="RequestTimeMillis">RequestTimeMillis</a></th>
<th><a id="th-RequestTimeMillisMax" class="lang" langKey="RequestTimeMillisMax">RequestTimeMillisMax</a></th>
<th><a id="th-RunningCount" class="lang" langKey="RunningCount">RunningCount</a></th>
<th><a id="th-ConcurrentMax" class="lang" langKey="ConcurrentMax">ConcurrentMax</a></th>
<th><a id="th-JdbcExecuteCount" class="lang" langKey="JdbcExecuteCount">JdbcExecuteCount</a></th>
<th><a id="th-JdbcExecuteErrorCount" class="lang" langKey="JdbcExecuteErrorCount">JdbcExecuteErrorCount</a></th>
<th><a id="th-JdbcExecuteTimeMillis" class="lang" langKey="JdbcExecuteTimeMillis">JdbcExecuteTimeMillis</a></th>
<th><a id="th-JdbcCommitCount" class="lang" langKey="JdbcCommitCount">JdbcCommitCount</a></th>
<th><a id="th-JdbcRollbackCount" class="lang" langKey="JdbcRollbackCount">JdbcRollbackCount</a></th>
<th><a id="th-JdbcFetchRowCount" class="lang" langKey="JdbcFetchRowCount">JdbcFetchRowCount</a></th>
<th><a id="th-JdbcUpdateCount" class="lang" langKey="JdbcUpdateCount">JdbcUpdateCount</a></th>
<th align="left" width="100"><span class="lang" langKey="Histogram">Histogram</span> <br/>[
<a id="th-Histogram[0]" class="langTitle" langKey="count1ms" title="count of '0-1 ms'">-</a>
<a id="th-Histogram[1]" class="langTitle" langKey="count10ms" title="count of '1-10 ms'">-</a>
<a id="th-Histogram[2]" class="langTitle" langKey="count100ms" title="count of '10-100 ms'">-</a>
<a id="th-Histogram[3]" class="langTitle" langKey="count1s" title="count of '100ms-1 s'">-</a>
<a id="th-Histogram[4]" class="langTitle" langKey="count10s" title="count of '1-10 s'">-</a>
<a id="th-Histogram[5]" class="langTitle" langKey="count100s" title="count of '10-100 s'">-</a>
<a id="th-Histogram[6]" class="langTitle" langKey="count1000s" title="count of '100-1000 s'">-</a>
<a id="th-Histogram[7]" class="langTitle" langKey="countBg1000s" title="count of '> 1000 s'">-</a> ]
</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
</div>
</div>
<script type="text/javascript">
$.namespace("druid.weburi");
druid.weburi = function () {
return {
init: function () {
druid.weburi.refreshService = $("#refreshServiceSelect option").first().val();
var serviceName = druid.weburi.refreshService;
$("#dataTable th a").click(function (obj) {
druid.common.setOrderBy(obj.target.id.substring(3))
})
druid.common.buildHead(5);
druid.common.ajaxuri = 'weburi.json?serviceName=' + serviceName + '&';
druid.common.handleCallback = druid.weburi.handleAjaxResult;
druid.common.setOrderBy("URI");
druid.weburi.controlRefresh();
},
controlRefresh: function () {
console.log("serviceName:" + druid.weburi.refreshService);
var serviceName = druid.weburi.refreshService;
druid.common.ajaxuri = 'weburi.json?serviceName=' + serviceName + '&';
var FIVE = 5;
if (!druid.weburi.refreshSeconds) {
druid.weburi.refreshSeconds = FIVE;
}
if (!druid.weburi.suspendedSeconds) {
druid.weburi.suspendedSeconds = 0;
}
druid.weburi.suspendedSeconds += FIVE;
if (!druid.weburi.disableAutoRefresh) {
if (druid.weburi.suspendedSeconds >= druid.weburi.refreshSeconds) {
druid.weburi.suspendedSeconds = 0;
druid.common.ajaxRequestForBasicInfo();
}
}
setTimeout(druid.weburi.controlRefresh, FIVE * 1000);
},
switchSuspendRefresh: function () {
druid.weburi.disableAutoRefresh = !druid.weburi.disableAutoRefresh;
if (druid.weburi.disableAutoRefresh) {
$("#btnSuspendRefresh").addClass("btn-warning").removeClass("btn-primary");
} else {
$("#btnSuspendRefresh").addClass("btn-primary").removeClass("btn-warning");
}
},
disableAutoRefresh: false,
refreshSeconds: 5,
refreshService: '',
suspendedSeconds: 0,
handleAjaxResult: function (data) {
var statList = data.Content;
if (statList == null) return;
var sqlStatTable = document.getElementById("dataTable");
while (sqlStatTable.rows.length > 1) {
sqlStatTable.deleteRow(1);
}
var html = "";
for (var i = 0; i < statList.length; i++) {
var stat = statList[i];
var newRow = sqlStatTable.insertRow(-1);
html += "<tr>";
html += "<td>" + (i + 1) + "</td>";
html += "<td>" + '<a target="_blank" href="weburi-detail.html?uri=' + encodeURI(stat.URI) + '">' + druid.common.subSqlString(stat.URI, 64) + '</a>' + "</td>";
html += "<td>" + replace(stat.RequestCount) + "</td>";
html += "<td>" + replace(stat.RequestTimeMillis) + "</td>";
html += "<td>" + replace(stat.RequestTimeMillisMax) + "</td>";
html += "<td>" + replace(stat.RunningCount) + "</td>";
html += "<td>" + replace(stat.ConcurrentMax) + "</td>";
html += "<td>" + replace(stat.JdbcExecuteCount) + "</td>";
html += "<td>" + replace(stat.JdbcExecuteErrorCount) + "</td>";
html += "<td>" + replace(stat.JdbcExecuteTimeMillis) + "</td>";
html += "<td>" + replace(stat.JdbcCommitCount) + "</td>";
html += "<td>" + replace(stat.JdbcRollbackCount) + "</td>";
html += "<td>" + replace(stat.JdbcFetchRowCount) + "</td>";
html += "<td>" + replace(stat.JdbcUpdateCount) + "</td>";
html += "<td>" + '[' + stat.Histogram + ']' + "</td>";
html += "</tr>";
}
$("#dataTable tbody").html(html);
druid.common.stripes();
}
}
}();
$(document).ready(function () {
druid.common.getService();
druid.weburi.init();
});
$("#refreshServiceSelect").on("change",function(){
druid.weburi.refreshService = $("#refreshServiceSelect option:selected").val();
druid.common.ajaxuri = 'weburi.json?serviceName=' + druid.weburi.refreshService + '&';
druid.common.ajaxRequestForBasicInfo();
druid.common.handleCallback = druid.weburi.handleAjaxResult;
});
</script>
</body>
</html>

View File

@@ -0,0 +1,88 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2018-2025, lengleng All rights reserved.
~
~ Redistribution and use in source and binary forms, with or without
~ modification, are permitted provided that the following conditions are met:
~
~ Redistributions of source code must retain the above copyright notice,
~ this list of conditions and the following disclaimer.
~ Redistributions in binary form must reproduce the above copyright
~ notice, this list of conditions and the following disclaimer in the
~ documentation and/or other materials provided with the distribution.
~ Neither the name of the pig4cloud.com developer nor the names of its
~ contributors may be used to endorse or promote products derived from
~ this software without specific prior written permission.
~ Author: lengleng (wangiegie@gmail.com)
-->
<!--
小技巧: 在根pom里面设置统一存放路径统一管理方便维护
<properties>
<log-path>/Users/lengleng</log-path>
</properties>
1. 其他模块加日志输出直接copy本文件放在resources 目录即可
2. 注意修改 <property name="${log-path}/log.path" value=""/> 的value模块
-->
<configuration debug="false" scan="false">
<property name="log.path" value="logs/${project.artifactId}"/>
<!-- 彩色日志格式 -->
<property name="CONSOLE_LOG_PATTERN"
value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
<!-- 彩色日志依赖的渲染类 -->
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/>
<conversionRule conversionWord="wex"
converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/>
<conversionRule conversionWord="wEx"
converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/>
<!-- Console log output -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
</encoder>
</appender>
<!-- Log file debug output -->
<appender name="debug" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/debug.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${log.path}/%d{yyyy-MM, aux}/debug.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
<maxFileSize>50MB</maxFileSize>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%date [%thread] %-5level [%logger{50}] %file:%line - %msg%n</pattern>
</encoder>
</appender>
<!-- Log file error output -->
<appender name="error" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/error.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${log.path}/%d{yyyy-MM}/error.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
<maxFileSize>50MB</maxFileSize>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%date [%thread] %-5level [%logger{50}] %file:%line - %msg%n</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
</appender>
<logger name="org.activiti.engine.impl.db" level="DEBUG">
<appender-ref ref="debug"/>
</logger>
<!--nacos 心跳 INFO 屏蔽-->
<logger name="com.alibaba.nacos" level="OFF">
<appender-ref ref="error"/>
</logger>
<!-- Level: FATAL 0 ERROR 3 WARN 4 INFO 6 DEBUG 7 -->
<root level="INFO">
<appender-ref ref="console"/>
<appender-ref ref="debug"/>
<appender-ref ref="error"/>
</root>
</configuration>