├── LICENSE
├── README.md
├── demo
└── MySQL Performance Analyzer.pptx
├── myperf
├── README.md
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── com
│ │ └── yahoo
│ │ └── dba
│ │ └── perf
│ │ └── myperf
│ │ ├── .DS_Store
│ │ ├── common
│ │ ├── AlertDefinition.java
│ │ ├── AlertEntry.java
│ │ ├── AlertReport.java
│ │ ├── AlertSettings.java
│ │ ├── AlertSubscribers.java
│ │ ├── Alerts.java
│ │ ├── AppUser.java
│ │ ├── AppUserManager.java
│ │ ├── Auth.java
│ │ ├── ColumnDescriptor.java
│ │ ├── ColumnInfo.java
│ │ ├── CommonUtils.java
│ │ ├── ConfigBlock.java
│ │ ├── ConfigHistory.java
│ │ ├── Constants.java
│ │ ├── CustomResultObject.java
│ │ ├── DBCredential.java
│ │ ├── DBGroupInfo.java
│ │ ├── DBInfoManager.java
│ │ ├── DBInstanceInfo.java
│ │ ├── DBUtils.java
│ │ ├── HipchatIntegration.java
│ │ ├── InstanceStates.java
│ │ ├── InstanceStatesManager.java
│ │ ├── MD5Util.java
│ │ ├── MailUtil.java
│ │ ├── Metric.java
│ │ ├── MetricDataType.java
│ │ ├── MetricsBuffer.java
│ │ ├── MetricsDefManager.java
│ │ ├── MetricsGroup.java
│ │ ├── MetricsResultObject.java
│ │ ├── MetricsSubscribers.java
│ │ ├── MyDatabases.java
│ │ ├── MyPerfConfiguration.java
│ │ ├── MyPerfContext.java
│ │ ├── ProcessListEntry.java
│ │ ├── ProcessListEntryAggregate.java
│ │ ├── ProcessListEntryProcessor.java
│ │ ├── ProcessListSummary.java
│ │ ├── QueryInputValidator.java
│ │ ├── QueryParameters.java
│ │ ├── ResultList.java
│ │ ├── ResultListMerger.java
│ │ ├── ResultListUtil.java
│ │ ├── ResultRow.java
│ │ ├── ResultRowKeyComparator.java
│ │ ├── SNMPSettings.java
│ │ ├── Sql.java
│ │ ├── SqlManager.java
│ │ ├── SqlParameter.java
│ │ ├── StatDefManager.java
│ │ ├── StateSnapshot.java
│ │ ├── UDMManager.java
│ │ ├── UserDefinedMetrics.java
│ │ └── UserReportManager.java
│ │ ├── db
│ │ ├── ConnectionFactory.java
│ │ ├── CustomQueryProcessor.java
│ │ ├── DBConnectionWrapper.java
│ │ ├── DynamicQuery.java
│ │ ├── DynamicQueryFactory.java
│ │ ├── InnoDbMutexPostProccessor.java
│ │ ├── MySQLStatusQueryProcessor.java
│ │ ├── PostQueryResultProcessor.java
│ │ ├── QueryExecutor.java
│ │ ├── ReplLagQueryProcessor.java
│ │ ├── ReplShowProcessor.java
│ │ ├── TableMetaProcessor.java
│ │ └── UserDBConnections.java
│ │ ├── meta
│ │ ├── KeyTool.java
│ │ └── MetaDB.java
│ │ ├── metrics
│ │ ├── DerbyMetricsDb.java
│ │ ├── MetricsDbBase.java
│ │ └── MySQLMetricsDb.java
│ │ ├── process
│ │ ├── AlertReportRunner.java
│ │ ├── AlertScanner.java
│ │ ├── AlertScannerRunner.java
│ │ ├── AutoScanner.java
│ │ ├── GlobalVariableChangeScanTask.java
│ │ ├── MetricScanner.java
│ │ ├── MetricScannerRunner.java
│ │ ├── MetricsRetentionTask.java
│ │ └── MyProfiler.java
│ │ ├── snmp
│ │ ├── SNMPClient.java
│ │ └── SNMPQueryProcessor.java
│ │ └── springmvc
│ │ ├── AlertsController.java
│ │ ├── CredController.java
│ │ ├── DatalistController.java
│ │ ├── DbController.java
│ │ ├── DbsearchController.java
│ │ ├── HelpController.java
│ │ ├── InnoController.java
│ │ ├── LogoutController.java
│ │ ├── MetricsController.java
│ │ ├── MyPerfBaseController.java
│ │ ├── PerfController.java
│ │ ├── ProfileController.java
│ │ ├── QueryController.java
│ │ ├── ReportController.java
│ │ ├── ResourceSessionListener.java
│ │ ├── SettingsController.java
│ │ ├── SigninController.java
│ │ ├── StatusController.java
│ │ ├── TermController.java
│ │ ├── UdmController.java
│ │ ├── UserController.java
│ │ ├── VardiffController.java
│ │ ├── VarhistoryController.java
│ │ └── WebAppUtil.java
│ ├── resources
│ ├── metrics.xml
│ ├── sql.xml
│ └── stats.xml
│ └── webapp
│ ├── WEB-INF
│ ├── decorators.xml
│ ├── dispatcher-servlet.xml
│ ├── jsp
│ │ ├── alerts.jsp
│ │ ├── chart.jsp
│ │ ├── commheader.jsp
│ │ ├── dashboard.jsp
│ │ ├── datalist.jsp
│ │ ├── dbinfo.jsp
│ │ ├── dbsearch.jsp
│ │ ├── help
│ │ │ ├── about.jsp
│ │ │ ├── account.jsp
│ │ │ ├── dbcred.jsp
│ │ │ ├── dbinfo.jsp
│ │ │ ├── m.jsp
│ │ │ ├── mt.jsp
│ │ │ ├── pf.jsp
│ │ │ ├── ps.jsp
│ │ │ ├── rt.jsp
│ │ │ ├── settings.jsp
│ │ │ ├── snmp.jsp
│ │ │ ├── st.jsp
│ │ │ ├── start.jsp
│ │ │ ├── top.jsp
│ │ │ └── udm.jsp
│ │ ├── jsonresult.jsp
│ │ ├── meta.jsp
│ │ ├── profile.jsp
│ │ ├── ps.jsp
│ │ ├── realtime.jsp
│ │ ├── realtop.jsp
│ │ ├── resetpwd.jsp
│ │ ├── settings.jsp
│ │ ├── signin.jsp
│ │ ├── snmp.jsp
│ │ ├── test.jsp
│ │ ├── udm.jsp
│ │ └── userinfo.jsp
│ ├── sitemesh.xml
│ ├── taglib
│ │ ├── messadmin-core.tld
│ │ └── messadmin-fmt.tld
│ └── web.xml
│ ├── css
│ └── theme.css
│ ├── decorators
│ ├── main.jsp
│ └── printable.jsp
│ ├── fonts
│ ├── adsdata-icons.eot
│ ├── adsdata-icons.svg
│ ├── adsdata-icons.ttf
│ ├── adsdata-icons.woff
│ ├── glyphicons-halflings-regular.eot
│ ├── glyphicons-halflings-regular.svg
│ ├── glyphicons-halflings-regular.ttf
│ ├── glyphicons-halflings-regular.woff
│ ├── helveticaneue-light.eot
│ ├── helveticaneue-light.ttf
│ ├── helveticaneue-light.woff
│ ├── helveticaneue-thin.eot
│ ├── helveticaneue-thin.ttf
│ ├── helveticaneue-thin.woff
│ ├── helveticaneue.eot
│ ├── helveticaneue.ttf
│ └── helveticaneue.woff
│ ├── images
│ └── loading.gif
│ ├── img
│ ├── next_arrow.gif
│ ├── save.gif
│ └── ui_active_tab.png
│ ├── includes
│ ├── footer.jsp
│ ├── header.jsp
│ └── style.jsp
│ ├── index.jsp
│ ├── jquery
│ ├── css
│ │ ├── themes
│ │ │ ├── tooltipster-light.css
│ │ │ ├── tooltipster-noir.css
│ │ │ ├── tooltipster-punk.css
│ │ │ └── tooltipster-shadow.css
│ │ ├── tooltipster.css
│ │ └── zTreeStyle
│ │ │ ├── .DS_Store
│ │ │ ├── img
│ │ │ ├── .DS_Store
│ │ │ ├── diy
│ │ │ │ ├── 1_close.png
│ │ │ │ ├── 1_open.png
│ │ │ │ ├── 2.png
│ │ │ │ ├── 3.png
│ │ │ │ ├── 4.png
│ │ │ │ ├── 5.png
│ │ │ │ ├── 6.png
│ │ │ │ ├── 7.png
│ │ │ │ ├── 8.png
│ │ │ │ └── 9.png
│ │ │ ├── line_conn.gif
│ │ │ ├── loading.gif
│ │ │ ├── zTreeStandard.gif
│ │ │ └── zTreeStandard.png
│ │ │ └── zTreeStyle.css
│ ├── datatables
│ │ ├── css
│ │ │ ├── jquery.dataTables.css
│ │ │ └── jquery.dataTables.min.css
│ │ ├── images
│ │ │ ├── Sorting icons.psd
│ │ │ ├── back_disabled.png
│ │ │ ├── back_enabled.png
│ │ │ ├── back_enabled_hover.png
│ │ │ ├── favicon.ico
│ │ │ ├── forward_disabled.png
│ │ │ ├── forward_enabled.png
│ │ │ ├── forward_enabled_hover.png
│ │ │ ├── sort_asc.png
│ │ │ ├── sort_asc_disabled.png
│ │ │ ├── sort_both.png
│ │ │ ├── sort_desc.png
│ │ │ └── sort_desc_disabled.png
│ │ └── js
│ │ │ ├── jquery.dataTables.js
│ │ │ ├── jquery.dataTables.min.js
│ │ │ └── jquery.js
│ └── js
│ │ ├── ZeroClipboard.Core.js
│ │ ├── ZeroClipboard.Core.min.js
│ │ ├── ZeroClipboard.Core.min.map
│ │ ├── ZeroClipboard.js
│ │ ├── ZeroClipboard.min.js
│ │ ├── ZeroClipboard.min.map
│ │ ├── ZeroClipboard.swf
│ │ ├── jquery.tooltipster.js
│ │ ├── jquery.ui-contextmenu.min.js
│ │ ├── jquery.ui-contextmenu.min.js.map
│ │ └── jquery.ztree.core-3.5.min.js
│ └── js
│ ├── common.js
│ ├── d3.v3.min.js
│ ├── d3simplechart.js
│ ├── md5.js
│ └── ui.js
├── perfJettyServer
├── README.md
├── pom.xml
└── src
│ ├── main
│ ├── assemble
│ │ ├── deployable-package.xml
│ │ ├── executable-jar-with-dependencies.xml
│ │ └── scripts
│ │ │ ├── config_default.properties
│ │ │ ├── config_sample.properties
│ │ │ ├── jetty_ssl_sample.sh
│ │ │ ├── start_myperf.sh
│ │ │ └── stop_myperf.sh
│ └── java
│ │ └── com
│ │ └── yahoo
│ │ └── dba
│ │ └── tools
│ │ └── myperfserver
│ │ └── App.java
│ └── test
│ └── java
│ └── com
│ └── yahoo
│ └── dba
│ └── tools
│ └── myperfserver
│ └── AppTest.java
├── pom.xml
└── project
└── pom.xml
/demo/MySQL Performance Analyzer.pptx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yahoo/mysql_perf_analyzer/94a9292bd4cf07062ec6211e8da9077079db0f79/demo/MySQL Performance Analyzer.pptx
--------------------------------------------------------------------------------
/myperf/README.md:
--------------------------------------------------------------------------------
1 | Source code of MySQL Perf Analyzer
--------------------------------------------------------------------------------
/myperf/pom.xml:
--------------------------------------------------------------------------------
1 |
6 |
8 | 4.0.0
9 |
10 | myperf-project
11 | com.yahoo.dba.perf
12 | 2.0.0-SNAPSHOT
13 | ../project/pom.xml
14 |
15 | myperf
16 | war
17 | MySQL Database Performance Tool
18 | http://maven.apache.org
19 |
20 |
21 | javax.servlet
22 | jstl
23 | 1.2
24 | compile
25 |
26 |
27 | javax.servlet
28 | javax.servlet-api
29 | 3.1.0
30 | provided
31 |
32 |
33 | taglibs
34 | standard
35 | 1.1.2
36 |
37 |
38 | opensymphony
39 | sitemesh
40 | 2.4.2
41 |
42 |
43 | org.springframework
44 | spring-core
45 | 4.3.26.RELEASE
46 |
47 |
48 |
49 | org.springframework
50 | spring-webmvc
51 | 4.3.26.RELEASE
52 |
53 |
54 |
55 | org.springframework
56 | spring-mock
57 | test
58 | 2.0.8
59 |
60 |
61 | org.apache.derby
62 | derby
63 | 10.8.1.2
64 |
65 |
66 |
67 | org.snmp4j
68 | snmp4j
69 | 1.10.1
70 |
71 |
72 | junit
73 | junit
74 | 3.8.1
75 | test
76 |
77 |
78 | javax.json
79 | javax.json-api
80 | 1.0
81 |
82 |
83 | org.glassfish
84 | javax.json
85 | 1.0.4
86 |
87 |
88 | org.eclipse.jetty
89 | jetty-servlets
90 | 9.2.7.v20150116
91 |
92 |
93 | mysql
94 | mysql-connector-java
95 | 8.0.19
96 |
97 |
98 |
99 |
100 | thirdparty-releases
101 | JBoss Thirdparty Releases
102 | https://repository.jboss.org/nexus/content/repositories/thirdparty-releases
103 |
104 |
105 | maven2-repository.dev.java.net
106 | Java.net Maven 2 Repository
107 | https://download.java.net/maven/2/
108 |
109 |
110 | jboss-repository.maven2
111 | JBoss Maven 2 Repository
112 | https://repository.jboss.org/maven2/
113 |
114 |
115 |
116 | myperf
117 |
118 |
119 | maven-compiler-plugin
120 | 3.0
121 |
122 | 1.8
123 | 1.8
124 | true
125 | true
126 | true
127 | ${maven.compiler.executable}
128 | 1.6
129 |
130 |
131 |
132 | maven-source-plugin
133 |
134 |
135 | source-jar
136 | deploy
137 |
138 | jar
139 |
140 |
141 |
142 |
143 | true
144 |
145 |
146 |
147 |
148 |
149 |
--------------------------------------------------------------------------------
/myperf/src/main/java/com/yahoo/dba/perf/myperf/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/yahoo/mysql_perf_analyzer/94a9292bd4cf07062ec6211e8da9077079db0f79/myperf/src/main/java/com/yahoo/dba/perf/myperf/.DS_Store
--------------------------------------------------------------------------------
/myperf/src/main/java/com/yahoo/dba/perf/myperf/common/AlertEntry.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015, Yahoo Inc.
3 | * Copyrights licensed under the Apache License.
4 | * See the accompanying LICENSE file for terms.
5 | */
6 | package com.yahoo.dba.perf.myperf.common;
7 |
8 | /**
9 | * Place holder for alert information
10 | * @author xrao
11 | *
12 | */
13 | public class AlertEntry implements java.io.Serializable{
14 | private static final long serialVersionUID = 1L;
15 |
16 | private long ts; //timestamp
17 | private String alertReason;//the type of alert
18 | private String alertValue;//the value triggered alert
19 | private String dbGroup;//database group
20 | private String dbHost;//database server host
21 | public AlertEntry()
22 | {
23 |
24 | }
25 |
26 | public AlertEntry(long ts, String alertReason, String alertValue, String dbGroup, String dbHost)
27 | {
28 | this.ts = ts;
29 | this.alertReason = alertReason;
30 | this.alertValue = alertValue;
31 | this.dbGroup = dbGroup;
32 | this.dbHost = dbHost;
33 | }
34 |
35 | public long getTs() {
36 | return ts;
37 | }
38 | public void setTs(long ts) {
39 | this.ts = ts;
40 | }
41 | public String getAlertReason() {
42 | return alertReason;
43 | }
44 | public void setAlertReason(String alertReason) {
45 | this.alertReason = alertReason;
46 | }
47 | public String getAlertValue() {
48 | return alertValue;
49 | }
50 | public void setAlertValue(String alertValue) {
51 | this.alertValue = alertValue;
52 | }
53 | public String getDbGroup() {
54 | return dbGroup;
55 | }
56 | public void setDbGroup(String dbGroup) {
57 | this.dbGroup = dbGroup;
58 | }
59 | public String getDbHost() {
60 | return dbHost;
61 | }
62 | public void setDbHost(String dbHost) {
63 | this.dbHost = dbHost;
64 | }
65 |
66 | public String getAlertTime()
67 | {
68 | return CommonUtils.formatTimeFromTimestamp(ts, "yyyy-MM-dd HH:mm:ss");
69 | }
70 |
71 | @Override
72 | public String toString() {
73 | StringBuilder sb = new StringBuilder();
74 | sb.append("ALERT: ").append(this.alertReason);
75 | if(this.alertValue != null && !this.alertValue.isEmpty())
76 | sb.append(", ").append(this.alertValue);
77 | sb.append(", ").append(this.dbGroup).append(", ").append(this.dbHost);
78 | sb.append(", TIME: ").append(this.getAlertTime());
79 | return sb.toString();
80 | }
81 |
82 |
83 | }
84 |
--------------------------------------------------------------------------------
/myperf/src/main/java/com/yahoo/dba/perf/myperf/common/Alerts.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015, Yahoo Inc.
3 | * Copyrights licensed under the Apache License.
4 | * See the accompanying LICENSE file for terms.
5 | */
6 | package com.yahoo.dba.perf.myperf.common;
7 |
8 | import java.util.List;
9 |
10 | /**
11 | * For now, it holds alerts for web notification purpose.
12 | * @author xrao
13 | *
14 | */
15 | public class Alerts implements java.io.Serializable{
16 | private static final long serialVersionUID = 1L;
17 | public static final int ALERT_CAPACITY = 100;//hold 100 alerts
18 |
19 | private List entries = null;
20 |
21 | public Alerts()
22 | {
23 | this.entries = new java.util.ArrayList(ALERT_CAPACITY);
24 | }
25 |
26 | /**
27 | * Add a new entry. If list full, remove first one
28 | * @param entry
29 | */
30 | synchronized public void addAlert(AlertEntry entry)
31 | {
32 | if(this.entries.size() >= ALERT_CAPACITY)
33 | this.entries.remove(0);//remove first one
34 | this.entries.add(entry);
35 | }
36 |
37 | /**
38 | * Retrieve a list of alerts later than given ts, up to max
39 | * @param ts
40 | * @return
41 | */
42 | synchronized public List getEntries(long ts, int max)
43 | {
44 | List resList = new java.util.ArrayList();
45 | int cnt = 0;
46 | for(int i=this.entries.size() - 1; i>=0; i--)
47 | {
48 | AlertEntry e = this.entries.get(i);
49 | if(e.getTs() > ts)
50 | {
51 | resList.add(e);
52 | cnt ++;
53 | if(max > 0 && cnt >= max)break;
54 | }
55 | }
56 | return resList;
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/myperf/src/main/java/com/yahoo/dba/perf/myperf/common/AppUser.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015, Yahoo Inc.
3 | * Copyrights licensed under the Apache License.
4 | * See the accompanying LICENSE file for terms.
5 | */
6 | package com.yahoo.dba.perf.myperf.common;
7 |
8 | import java.util.ArrayList;
9 | import java.util.List;
10 |
11 | /**
12 | * an AppUser is the user who is going to use this app.
13 | * @author xrao
14 | *
15 | */
16 | public class AppUser implements java.io.Serializable{
17 | private static final long serialVersionUID = 1L;
18 | public static final int PRIV_USER_STANDARD = 0; //standard user.
19 | public static final int PRIV_USER_POWER = 1; //power user, can manage this app.
20 | public static final int PRIV_USER_RESTRICTED = 2; //restricted user, can only access database groups assgined by admin user.
21 | public static final String SESSION_ATTRIBUTE="APP_USER"; //session handle for AppUser
22 | public static final String SERVER_TS="SERVER_TS"; //server timestamp, use for login
23 | public static final String RANDOM_SEED="RANDOM_SEED"; //random seed
24 |
25 |
26 | private String name;//user name
27 | private String md5Hash;//password hash to login to this site.
28 | private String password;//not really used
29 | private int userprivilege = PRIV_USER_STANDARD;//or uset type
30 | private String email;
31 | private boolean verified = false; //for newly registered user
32 |
33 | public AppUser(){}
34 |
35 | public AppUser(String name)
36 | {
37 | this.name = name;
38 | }
39 |
40 | public String getName()
41 | {
42 | return name;
43 | }
44 |
45 | public void setName(String name) {
46 | this.name = name;
47 | }
48 |
49 | public String getMd5Hash() {
50 | return md5Hash;
51 | }
52 |
53 | public void setMd5Hash(String md5Hash) {
54 | this.md5Hash = md5Hash;
55 | }
56 |
57 | public boolean match(String pwd)
58 | {
59 | try
60 | {
61 | return this.md5Hash.equals(MD5Util.MD5(this.name+":"+pwd));
62 | }catch(Exception ex)
63 | {
64 | return false;
65 | }
66 | }
67 |
68 | public boolean match(String hash, long ts, int seed)
69 | {
70 | if(hash==null)return false;
71 | try
72 | {
73 | return hash.equals(MD5Util.MD5(ts+":"+this.md5Hash+":"+seed));
74 | }catch(Exception ex)
75 | {
76 | return false;
77 | }
78 | }
79 |
80 | public String calMd5(String pwd)
81 | {
82 | try
83 | {
84 | return MD5Util.MD5(this.name+":"+pwd);
85 | }catch(Exception ex)
86 | {
87 | return "0";
88 | }
89 | }
90 |
91 | public String getPassword()
92 | {
93 | return password;
94 | }
95 |
96 | public void setPassword(String password)
97 | {
98 | this.password = password;
99 | }
100 |
101 | public int getUserprivilege()
102 | {
103 | return userprivilege;
104 | }
105 |
106 | public void setUserprivilege(int userprivilege)
107 | {
108 | this.userprivilege = userprivilege;
109 | }
110 |
111 | public boolean isAdminUser()
112 | {
113 | return this.userprivilege == PRIV_USER_POWER;
114 | }
115 |
116 | public boolean isRestrictedUser()
117 | {
118 | return this.userprivilege == PRIV_USER_RESTRICTED;
119 | }
120 | public String getEmail()
121 | {
122 | return email;
123 | }
124 |
125 | public void setEmail(String email)
126 | {
127 | this.email = email;
128 | }
129 |
130 | public boolean matchPassword(String pd)
131 | {
132 | if(pd==null)return false;//we always need password
133 | return this.calMd5(pd).equals(this.md5Hash);
134 | }
135 |
136 | private final static String LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
137 |
138 | /**
139 | * Utility to generate random password
140 | * @return
141 | */
142 | public static String geterateRandomPwd()
143 | {
144 | char mypwd[] = new char[8];
145 | char[] chars = LETTERS.toCharArray();
146 | for(int i=0;i<8;i++)
147 | {
148 | mypwd[i] = chars[(int)(Math.floor(Math.random()*chars.length))];
149 | }
150 | return new String(mypwd);
151 | }
152 |
153 | public boolean isVerified() {
154 | return verified;
155 | }
156 |
157 | public void setVerified(boolean verified) {
158 | this.verified = verified;
159 | }
160 |
161 | }
162 |
--------------------------------------------------------------------------------
/myperf/src/main/java/com/yahoo/dba/perf/myperf/common/AppUserManager.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015, Yahoo Inc.
3 | * Copyrights licensed under the Apache License.
4 | * See the accompanying LICENSE file for terms.
5 | */
6 | package com.yahoo.dba.perf.myperf.common;
7 |
8 | import java.io.Serializable;
9 | import java.util.Map;
10 |
11 | import com.yahoo.dba.perf.myperf.meta.MetaDB;
12 |
13 | public class AppUserManager implements Serializable{
14 | private static final long serialVersionUID = 1L;
15 | private Map userMap = new java.util.HashMap();
16 | private MetaDB metaDb; //to access meta db for persistent actions
17 |
18 | public AppUserManager(){}
19 |
20 | /**
21 | * get user by id
22 | * @param name
23 | * @return
24 | */
25 | synchronized public AppUser getUser(String name)
26 | {
27 | if(name == null || name.isEmpty()) return null;
28 | if(this.userMap.containsKey(name))return this.userMap.get(name);
29 |
30 | if(this.metaDb != null)
31 | {
32 | AppUser appUser = this.metaDb.retrieveUserInfo(name);
33 | if(appUser != null)this.addUser(appUser);
34 | return appUser;
35 | }
36 | return null;
37 | }
38 |
39 | synchronized public void addUser(AppUser user)
40 | {
41 | this.userMap.put(user.getName(), user);
42 | }
43 |
44 | public java.util.Map getUserMap()
45 | {
46 | return java.util.Collections.unmodifiableMap(this.userMap);
47 | }
48 |
49 | public MetaDB getMetaDb() {
50 | return metaDb;
51 | }
52 |
53 | public void setMetaDb(MetaDB metaDb) {
54 | this.metaDb = metaDb;
55 | }
56 |
57 | public AppUser retrieveUserInfoFromMetaDB(String username)
58 | {
59 | return metaDb.retrieveUserInfo(username);
60 | }
61 |
62 | public boolean storeNewPassword(String username, String newpwd)
63 | {
64 | return this.metaDb.changePasssword(username, newpwd);
65 | }
66 |
67 | public void updatePasswordCache(String username, String passwd)
68 | {
69 | AppUser au = this.getUser(username.toLowerCase());
70 | if(au!=null)
71 | au.setMd5Hash(au.calMd5(passwd));
72 | }
73 |
74 | public boolean storeEmail(String username, String email)
75 | {
76 | return this.metaDb.changeEmail(username, email);
77 | }
78 |
79 | public void updateEmailCache(String username, String email)
80 | {
81 | AppUser au = this.getUser(username.toLowerCase());
82 | if(au!=null)
83 | au.setEmail(email);
84 | }
85 |
86 | public boolean storePrivilege(String username, int priv)
87 | {
88 | return this.metaDb.changePrivilege(username, priv);
89 | }
90 |
91 | public void updateprivilegeCache(String username, int priv)
92 | {
93 | AppUser au = this.getUser(username.toLowerCase());
94 | if(au!=null)
95 | au.setUserprivilege(priv==AppUser.PRIV_USER_POWER?AppUser.PRIV_USER_POWER:AppUser.PRIV_USER_STANDARD);
96 | }
97 |
98 | public void confirmNewUser(String username, boolean confirmed)
99 | {
100 | if(this.metaDb.confirmUser(username, confirmed))
101 | {
102 | AppUser au = this.getUser(username.toLowerCase());
103 | if(au!=null)
104 | au.setVerified(confirmed);
105 | }
106 | }
107 |
108 | public boolean deleteUser(String username)
109 | {
110 | boolean ret = this.metaDb.deleteUser(username);
111 | if(ret)
112 | this.userMap.remove(username);
113 | return ret;
114 | }
115 | /**
116 | * Add a new user. Return AppUser object if succeed. Otherwise null.
117 | * @param userame
118 | * @param pwd
119 | * @param priv
120 | * @param email
121 | * @param confirmed If a user is added by admin, set it as confirmed
122 | * @return
123 | */
124 | public AppUser addNewUser(String username, String pwd, String priv, String email, boolean confirmed)
125 | {
126 | if(this.retrieveUserInfoFromMetaDB(username)!=null)
127 | return null;
128 |
129 | AppUser newUser = new AppUser();
130 | newUser.setName(username.trim().toLowerCase());
131 | newUser.setPassword(pwd);
132 | newUser.setUserprivilege(AppUser.PRIV_USER_STANDARD);
133 | newUser.setEmail(email);
134 | newUser.setVerified(confirmed);
135 | try
136 | {
137 | int privInt = Integer.parseInt(priv);
138 | if(privInt == AppUser.PRIV_USER_POWER || privInt == AppUser.PRIV_USER_RESTRICTED)
139 | newUser.setUserprivilege(privInt);
140 | //otherwise standard
141 | }catch(Exception ex){}
142 | newUser.setMd5Hash(newUser.calMd5(newUser.getPassword()));
143 | metaDb.upsertAppUser(newUser);//save to db
144 | this.addUser(newUser);//add to cache
145 | return newUser;
146 | }
147 | }
148 |
--------------------------------------------------------------------------------
/myperf/src/main/java/com/yahoo/dba/perf/myperf/common/Auth.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015, Yahoo Inc.
3 | * Copyrights licensed under the Apache License.
4 | * See the accompanying LICENSE file for terms.
5 | */
6 | package com.yahoo.dba.perf.myperf.common;
7 |
8 | import javax.servlet.http.HttpServletRequest;
9 | import javax.servlet.http.HttpSession;
10 |
11 | import com.yahoo.dba.perf.myperf.springmvc.WebAppUtil;
12 |
13 | /**
14 | * First we move all auth (authentication/authorization) related functions together
15 | * TODO add retry count
16 | * @author xrao
17 | *
18 | */
19 | public class Auth {
20 |
21 | private MyPerfContext context;
22 |
23 | public Auth()
24 | {
25 |
26 | }
27 |
28 | public Auth(MyPerfContext ctx)
29 | {
30 | this.context = ctx;
31 | }
32 |
33 |
34 | /**
35 | * Find user by name. Return null if not found
36 | * @param name
37 | * @return
38 | */
39 | public AppUser findUserByName(String name)
40 | {
41 | if(name==null||name.isEmpty())return null;
42 | String username = name.trim().toLowerCase();
43 | //find the user from the system cache
44 | AppUser appUser = this.context.getUserManager().getUser(username);
45 | if(appUser != null)return appUser;
46 | //find the user from db and add it to system cache
47 | appUser = this.context.getUserManager().retrieveUserInfoFromMetaDB(username);
48 | if(appUser!=null)
49 | this.context.getUserManager().addUser(appUser);
50 | return appUser;
51 | }
52 |
53 | public boolean login(AppUser appUser, HttpServletRequest request)
54 | {
55 | if(appUser==null)return false;
56 |
57 | //check if login session timed out
58 | HttpSession sess = request.getSession();
59 | if(sess!=null)//if no more session, we cannot login
60 | {
61 | long stored_server_ts = System.currentTimeMillis();
62 | if(sess.getAttribute(AppUser.SERVER_TS)!=null)
63 | stored_server_ts = (Long)sess.getAttribute(AppUser.SERVER_TS);
64 | int stored_seed = (int)(Math.random()*Integer.MAX_VALUE);
65 | if(sess.getAttribute(AppUser.RANDOM_SEED)!=null)
66 | stored_seed = (Integer)sess.getAttribute(AppUser.RANDOM_SEED);
67 | boolean authed = appUser.match(request.getParameter("s"), stored_server_ts, stored_seed);
68 | if(authed)
69 | {
70 | String user = null;
71 | try{user = WebAppUtil.findUserFromRequest(request);}catch(Exception ex){};
72 | if(!appUser.getName().equalsIgnoreCase(user))
73 | {
74 | sess.invalidate();
75 | sess = request.getSession(true);//get a new session
76 | }
77 | }
78 | sess.setAttribute(AppUser.SESSION_ATTRIBUTE, appUser);
79 | sess.removeAttribute(AppUser.SERVER_TS);
80 | sess.removeAttribute(AppUser.RANDOM_SEED);
81 | return authed;
82 | }
83 | return false;
84 | }
85 | public MyPerfContext getContext() {
86 | return context;
87 | }
88 |
89 | public void setContext(MyPerfContext context) {
90 | this.context = context;
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/myperf/src/main/java/com/yahoo/dba/perf/myperf/common/ColumnDescriptor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015, Yahoo Inc.
3 | * Copyrights licensed under the Apache License.
4 | * See the accompanying LICENSE file for terms.
5 | */
6 | package com.yahoo.dba.perf.myperf.common;
7 |
8 | /**
9 | * Information about the columns from the a query retiurn results
10 | * @author xrao
11 | *
12 | */
13 | public class ColumnDescriptor implements java.io.Serializable{
14 |
15 | private static final long serialVersionUID = 6923318258330634209L;
16 |
17 | private java.util.List columns ;
18 |
19 | public ColumnDescriptor()
20 | {
21 | columns = new java.util.ArrayList();
22 | }
23 |
24 | public java.util.List getColumns() {
25 | return columns;
26 | }
27 |
28 | public void setColumns(java.util.List columns) {
29 | this.columns = columns;
30 | }
31 |
32 | public ColumnInfo getColumn(String colName)
33 | {
34 | for(int i=this.columns.size()-1;i>=0;i--)
35 | {
36 | if(colName.equalsIgnoreCase(this.columns.get(i).getName()))return this.columns.get(i);
37 | }
38 | return null;
39 | }
40 | public int getColumnIndex(String colName)
41 | {
42 | for(int i=this.columns.size()-1;i>=0;i--)
43 | {
44 | if(colName.equalsIgnoreCase(this.columns.get(i).getName()))return i;
45 | }
46 | return -1;
47 | }
48 |
49 | public void addColumn(String colName, boolean isNumber, int pos)
50 | {
51 | if(this.columns==null)this.columns = new java.util.ArrayList();
52 | ColumnInfo col = new ColumnInfo();
53 | col.setName(colName);
54 | col.setNumberType(isNumber);
55 | col.setPosition(pos);
56 | this.columns.add(col);
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/myperf/src/main/java/com/yahoo/dba/perf/myperf/common/ColumnInfo.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015, Yahoo Inc.
3 | * Copyrights licensed under the Apache License.
4 | * See the accompanying LICENSE file for terms.
5 | */
6 | package com.yahoo.dba.perf.myperf.common;
7 |
8 | /**
9 | * Result column descriptor
10 | * @author xrao
11 | *
12 | */
13 | public class ColumnInfo implements java.io.Serializable{
14 |
15 | private static final long serialVersionUID = 2467837325706019159L;
16 | private String name;//name of the column
17 | private int position;//position of the column
18 | private boolean numberType;//no need to quote number type
19 | private int maxLength = 0;//used for formatting
20 |
21 | //support repository
22 | private String dbDataType;//data type of the database column
23 | private String javaType;//data type in java
24 | private String javaName;//java bean member name
25 | private String srcName;//column name from source Oracle database
26 |
27 | public ColumnInfo()
28 | {
29 |
30 | }
31 |
32 | public ColumnInfo(String name)
33 | {
34 | this.name = name;
35 | }
36 |
37 | public String getName() {
38 | return name;
39 | }
40 |
41 | public void setName(String name) {
42 | this.name = name;
43 | }
44 |
45 | public int getPosition() {
46 | return position;
47 | }
48 |
49 | public void setPosition(int position) {
50 | this.position = position;
51 | }
52 |
53 | public boolean isNumberType() {
54 | return numberType;
55 | }
56 |
57 | public void setNumberType(boolean numberType) {
58 | this.numberType = numberType;
59 | }
60 |
61 | public ColumnInfo copy()
62 | {
63 | ColumnInfo colInfo = new ColumnInfo(this.name);
64 | colInfo.setNumberType(this.numberType);
65 | return colInfo;
66 | }
67 |
68 | public int getMaxLength() {
69 | return maxLength;
70 | }
71 |
72 | public void setMaxLength(int maxLength) {
73 | this.maxLength = maxLength;
74 | }
75 |
76 | public String getDbDataType() {
77 | return dbDataType;
78 | }
79 |
80 | public void setDbDataType(String dbDataType) {
81 | this.dbDataType = dbDataType;
82 | }
83 |
84 | public String getJavaType() {
85 | return javaType;
86 | }
87 |
88 | public void setJavaType(String javaType) {
89 | this.javaType = javaType;
90 | }
91 |
92 | public String getJavaName() {
93 | return javaName;
94 | }
95 |
96 | public void setJavaName(String javaName) {
97 | this.javaName = javaName;
98 | }
99 |
100 | public String getSrcName() {
101 | return srcName;
102 | }
103 |
104 | public void setSrcName(String srcName) {
105 | this.srcName = srcName;
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/myperf/src/main/java/com/yahoo/dba/perf/myperf/common/CommonUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015, Yahoo Inc.
3 | * Copyrights licensed under the Apache License.
4 | * See the accompanying LICENSE file for terms.
5 | */
6 | package com.yahoo.dba.perf.myperf.common;
7 |
8 | import java.util.Date;
9 | import java.util.Map;
10 | import java.util.TimeZone;
11 |
12 | /**
13 | * Some common utility functions are consolidated here for reuse purpose
14 | * @author xrao
15 | *
16 | */
17 | public class CommonUtils {
18 | public static long getMapValueLong(Map map, String key, long def)
19 | {
20 | if(map==null)return def;
21 | if(!map.containsKey(key))return def;
22 | try
23 | {
24 | return Long.parseLong(map.get(key));
25 | }catch(Exception ex)
26 | {
27 | return def;
28 | }
29 | }
30 | public static float getMapValueFloat(Map map, String key, float def)
31 | {
32 | if(map==null)return def;
33 | if(!map.containsKey(key))return def;
34 | try
35 | {
36 | return Float.parseFloat(map.get(key));
37 | }catch(Exception ex)
38 | {
39 | return def;
40 | }
41 | }
42 |
43 | public static String escapeJsonHTML(String str)
44 | {
45 | if(str==null)return "";
46 | StringBuilder sb = new StringBuilder(str.length());
47 | char[] carray = str.toCharArray();
48 | for(int i=0;i variables;//well, in MySQL, there are called variables
25 |
26 | public ConfigBlock()
27 | {
28 | this.variables = new TreeMap();
29 | }
30 |
31 | public String getTime() {
32 | return time;
33 | }
34 |
35 | public void setTime(String time) {
36 | this.time = time;
37 | }
38 |
39 | public Map getVariables() {
40 | return variables;
41 | }
42 |
43 | public void setVariables(Map variables) {
44 | this.variables = variables;
45 | }
46 |
47 | public void addVariable(String name, String value)
48 | {
49 | this.variables.put(name, value);
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/myperf/src/main/java/com/yahoo/dba/perf/myperf/common/Constants.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015, Yahoo Inc.
3 | * Copyrights licensed under the Apache License.
4 | * See the accompanying LICENSE file for terms.
5 | */
6 | package com.yahoo.dba.perf.myperf.common;
7 |
8 | public class Constants
9 | {
10 | //Analyzer version
11 | public static final String VERSION = "2.0";
12 |
13 | //Status
14 | public static final int STATUS_OK = 0;
15 | public static final int STATUS_BAD = -1;
16 |
17 | // DB instance management action
18 | public static final int DBM_ACTION_ADD_CLUSTER=0;
19 | public static final int DBM_ACTION_ADD_CLUSTER_USING_VIP=1;
20 | public static final int DBM_ACTION_ADD_HOST=2;
21 | public static final int DBM_ACTION_UPDATE_HOST=3;
22 | public static final int DBM_ACTION_REMOVE_HOST=4;
23 | public static final int DBM_ACTION_REMOVE_CLUSTER=5;
24 | public static final int DBM_ACTION_RENAME_CLUSTER=6;
25 | public static final int DBM_ACTION_ACL=7;
26 |
27 | public static final String URL_PATH_CMD = "CMD";
28 | public static final String URL_PATH_DBGROUP = "DBGROUP";
29 | public static final String URL_PATH_DBHOST = "DBHOST";
30 | public static final String URL_PATH_METRICS = "METRICS";
31 | public static final String URL_PATH_START_TS = "START_TS";
32 | public static final String URL_PATH_END_TS = "END_TS";
33 | public static final String URL_PATH_ALERT_TYPE = "ALERT_TYPE";
34 |
35 | public static final String SESSION_DEBUG="sess_debug";
36 |
37 | public static final String CONN_MSG_NORETRY = "CONN_NO_RETRY";
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/myperf/src/main/java/com/yahoo/dba/perf/myperf/common/CustomResultObject.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015, Yahoo Inc.
3 | * Copyrights licensed under the Apache License.
4 | * See the accompanying LICENSE file for terms.
5 | */
6 | package com.yahoo.dba.perf.myperf.common;
7 |
8 | /**
9 | * An app specific object to be inserted into ResultList as part of result header
10 | * @author xrao
11 | *
12 | */
13 | public interface CustomResultObject extends java.io.Serializable{
14 | String getName();//the name/key in json ResultList
15 | String getValueJsonString();//the value in json ResultList
16 | }
17 |
--------------------------------------------------------------------------------
/myperf/src/main/java/com/yahoo/dba/perf/myperf/common/DBCredential.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015, Yahoo Inc.
3 | * Copyrights licensed under the Apache License.
4 | * See the accompanying LICENSE file for terms.
5 | */
6 | package com.yahoo.dba.perf.myperf.common;
7 |
8 | import com.yahoo.dba.perf.myperf.meta.KeyTool;
9 |
10 | /**
11 | * Database access user name and password
12 | * @author xrao
13 | *
14 | */
15 | public class DBCredential implements java.io.Serializable{
16 |
17 | private static final long serialVersionUID = 1L;
18 |
19 | private String appUser;//the user stores this db username/password pair
20 | private String username;//db username
21 | private String password;//db password
22 | private String dbGroupName;//the name of the database group
23 |
24 | private String encrypted; //encypted password
25 |
26 | public DBCredential()
27 | {
28 | }
29 |
30 | public String getAppUser()
31 | {
32 | return appUser;
33 | }
34 |
35 | public void setAppUser(String appUser)
36 | {
37 | this.appUser = appUser;
38 | }
39 |
40 | public String getUsername()
41 | {
42 | return username;
43 | }
44 |
45 | public void setUsername(String username)
46 | {
47 | this.username = username;
48 | }
49 |
50 | public String getPassword()
51 | {
52 | return password;
53 | }
54 |
55 | public void setPassword(String password)
56 | {
57 | this.password = password;
58 | }
59 |
60 | /**
61 | * Retrun a copy
62 | * @return
63 | */
64 | public DBCredential copy()
65 | {
66 | DBCredential cred = new DBCredential();
67 | cred.setAppUser(this.appUser);
68 | cred.setDbGroupName(this.dbGroupName);
69 | cred.setUsername(this.username);
70 | cred.setPassword(this.password);
71 | cred.setEncrypted(encrypted);
72 | return cred;
73 | }
74 |
75 | public String getDbGroupName()
76 | {
77 | return dbGroupName;
78 | }
79 |
80 | public void setDbGroupName(String dbname)
81 | {
82 | this.dbGroupName = dbname;
83 | }
84 |
85 | public String getEncrypted() {
86 | return encrypted;
87 | }
88 |
89 | public void setEncrypted(String encrypted) {
90 | this.encrypted = encrypted;
91 | }
92 |
93 | /**
94 | * Invoke this method if password is encrypted
95 | * @param keyTool
96 | */
97 | public void decryptPassword(KeyTool.DesEncrypter keyTool)
98 | {
99 | if(encrypted == null)
100 | return;
101 | String credString = keyTool.decrypt(encrypted);
102 | credString = credString.substring(0, credString.lastIndexOf("::"));
103 | credString = credString.substring(credString.lastIndexOf("::")+2);
104 | this.password = credString;
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/myperf/src/main/java/com/yahoo/dba/perf/myperf/common/DBGroupInfo.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015, Yahoo Inc.
3 | * Copyrights licensed under the Apache License.
4 | * See the accompanying LICENSE file for terms.
5 | */
6 | package com.yahoo.dba.perf.myperf.common;
7 |
8 | import java.util.List;
9 |
10 | /**
11 | * Information about a group of DB, such as a DB cluster
12 | * @author xrao
13 | *
14 | */
15 | public class DBGroupInfo implements java.io.Serializable
16 | {
17 | private static final long serialVersionUID = 1L;
18 | private List instances = new java.util.ArrayList();
19 | private String groupName;
20 |
21 | public DBGroupInfo()
22 | {
23 | }
24 |
25 | public List getInstances()
26 | {
27 | return instances;
28 | }
29 | public DBInstanceInfo getInstance(int instanceNumber)
30 | {
31 | for(DBInstanceInfo inst:instances)
32 | {
33 | if(instanceNumber==inst.getInstance())return inst;
34 | }
35 | return null;
36 | }
37 |
38 | /**
39 | * If all hosts can be accessed directly
40 | * @return
41 | */
42 | public boolean canAccessDirectly()
43 | {
44 | for(DBInstanceInfo inst:instances)
45 | {
46 | if(!inst.isConnectionVerified())return false;
47 | }
48 | return true;
49 | }
50 |
51 | public DBInstanceInfo findInstanceByHost(String hostname)
52 | {
53 | for(DBInstanceInfo dbinfo: this.instances)
54 | {
55 | if(hostname.equalsIgnoreCase(dbinfo.getHostName()))
56 | return dbinfo;
57 | }
58 | return null;
59 | }
60 |
61 | public void addOrUpdateInstance(DBInstanceInfo dbinfo)
62 | {
63 | DBInstanceInfo db = findInstanceByHost(dbinfo.getHostName());
64 | if(db==null)
65 | this.instances.add(dbinfo);
66 | else
67 | {
68 | db.setPort(dbinfo.getPort());
69 | db.setDatabaseName(dbinfo.getDatabaseName());
70 | db.setUseTunneling(dbinfo.isUseTunneling());
71 | db.setLocalHostName(dbinfo.getLocalHostName());
72 | db.setLocalPort(dbinfo.getLocalPort());
73 | db.setInstance(dbinfo.getInstance());
74 | db.setConnectionVerified(dbinfo.isConnectionVerified());
75 | }
76 | }
77 |
78 | public String getGroupName()
79 | {
80 | return groupName;
81 | }
82 |
83 | public void setGroupName(String groupName)
84 | {
85 | this.groupName = groupName;
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/myperf/src/main/java/com/yahoo/dba/perf/myperf/common/HipchatIntegration.java:
--------------------------------------------------------------------------------
1 | package com.yahoo.dba.perf.myperf.common;
2 |
3 | import java.net.HttpURLConnection;
4 | import java.net.UnknownHostException;
5 | import java.util.logging.Level;
6 | import java.util.logging.Logger;
7 |
8 | /**
9 | * Add Hipchat integration. So far it is only for alert notification purpose.
10 | * We can add command notification in the future.
11 | * @author xrao
12 | *
13 | */
14 | public class HipchatIntegration {
15 | private static Logger logger = Logger.getLogger(HipchatIntegration.class.getName());
16 |
17 | private String hipchatURL; //must be in the format like https://xxx.hipchat.com/v2/room/{roomnumber}/notification?
18 | private String authToken; //we will append authToken to construct the full url
19 | private String hostname;
20 | private boolean enabled = false;
21 | public HipchatIntegration()
22 | {
23 |
24 | }
25 |
26 | public void init(MyPerfContext ctx){
27 | this.enabled = false;
28 | try {
29 | this.hostname = java.net.InetAddress.getLocalHost().getHostName();
30 | } catch (UnknownHostException e) {
31 | logger.log(Level.WARNING, "Failed to get local host name", e);
32 | }
33 | this.hipchatURL = ctx.getMyperfConfig().getHipchatUrl();
34 | this.authToken = ctx.getMyperfConfig().getHipchatAuthToken();
35 | if(authToken != null && !authToken.isEmpty()
36 | && hipchatURL != null && !hipchatURL.isEmpty())this.enabled = true;
37 | if(this.enabled){
38 | //do a test
39 | this.enabled = this.sendMessage("MySQL Perf Analzyer Hipchat Integration Initiated on " + this.hostname);
40 | if(this.enabled){
41 | logger.info("Hipchat integration is enabed.");
42 | }
43 | }
44 | }
45 |
46 | public String getHipchatURL() {
47 | return hipchatURL;
48 | }
49 |
50 | public void setHipchatURL(String hipchatURL) {
51 | this.hipchatURL = hipchatURL;
52 | }
53 |
54 |
55 | public String getAuthToken() {
56 | return authToken;
57 | }
58 |
59 | public void setAuthToken(String authToken) {
60 | this.authToken = authToken;
61 | }
62 |
63 | public boolean isEnabled(){
64 |
65 | return this.enabled;
66 | }
67 |
68 | /**
69 | * This should be invoked if isEnabled = true
70 | * @param mgs
71 | */
72 | public boolean sendMessage(String msg)
73 | {
74 | if(!this.enabled){
75 | logger.info("Hichat is not enabled, ignore.");
76 | return false;
77 | }
78 | java.io.OutputStream out = null;
79 | java.io.InputStream in = null;
80 | String url = this.hipchatURL+"auth_token="+this.authToken;
81 | try
82 | {
83 |
84 | java.net.URL hipchatUrl = new java.net.URL(url);
85 | java.net.HttpURLConnection conn = HttpURLConnection.class.cast( hipchatUrl.openConnection());
86 | conn.setDoOutput(true);
87 | conn.addRequestProperty("Content-Type", "application/json");
88 | String jsonMsg = this.constructJsonMessage("Source: "+ this.hostname+"\n" + msg);
89 | //logger.info("Sending message to hipchat (" + url + "): " + jsonMsg);
90 | byte[] jsonByte = jsonMsg.getBytes();
91 | conn.addRequestProperty("Content-Length", String.valueOf(jsonByte.length));
92 | out = conn.getOutputStream();
93 | out.write(jsonByte);
94 | out.flush();
95 | int code = conn.getResponseCode();
96 | in = conn.getInputStream();
97 | //logger.info("Recieve response code " + code);
98 | if(code >= 200 && code < 400)
99 | return true;
100 | logger.warning("Failed hipchat integration with URL: " + this.hipchatURL+", code: "+ code+", data: " + jsonMsg);
101 | }catch(Throwable th){
102 | logger.log(Level.WARNING, "Failed to send message: " + msg, th);
103 | return false;
104 | }finally{
105 | if(out != null){
106 | try{out.close();}catch(Exception ex){}
107 | }
108 | if(in != null){
109 | try{in.close();}catch(Exception ex){}
110 | }
111 | }
112 | return false;
113 | }
114 |
115 | private String constructJsonMessage(String str){
116 | StringBuilder sb = new StringBuilder();
117 | sb.append("{\"color\":\"green\",\"message\":\"");
118 | sb.append(CommonUtils.escapeJson(str));
119 | sb.append("\",\"notify\":false,\"message_format\":\"text\"}");
120 | return sb.toString();
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/myperf/src/main/java/com/yahoo/dba/perf/myperf/common/InstanceStatesManager.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015, Yahoo Inc.
3 | * Copyrights licensed under the Apache License.
4 | * See the accompanying LICENSE file for terms.
5 | */
6 | package com.yahoo.dba.perf.myperf.common;
7 |
8 | import java.io.File;
9 | import java.io.FileInputStream;
10 | import java.io.FileOutputStream;
11 | import java.io.IOException;
12 | import java.io.ObjectInputStream;
13 | import java.io.ObjectOutputStream;
14 | import java.util.HashMap;
15 | import java.util.Map;
16 | import java.util.logging.Level;
17 | import java.util.logging.Logger;
18 |
19 |
20 | /**
21 | * store realtime status
22 | * @author xrao
23 | *
24 | */
25 | public class InstanceStatesManager implements java.io.Serializable{
26 | private static final long serialVersionUID = 1L;
27 | private static Logger logger = Logger.getLogger(InstanceStatesManager.class.getName());
28 | public static String OBJ_FILE_NAME="instance_status.ser";
29 | public static final String STORAGE_DIR = "autoscan";
30 | private String rootPath = "myperf_reports";//data will be stored under $rootPath/autoscan
31 |
32 | private Map statesMap = new HashMap();
33 |
34 | public InstanceStatesManager()
35 | {
36 |
37 | }
38 |
39 | /**
40 | * Make the data persistent
41 | */
42 | public void saveStatus()
43 | {
44 | logger.info("Store instance status snapshots");
45 | File root = new File(new File(this.rootPath), STORAGE_DIR);
46 | File objFile = new File(root, OBJ_FILE_NAME);
47 | storeObject(objFile);
48 | }
49 | public void storeObject(File objf)
50 | {
51 | ObjectOutputStream outputStream = null;
52 |
53 | try {
54 |
55 | //Construct the LineNumberReader object
56 | outputStream = new ObjectOutputStream(new FileOutputStream(objf));
57 | outputStream.writeObject(this.statesMap);
58 |
59 | } catch (Exception ex) {
60 | logger.log(Level.SEVERE,"Exception when store instance status object", ex);
61 | }finally {
62 | //Close the ObjectOutputStream
63 | try {
64 | if (outputStream != null) {
65 | outputStream.flush();
66 | outputStream.close();
67 | }
68 | } catch (IOException ex) {
69 | ex.printStackTrace();
70 | }
71 | }
72 | }
73 |
74 | @SuppressWarnings("unchecked")
75 | public Map readObject(File objf)
76 | {
77 | ObjectInputStream input = null;
78 | try
79 | {
80 | input = new ObjectInputStream(
81 | new FileInputStream(objf));
82 | return (Map)input.readObject();
83 | }catch(Exception ex)
84 | {
85 | logger.log(Level.WARNING,"Exception when read instance status object", ex);
86 |
87 | }finally
88 | {
89 | if(input!=null)try{input.close();}catch(Exception iex){}
90 | }
91 | return null;
92 | }
93 |
94 | synchronized public InstanceStates getStates(int dbid)
95 | {
96 | if(statesMap.containsKey(dbid))
97 | return statesMap.get(dbid);
98 | return null;
99 | }
100 |
101 |
102 | synchronized public void addInstanceStates(int dbid)
103 | {
104 | if(statesMap.containsKey(dbid))
105 | return;
106 | this.statesMap.put(dbid, new InstanceStates());
107 | }
108 |
109 | synchronized public boolean removeInstanceStates(int dbid)
110 | {
111 | if(statesMap.containsKey(dbid))
112 | {
113 | statesMap.remove(dbid);
114 | return true;
115 | }
116 | return false;
117 | }
118 |
119 | /**
120 | * This should be called during context initialization
121 | * @param context
122 | */
123 | public void init(MyPerfContext context)
124 | {
125 | logger.info("Initialize InstanceStatesManager");
126 | File root = new File(new File(this.rootPath), STORAGE_DIR);
127 | if(!root.exists())root.mkdirs();
128 |
129 | File objFile = new File(root, OBJ_FILE_NAME);
130 | if(objFile.exists())
131 | {
132 | logger.info("Load saved status");
133 | Map savedState = readObject(objFile);
134 | if(savedState!=null)
135 | {
136 | for(Map.Entry e: savedState.entrySet())
137 | this.statesMap.put(e.getKey(), e.getValue());
138 | }
139 | }
140 |
141 | for(Map.Entry e: context.getDbInfoManager().getClusters().entrySet())
142 | {
143 | for (DBInstanceInfo dbinfo: e.getValue().getInstances())
144 | {
145 | if(!this.statesMap.containsKey(dbinfo.getDbid()))
146 | this.statesMap.put(dbinfo.getDbid(), new InstanceStates());
147 | }
148 | }
149 | logger.info("Initialized InstanceStatesManager");
150 | }
151 |
152 | public String getRootPath() {
153 | return rootPath;
154 | }
155 |
156 | public void setRootPath(String rootPath) {
157 | this.rootPath = rootPath;
158 | }
159 | }
160 |
--------------------------------------------------------------------------------
/myperf/src/main/java/com/yahoo/dba/perf/myperf/common/MD5Util.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015, Yahoo Inc.
3 | * Copyrights licensed under the Apache License.
4 | * See the accompanying LICENSE file for terms.
5 | */
6 | package com.yahoo.dba.perf.myperf.common;
7 |
8 | import java.io.UnsupportedEncodingException;
9 | import java.security.MessageDigest;
10 | import java.security.NoSuchAlgorithmException;
11 |
12 | public class MD5Util {
13 | private static String convertToHex(byte[] data) {
14 | StringBuffer buf = new StringBuffer();
15 | for (int i = 0; i < data.length; i++) {
16 | int halfbyte = (data[i] >>> 4) & 0x0F;
17 | int two_halfs = 0;
18 | do {
19 | if ((0 <= halfbyte) && (halfbyte <= 9))
20 | buf.append((char) ('0' + halfbyte));
21 | else
22 | buf.append((char) ('a' + (halfbyte - 10)));
23 | halfbyte = data[i] & 0x0F;
24 | } while(two_halfs++ < 1);
25 | }
26 | return buf.toString();
27 | }
28 |
29 | public static String MD5(String text) throws NoSuchAlgorithmException, UnsupportedEncodingException {
30 | MessageDigest md;
31 | md = MessageDigest.getInstance("MD5");
32 | byte[] md5hash = null;
33 | md.update(text.getBytes("iso-8859-1"), 0, text.length());
34 | md5hash = md.digest();
35 | return convertToHex(md5hash);
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/myperf/src/main/java/com/yahoo/dba/perf/myperf/common/MailUtil.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015, Yahoo Inc.
3 | * Copyrights licensed under the Apache License.
4 | * See the accompanying LICENSE file for terms.
5 | */
6 | package com.yahoo.dba.perf.myperf.common;
7 |
8 | import java.io.Writer;
9 | import java.util.logging.Level;
10 | import java.util.logging.Logger;
11 |
12 | public class MailUtil {
13 | private static Logger logger = Logger.getLogger(MailUtil.class.getName());
14 |
15 | /**
16 | * A simple mail client to use shell command to send mail
17 | * @param receiver
18 | * @param subject
19 | * @param msg
20 | * @return
21 | */
22 | public static boolean sendMail(String receiver, String subject, String msg)
23 | {
24 | String mailCommand = "mailx";//or mail, which send long body as attachment
25 |
26 | String os = System.getProperty("os.name");
27 | if(os!=null && os.toUpperCase().contains("WIN"))return false;
28 | logger.info("Sending email to "+receiver+" regarding "+subject);
29 | String[] cmd = {mailCommand, "-s", subject, receiver};
30 | try
31 | {
32 | Process p = Runtime.getRuntime().exec(cmd);
33 | Writer w = new java.io.OutputStreamWriter(p.getOutputStream());
34 | w.append(msg);
35 | w.flush();
36 | w.close();
37 | p.waitFor();
38 | logger.info("Mail exitValue="+p.exitValue());
39 | return true;
40 | }catch(Exception ex)
41 | {
42 | logger.log(Level.SEVERE, "Error when send mail", ex);
43 | }
44 | return false;
45 | }
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/myperf/src/main/java/com/yahoo/dba/perf/myperf/common/MetricDataType.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015, Yahoo Inc.
3 | * Copyrights licensed under the Apache License.
4 | * See the accompanying LICENSE file for terms.
5 | */
6 | package com.yahoo.dba.perf.myperf.common;
7 |
8 | public enum MetricDataType {
9 |
10 | BYTE(0,1,"BYTE"),
11 | SHORT(1,2,"SHORT"),
12 | INT(2,4,"INT"),
13 | LONG(3,8,"LONG"),
14 | FLOAT(4,4,"FLOAT"),
15 | DOUBLE(5,8,"DOUBLE");
16 |
17 | private final int code;
18 | private final int length;//data length
19 | private final String description;//data description
20 |
21 | MetricDataType(int code, int length, String description)
22 | {
23 | this.code = code;
24 | this.length = length;
25 | this.description = description;
26 | }
27 |
28 | public int getCode()
29 | {
30 | return this.code;
31 | }
32 |
33 | public int getLength()
34 | {
35 | return this.length;
36 | }
37 |
38 | public String getDescription()
39 | {
40 | return this.description;
41 | }
42 | }
43 |
44 |
--------------------------------------------------------------------------------
/myperf/src/main/java/com/yahoo/dba/perf/myperf/common/MetricsResultObject.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015, Yahoo Inc.
3 | * Copyrights licensed under the Apache License.
4 | * See the accompanying LICENSE file for terms.
5 | */
6 | package com.yahoo.dba.perf.myperf.common;
7 |
8 | public class MetricsResultObject implements CustomResultObject {
9 | private static final long serialVersionUID = 1L;
10 |
11 | private java.util.List metrics;
12 | public MetricsResultObject()
13 | {
14 |
15 | }
16 | @Override
17 | public String getName()
18 | {
19 | return "metrics";//fixed the name
20 | }
21 |
22 | @Override
23 | public String getValueJsonString() {
24 | StringBuilder sb = new StringBuilder();
25 | sb.append("{");
26 | if(this.metrics!=null)
27 | {
28 | boolean first = true;
29 | for(Metric m: this.metrics)
30 | {
31 | if(!first)sb.append(",");
32 | else first = false;
33 | sb.append("\"").append(m.getName()).append("\"");
34 | sb.append(":{");
35 | sb.append("\"shortName\":\"").append(m.getShortName()).append("\"");
36 | sb.append(",\"inc\":").append(m.isIncremental()?"1":"0");
37 | sb.append(",\"unit\":\"").append(m.getMetricUnit()).append("\"");
38 | if(m.getAverageTimeUnit()!=null)
39 | sb.append(",\"avg\":\"").append(m.getAverageTimeUnit()).append("\"");
40 | if(m.getAdjustment()!=null)
41 | sb.append(",\"adj\":").append(m.getAdjustment());
42 | if(m.getChartDisplayUnit()!=null)
43 | sb.append(",\"display\":\"").append(m.getChartDisplayUnit()).append("\"");
44 | if(m.getDescription()!=null)
45 | sb.append(",\"description\":\"").append(m.getDescription()).append("\"");
46 | sb.append("}\r\n");
47 | }
48 | }
49 | sb.append("}");
50 | return sb.toString();
51 | }
52 | public java.util.List getMetrics() {
53 | return metrics;
54 | }
55 | public void setMetrics(java.util.List metrics) {
56 | this.metrics = metrics;
57 | }
58 |
59 | //will prefix metricsGroupname
60 | public void setMetrics(java.util.List metrics, String metricsGroupName) {
61 | if(metrics!=null && metricsGroupName!=null && !metricsGroupName.isEmpty() && !"globalstatus".equals(metricsGroupName))
62 | {
63 | for(Metric m: metrics)
64 | {
65 | m.setName(metricsGroupName+"."+m.getName());
66 | }
67 | }
68 | this.metrics = metrics;
69 | }
70 |
71 | public void addMetric(Metric m)
72 | {
73 | if(this.metrics==null)this.metrics = new java.util.ArrayList();
74 | this.metrics.add(m);
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/myperf/src/main/java/com/yahoo/dba/perf/myperf/common/MyDatabases.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015, Yahoo Inc.
3 | * Copyrights licensed under the Apache License.
4 | * See the accompanying LICENSE file for terms.
5 | */
6 | package com.yahoo.dba.perf.myperf.common;
7 |
8 | import java.util.List;
9 | import java.util.Set;
10 | import java.util.TreeSet;
11 |
12 | public class MyDatabases implements java.io.Serializable{
13 |
14 | private static final long serialVersionUID = -8586381924495834726L;
15 |
16 | private Set myDbSet = new TreeSet();
17 |
18 | synchronized public Set getMyDbList()
19 | {
20 | return java.util.Collections.unmodifiableSet(this.myDbSet);
21 | }
22 |
23 | synchronized public void addDb(String name)
24 | {
25 | if(!this.myDbSet.contains(name))
26 | this.myDbSet.add(name);
27 | }
28 | synchronized public void addDbs(List names)
29 | {
30 | for (String name:names)
31 | {
32 | if(!this.myDbSet.contains(name))
33 | this.myDbSet.add(name);
34 | }
35 | }
36 |
37 | synchronized public void removeDb(String name)
38 | {
39 | if(this.myDbSet.contains(name))
40 | this.myDbSet.remove(name);
41 | }
42 |
43 | synchronized public void replaceDb(String oldName, String newName)
44 | {
45 | if(!this.myDbSet.contains(oldName))
46 | {
47 | this.myDbSet.remove(oldName);
48 | this.myDbSet.remove(newName);
49 |
50 | }
51 | }
52 |
53 | synchronized public int size()
54 | {
55 | return this.myDbSet.size();
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/myperf/src/main/java/com/yahoo/dba/perf/myperf/common/ProcessListEntryAggregate.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015, Yahoo Inc.
3 | * Copyrights licensed under the Apache License.
4 | * See the accompanying LICENSE file for terms.
5 | */
6 | package com.yahoo.dba.perf.myperf.common;
7 |
8 | import java.util.Map;
9 |
10 | /**
11 | * The default compartor is sorted by total_time_sec
12 | * @author xrao
13 | *
14 | */
15 | public class ProcessListEntryAggregate implements java.io.Serializable, Comparable{
16 | private static final long serialVersionUID = 1L;
17 |
18 | static final char HEXES[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
19 |
20 | private String sql;//that will be the key
21 | private int count = 0;
22 | private int total_time_sec = 0;//at this moment, sec only
23 | private int min_time_sec = -1;//minimum time recorded -1 manes not updated yet
24 | private int max_time_sec = 0;//max time recorded
25 |
26 | private String checksum;
27 |
28 | public static class SortByCount implements java.util.Comparator
29 | {
30 |
31 | @Override
32 | public int compare(ProcessListEntryAggregate obj1,
33 | ProcessListEntryAggregate obj2) {
34 | if(obj1==null && obj2==null)
35 | return 0;
36 | else if(obj1==null)return 1;
37 | else if(obj2==null)return -1;
38 | return obj2.getCount() - obj1.getCount();//reverse order
39 | }
40 |
41 | }
42 | public ProcessListEntryAggregate(String sql)
43 | {
44 | this.sql = sql;
45 | }
46 |
47 | public String getSql() {
48 | return sql;
49 | }
50 |
51 | public int getCount() {
52 | return count;
53 | }
54 |
55 | public int getTotal_time_sec() {
56 | return total_time_sec;
57 | }
58 |
59 | public int getMin_time_sec() {
60 | return min_time_sec;
61 | }
62 |
63 |
64 | public int getMax_time_sec() {
65 | return max_time_sec;
66 | }
67 |
68 | public float getAverage()
69 | {
70 | if(this.count==0)return 0;
71 | else
72 | return (float)this.total_time_sec/(float)this.count;
73 | }
74 | /**
75 | * Record one execution instance time. Later we might want to add more metrics for example, rows_read, etc
76 | * @param time_sec
77 | */
78 | public void record(int time_sec)
79 | {
80 | this.count++;
81 | this.total_time_sec+=time_sec;
82 | if(this.min_time_sec<0)
83 | this.min_time_sec = time_sec;
84 | else
85 | this.min_time_sec = Math.min(this.min_time_sec, time_sec);
86 | this.max_time_sec = Math.max(this.max_time_sec, time_sec);
87 | }
88 |
89 | @Override
90 | public int compareTo(ProcessListEntryAggregate obj) {
91 | if(obj==null)return -1;
92 | return obj.getTotal_time_sec() - this.getTotal_time_sec();
93 | }
94 |
95 | public static void updateDataMap(Map m, String sql, int time_sec)
96 | {
97 | if(m==null)return;
98 | if(m.containsKey(sql))
99 | {
100 | m.get(sql).record(time_sec);
101 | }else
102 | {
103 | ProcessListEntryAggregate e = new ProcessListEntryAggregate(sql);
104 | e.setChecksum(generateDigest(sql));
105 | e.record(time_sec);
106 | m.put(sql, e);
107 | }
108 | }
109 |
110 | public String getChecksum() {
111 | return checksum;
112 | }
113 |
114 | public void setChecksum(String checksum) {
115 | this.checksum = checksum;
116 | }
117 |
118 | /**
119 | * Generate a digest for each query string
120 | * @param str
121 | * @return
122 | */
123 | public static String generateDigest(String str)
124 | {
125 | if(str==null||str.isEmpty())return "00000000";
126 | try
127 | {
128 | java.security.MessageDigest md = java.security.MessageDigest.getInstance("SHA1");
129 | md.update(str.getBytes());
130 | byte[] digest = md.digest();
131 | StringBuilder sb = new StringBuilder();
132 | for(byte b: digest)
133 | {
134 | sb.append(HEXES[(b & 0xF0)>>4])
135 | .append(HEXES[(b&0x0F)]);
136 | }
137 | return sb.toString();
138 | }catch(Exception ex)
139 | {
140 |
141 | }
142 | return "00000000";
143 | }
144 |
145 | }
146 |
--------------------------------------------------------------------------------
/myperf/src/main/java/com/yahoo/dba/perf/myperf/common/ProcessListEntryProcessor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015, Yahoo Inc.
3 | * Copyrights licensed under the Apache License.
4 | * See the accompanying LICENSE file for terms.
5 | */
6 | package com.yahoo.dba.perf.myperf.common;
7 |
8 | import java.io.PrintWriter;
9 |
10 | /**
11 | * Allow application specific information summary to take advantage of application convention
12 | * @author xrao
13 | *
14 | */
15 | interface ProcessListEntryProcessor
16 | {
17 | void processEntry(ProcessListEntry e);
18 | void dumpSummary(PrintWriter pw);
19 | }
20 |
--------------------------------------------------------------------------------
/myperf/src/main/java/com/yahoo/dba/perf/myperf/common/QueryInputValidator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015, Yahoo Inc.
3 | * Copyrights licensed under the Apache License.
4 | * See the accompanying LICENSE file for terms.
5 | */
6 | package com.yahoo.dba.perf.myperf.common;
7 |
8 | public class QueryInputValidator {
9 |
10 | /**
11 | * If has issue, a RuntimeException will be thrown with the validation message
12 | * @param sqlManager
13 | * @param qps
14 | * @return
15 | */
16 | public static void validateSql(SqlManager sqlManager, QueryParameters qps)
17 | {
18 | Sql sql = sqlManager.getSql(qps.getSql());
19 | if(sql==null)throw new RuntimeException("Cannot find sql for handle "+qps.getSql());
20 | int paramCnt = sql.getParamCount();
21 | for(int i=1;i<=paramCnt;i++)
22 | {
23 | //parameter name uses p_nn convention
24 | if(!qps.getSqlParams().containsKey("p_"+i))
25 | {
26 | throw new RuntimeException("Missing parameter p_"+i);
27 | }
28 | }
29 | }
30 |
31 | public static void validateDiffSqls(SqlManager sqlManager, QueryParameters qpsA, QueryParameters qpsB)
32 | {
33 | Sql sqlA = sqlManager.getSql(qpsA.getSql());
34 | if(sqlA==null)throw new RuntimeException("Cannot find sql for handle "+qpsA.getSql());
35 | int paramCnt = sqlA.getParamCount();
36 | for(int i=1;i<=paramCnt;i++)
37 | {
38 | //parameter name uses p_nn convention
39 | if(!qpsA.getSqlParams().containsKey("p_"+i))
40 | {
41 | throw new RuntimeException("SQL A is missing parameter p_"+i);
42 | }
43 | }
44 | Sql sqlB = sqlManager.getSql(qpsB.getSql());
45 | if(sqlB==null)throw new RuntimeException("Cannot find sql for handle "+qpsB.getSql());
46 | paramCnt = sqlB.getParamCount();
47 | for(int i=1;i<=paramCnt;i++)
48 | {
49 | //parameter name uses p_nn convention
50 | if(!qpsB.getSqlParams().containsKey("p_"+i))
51 | {
52 | throw new RuntimeException("SQL B is missing parameter p_"+i);
53 | }
54 | }
55 |
56 | //compare key list
57 | if(sqlA.getKeyList().size()!=sqlB.getKeyList().size())
58 | {
59 | throw new RuntimeException("SQL A and SQL B do not have same number of key columnss.");
60 | }
61 |
62 | for(String key:sqlA.getKeyList())
63 | {
64 | if(!sqlB.getKeyList().contains(key))
65 | throw new RuntimeException("SQL B does not have key "+key);
66 | }
67 | //compare metrics list
68 | if(sqlA.getValueList().size()!=sqlB.getValueList().size())
69 | {
70 | throw new RuntimeException("SQL A and SQL B do not have same number of value columns.");
71 | }
72 |
73 | for(String key:sqlA.getValueList())
74 | {
75 | if(!sqlB.getValueList().contains(key))
76 | throw new RuntimeException("SQL B does not have value column "+key);
77 | }
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/myperf/src/main/java/com/yahoo/dba/perf/myperf/common/QueryParameters.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015, Yahoo Inc.
3 | * Copyrights licensed under the Apache License.
4 | * See the accompanying LICENSE file for terms.
5 | */
6 | package com.yahoo.dba.perf.myperf.common;
7 |
8 | import java.io.Serializable;
9 | import java.util.Map;
10 | /**
11 | * Wrap query parameters
12 | */
13 | public class QueryParameters implements Serializable{
14 |
15 | private static final long serialVersionUID = 6906313101027653783L;
16 | private String group;//an identifier for the target database
17 | private String host;//DB hostname
18 | private String port;//DB port
19 | private String svc;//servicename
20 | private String sid;//sid
21 | private String sql;//an internal sql id
22 | private int targetInstance = 0;//0 is invalid number, meaning no target instance is passed. If it is passed, it will be in higher priority than the one derived from host
23 |
24 | private Map sqlParams = new java.util.TreeMap();
25 | //parameter in p_1, p_2,..., name convention
26 |
27 | private int maxRows = 5000;//maximum rows to return
28 |
29 | private String sqlText;//So we can use it for non predefined queries.
30 |
31 | public QueryParameters()
32 | {
33 |
34 | }
35 |
36 | public String getGroup() {
37 | return group;
38 | }
39 |
40 | public void setGroup(String group) {
41 | if(group!=null && group.trim().length()>0)
42 | this.group = group.trim();
43 | else
44 | this.group = null;
45 | }
46 | public String getHost() {
47 | return this.host;
48 | }
49 |
50 | public void setHost(String host) {
51 | if(host!=null&&host.trim().length()>0)
52 | this.host = host.trim();
53 | else this.host = null;
54 | }
55 |
56 | public String getPort() {
57 | return port;
58 | }
59 |
60 | public void setPort(String port) {
61 | if(port!=null&&port.trim().length()>0)
62 | this.port = port.trim();
63 | else this.port = "1521";
64 | }
65 |
66 | public String getSvc() {
67 | return svc;
68 | }
69 |
70 | public void setSvc(String svc) {
71 | if(svc!=null&&svc.trim().length()>0)
72 | this.svc = svc.trim();
73 | else this.svc = null;
74 | }
75 |
76 | public String getSid() {
77 | return sid;
78 | }
79 |
80 | public void setSid(String sid) {
81 | if(sid!=null&&sid.trim().length()>0)
82 | this.sid = sid.trim();
83 | else this.sid=null;
84 | }
85 |
86 | public String getSql() {
87 | return sql;
88 | }
89 |
90 | public void setSql(String sql) {
91 | if(sql!=null&&sql.trim().length()>0)
92 | this.sql = sql.trim();
93 | else this.sql = null;
94 | }
95 |
96 | @Override
97 | public String toString() {
98 |
99 | StringBuilder sb = new StringBuilder();
100 |
101 | sb.append("[id=").append(group).append("]");
102 | sb.append(",[host=").append(host).append("]");
103 | sb.append(",[port=").append(port).append("]");
104 | sb.append(",[svc=").append(svc).append("]");
105 | sb.append(",[sid=").append(sid).append("]");
106 | sb.append(",[sql=").append(sql).append("]");
107 | if(this.sqlParams.size()>0)
108 | {
109 | for(String key: this.sqlParams.keySet())
110 | {
111 | sb.append(",[").append(key).append("=").append(this.sqlParams.get(key)).append("]");
112 | }
113 | }
114 | return sb.toString();
115 | }
116 |
117 | public Map getSqlParams() {
118 | return sqlParams;
119 | }
120 |
121 | /**
122 | * Validate the parameters. Return null or empty if validated. Otherwise, error messages
123 | * TODO
124 | * @return
125 | */
126 | public String validate()
127 | {
128 | StringBuilder sb = new StringBuilder();
129 | if(group==null)sb.append("group is required. ");
130 | if(host==null)sb.append("host is required. ");
131 | //if(svc==null&&sid==null)sb.append("one of svc and sid is required. ");
132 | if(sql==null)sb.append("sql is required. ");
133 | return sb.toString();
134 | }
135 |
136 |
137 | public int getTargetInstance() {
138 | return targetInstance;
139 | }
140 |
141 | public void setTargetInstance(int targetInstance) {
142 | this.targetInstance = targetInstance;
143 | }
144 |
145 | public int getMaxRows() {
146 | return maxRows;
147 | }
148 |
149 | public void setMaxRows(int maxRows) {
150 | this.maxRows = maxRows;
151 | }
152 |
153 | public String getSqlText() {
154 | return sqlText;
155 | }
156 |
157 | public void setSqlText(String sqlText) {
158 | this.sqlText = sqlText;
159 | }
160 | }
161 |
--------------------------------------------------------------------------------
/myperf/src/main/java/com/yahoo/dba/perf/myperf/common/ResultList.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015, Yahoo Inc.
3 | * Copyrights licensed under the Apache License.
4 | * See the accompanying LICENSE file for terms.
5 | */
6 | package com.yahoo.dba.perf.myperf.common;
7 |
8 | /**
9 | * Store qresultset of a query
10 | * @author xrao
11 | *
12 | */
13 | public class ResultList implements java.io.Serializable {
14 | private static final long serialVersionUID = 1126296256817182221L;
15 | private ColumnDescriptor columnDescriptor;//meta data
16 | private java.util.List rows;//results
17 | private long totalResponseTime = 0L;//total time used in milliseconds
18 | private long totalExecutionTime = 0L;//total DB execution time used in milliseconds
19 | private long totalFetchTime = 0L;//total Resultset Fetch time used in milliseconds
20 | private java.util.Map customObjects;//The key is the json key name
21 |
22 | public ResultList()
23 | {
24 | rows = new java.util.ArrayList();
25 | }
26 | public ResultList(int capacity)
27 | {
28 | rows = new java.util.ArrayList(capacity);
29 | }
30 |
31 | public ColumnDescriptor getColumnDescriptor() {
32 | return columnDescriptor;
33 | }
34 |
35 | public void setColumnDescriptor(ColumnDescriptor columnDescriptor) {
36 | this.columnDescriptor = columnDescriptor;
37 | }
38 |
39 | public int getColumnIndex(String colName)
40 | {
41 | return this.columnDescriptor.getColumnIndex(colName);
42 | }
43 | public java.util.List getRows() {
44 | return rows;
45 | }
46 |
47 | public void addRow(ResultRow row)
48 | {
49 | this.rows.add(row);
50 | }
51 | public long getTotalResponseTime() {
52 | return totalResponseTime;
53 | }
54 | public void setTotalResponseTime(long totalResponseTime) {
55 | this.totalResponseTime = totalResponseTime;
56 | }
57 | public long getTotalExecutionTime() {
58 | return totalExecutionTime;
59 | }
60 | public void setTotalExecutionTime(long totalExecutionTime) {
61 | this.totalExecutionTime = totalExecutionTime;
62 | }
63 | public long getTotalFetchTime() {
64 | return totalFetchTime;
65 | }
66 | public void setTotalFetchTime(long totalFetchTime) {
67 | this.totalFetchTime = totalFetchTime;
68 | }
69 | public java.util.Map getCustomObjects() {
70 | return customObjects;
71 | }
72 | public void setCustomObjects(java.util.Map customObjects) {
73 | this.customObjects = customObjects;
74 | }
75 | public void addCustomeObject(CustomResultObject obj)
76 | {
77 | if(obj==null)return;
78 | if(this.customObjects==null)this.customObjects = new java.util.HashMap();
79 | this.customObjects.put(obj.getName(), obj);
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/myperf/src/main/java/com/yahoo/dba/perf/myperf/common/ResultRow.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015, Yahoo Inc.
3 | * Copyrights licensed under the Apache License.
4 | * See the accompanying LICENSE file for terms.
5 | */
6 | package com.yahoo.dba.perf.myperf.common;
7 |
8 | public class ResultRow implements java.io.Serializable{
9 | private static final long serialVersionUID = 2131095887594423404L;
10 |
11 | private ColumnDescriptor columnDescriptor;
12 | private java.util.List columns;//we only need string value for display
13 | public ResultRow()
14 | {
15 |
16 | }
17 |
18 |
19 | public ColumnDescriptor getColumnDescriptor() {
20 | return columnDescriptor;
21 | }
22 |
23 |
24 | public void setColumnDescriptor(ColumnDescriptor columnDescriptor) {
25 | this.columnDescriptor = columnDescriptor;
26 | }
27 |
28 |
29 | public java.util.List getColumns() {
30 | return columns;
31 | }
32 |
33 |
34 | public void setColumns(java.util.List columns) {
35 | this.columns = columns;
36 | }
37 |
38 | /**
39 | * The user can build columns by adding column one by one. The user should not use setColumns when this is used.
40 | * This is convenient when there are only a few columns to build
41 | * @param s
42 | */
43 | public void addColumn(String s)
44 | {
45 | if(this.columns==null)
46 | this.columns = new java.util.ArrayList();
47 | this.columns.add(s);
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/myperf/src/main/java/com/yahoo/dba/perf/myperf/common/ResultRowKeyComparator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015, Yahoo Inc.
3 | * Copyrights licensed under the Apache License.
4 | * See the accompanying LICENSE file for terms.
5 | */
6 | package com.yahoo.dba.perf.myperf.common;
7 |
8 | import java.util.Comparator;
9 | import java.util.List;
10 |
11 | /**
12 | * Compare two ResultRows based on keyList. For simplicity, the column descriptors for both rows should be provided
13 | * @author xrao
14 | *
15 | */
16 | public class ResultRowKeyComparator implements Comparator, java.io.Serializable{
17 | private static final long serialVersionUID = 2243120460008043846L;
18 | private List keyList;
19 | private List index1List;
20 | private List index2List;
21 |
22 |
23 | public ResultRowKeyComparator(List keyList, ColumnDescriptor descA, ColumnDescriptor descB)
24 | {
25 | this.keyList = keyList;
26 | this.index1List = new java.util.ArrayList(this.keyList.size());
27 | this.index2List = new java.util.ArrayList(this.keyList.size());
28 |
29 | for(int i=0;i=0?o1.getColumns().get(this.index1List.get(i)):null;
45 | String valB = this.index2List.get(i)>=0?o2.getColumns().get(this.index2List.get(i)):null;
46 | if(valA==null && valB==null)return 0;
47 | if(valA==null)return -1;
48 | if(valB==null)return 1;
49 | int c = valA.trim().compareTo(valB.trim());
50 | if(c!=0)return c;
51 | }
52 |
53 | return 0;
54 | }
55 |
56 | }
57 |
--------------------------------------------------------------------------------
/myperf/src/main/java/com/yahoo/dba/perf/myperf/common/SqlParameter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015, Yahoo Inc.
3 | * Copyrights licensed under the Apache License.
4 | * See the accompanying LICENSE file for terms.
5 | */
6 | package com.yahoo.dba.perf.myperf.common;
7 |
8 | import java.math.BigDecimal;
9 |
10 | public class SqlParameter implements java.io.Serializable{
11 |
12 | private static final long serialVersionUID = 1L;
13 |
14 | public final static String TYPE_NUMERIC = "numeric";
15 | public final static String TYPE_NONBREAKABLE_STRING = "non_breakable_string";//no space, quote, , ; \r, \n allowed
16 | public final static String TYPE_BREAK_STRING = "breakable_string";
17 | public final static String TYPE_QUOTED_STRING = "single_quoted_string";//so we only need escape single quote
18 |
19 | private String name;//actual parameter meaningful name
20 | private String dataType = TYPE_NONBREAKABLE_STRING;//value type, one of above defined value
21 |
22 | public SqlParameter()
23 | {
24 |
25 | }
26 |
27 | public SqlParameter(String name, String dataType)
28 | {
29 | this.name = name;
30 | if(dataType!=null)
31 | this.dataType = dataType;
32 | }
33 | public String getName() {
34 | return name;
35 | }
36 | public void setName(String name) {
37 | this.name = name;
38 | }
39 | public String getDataType() {
40 | return dataType;
41 | }
42 | public void setDataType(String dataType) {
43 | if(dataType!=null)
44 | this.dataType = dataType;
45 | }
46 |
47 | public boolean needEscape()
48 | {
49 | return TYPE_BREAK_STRING.equalsIgnoreCase(this.dataType)
50 | ||TYPE_QUOTED_STRING.equalsIgnoreCase(this.dataType);
51 | }
52 | public boolean isValidValue(String input)
53 | {
54 | //check if numeric type
55 | if(TYPE_NUMERIC.equalsIgnoreCase(this.dataType))
56 | {
57 | try{
58 | BigDecimal dec = new BigDecimal(input);
59 | return true;
60 | }catch(Exception ex)
61 | {
62 | return false;
63 | }
64 | }else if(TYPE_NONBREAKABLE_STRING.equalsIgnoreCase(this.dataType))
65 | {
66 | if(input==null)return true;
67 | else if(input.indexOf(' ')>=0)return false;
68 | else if(input.indexOf('\t')>=0)return false;
69 | else if(input.indexOf('\n')>=0)return false;
70 | else if(input.indexOf('\r')>=0)return false;
71 | else if(input.indexOf(';')>=0)return false;
72 | else if(input.indexOf(',')>=0)return false;
73 |
74 | return true;
75 | }
76 | return true;
77 | }
78 |
79 | public static String escapeSingleQuote(String input)
80 | {
81 | if(input==null)return null;
82 | return input.replaceAll("'" , "''");
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/myperf/src/main/java/com/yahoo/dba/perf/myperf/common/StatDefManager.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015, Yahoo Inc.
3 | * Copyrights licensed under the Apache License.
4 | * See the accompanying LICENSE file for terms.
5 | */
6 | package com.yahoo.dba.perf.myperf.common;
7 |
8 | import java.util.Map;
9 | import java.util.TreeMap;
10 | import java.util.logging.Level;
11 | import java.util.logging.Logger;
12 |
13 | import javax.xml.stream.XMLInputFactory;
14 | import javax.xml.stream.XMLStreamConstants;
15 | import javax.xml.stream.XMLStreamException;
16 | import javax.xml.stream.XMLStreamReader;
17 |
18 |
19 | public class StatDefManager implements java.io.Serializable{
20 |
21 | private static final long serialVersionUID = 9087706748220206476L;
22 | private static Logger logger = Logger.getLogger(StatDefManager.class.getName());
23 | @SuppressWarnings("restriction")
24 | static final XMLInputFactory inputFactory = XMLInputFactory.newInstance();
25 | private Map statMap = new TreeMap();
26 | private String sourcePath = "stats.xml";
27 |
28 | public StatDefManager()
29 | {
30 |
31 | }
32 |
33 | public String getSourcePath() {
34 | return sourcePath;
35 | }
36 |
37 | public void setSourcePath(String sourcePath) {
38 | this.sourcePath = sourcePath;
39 | }
40 |
41 | public String getStatDescription(String category, String name)
42 | {
43 | if(category==null||category.isEmpty())
44 | return getStatDescription(name);
45 | if("thead_state".equalsIgnoreCase(category))
46 | {
47 |
48 | }
49 | return null;
50 | }
51 | public String getStatDescription(String name)
52 | {
53 | if(name==null)return null;
54 | name = name.trim().toLowerCase();
55 | if(this.statMap.containsKey(name))
56 | return this.statMap.get(name);
57 | if(name.startsWith("mysql_status_com_stmt"))
58 | return this.statMap.get("mysql_status_com_stmt_xxx");
59 | if(name.startsWith("mysql_status_com_"))
60 | return this.statMap.get("mysql_status_com_xxx");
61 | if(name.startsWith("mysql_status_performance_schema"))
62 | return this.statMap.get("mysql_status_performance_schema_xxx");
63 | return null;
64 | }
65 |
66 | public String[] getStatNames()
67 | {
68 | return this.statMap.keySet().toArray(new String[0]);
69 | }
70 | public void setStatMap(Map statMap) {
71 | this.statMap = statMap;
72 | }
73 |
74 | /**
75 | * Load all predefined sqls
76 | * @param in
77 | * @return
78 | * @throws XMLStreamException
79 | */
80 | @SuppressWarnings("restriction")
81 | public boolean load(java.io.InputStream in) throws XMLStreamException
82 | {
83 | XMLStreamReader reader = null;
84 | try
85 | {
86 | reader = inputFactory.createXMLStreamReader(new java.io.InputStreamReader(in));
87 | while(reader.hasNext())
88 | {
89 | //loop till one sql tag is found
90 | int evtType = reader.next();
91 | if(evtType!=XMLStreamConstants.START_ELEMENT)continue;
92 | String tagName = reader.getLocalName();
93 | if(!"stat".equals(tagName))continue;
94 | String name = reader.getAttributeValue(null, "name");
95 | if(name!=null&&name.trim().length()>0)
96 | {
97 | this.statMap.put(name.toLowerCase(), reader.getElementText());
98 | }
99 | }
100 | }
101 | finally
102 | {
103 | if(reader!=null)try{reader.close(); reader=null;}catch(Exception iex){}
104 | }
105 |
106 | return false;
107 | }
108 | public boolean init()
109 | {
110 | java.io.InputStream in = null;
111 |
112 | try{
113 | in = this.getClass().getClassLoader().getResourceAsStream(this.sourcePath);
114 | this.load(in);
115 | logger.info("Load preloaded stat def: "+this.statMap.size()+", input "+(in==null)+", source path="+this.sourcePath);
116 | return true;
117 | }catch(Exception ex)
118 | {
119 | logger.log(Level.SEVERE,"Exception", ex);
120 | }finally
121 | {
122 | if(in!=null)try{in.close();}catch(Exception ex){}
123 | }
124 | return false;
125 | }
126 |
127 |
128 | }
129 |
--------------------------------------------------------------------------------
/myperf/src/main/java/com/yahoo/dba/perf/myperf/db/ConnectionFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015, Yahoo Inc.
3 | * Copyrights licensed under the Apache License.
4 | * See the accompanying LICENSE file for terms.
5 | */
6 | package com.yahoo.dba.perf.myperf.db;
7 |
8 | import java.sql.Connection;
9 | import java.sql.DriverManager;
10 | import java.util.Map.Entry;
11 |
12 | import com.yahoo.dba.perf.myperf.common.*;
13 |
14 |
15 | /**
16 | * ConnectionFactory is used to create connections
17 | * @author xrao
18 | *
19 | */
20 | public class ConnectionFactory
21 | {
22 | /**
23 | * The purpose is to create JDBC connection to DBInstanceInfo db,
24 | * using credential from cred. Using ConnectionFactory so that
25 | * we can later cover multiple types of database.
26 | * @param db
27 | * @param cred
28 | * @param context
29 | * @return
30 | * @throws java.sql.SQLException
31 | */
32 | public static Connection connect(DBInstanceInfo db, DBCredential cred, MyPerfContext context)
33 | throws java.sql.SQLException
34 | {
35 | java.util.Properties info = new java.util.Properties();
36 | info.put ("user", cred.getUsername());
37 | info.put ("password",cred.getPassword());
38 | if("oracle".equalsIgnoreCase(db.getDbType()))
39 | {
40 | info.put("oracle.net.CONNECT_TIMEOUT", String.valueOf(context.getConnectionTimeout()));
41 | info.put("oracle.net.READ_TIMEOUT", String.valueOf(context.getConnectionReadTimeout()));
42 | info.put("oracle.jdbc.ReadTimeout", String.valueOf(context.getConnectionReadTimeout()));
43 | }
44 | else if("mysql".equalsIgnoreCase(db.getDbType()))
45 | {
46 | info.put("connectTimeout", String.valueOf(context.getConnectionTimeout()));
47 | info.put("socketTimeout", String.valueOf(context.getConnectionReadTimeout()));
48 | }
49 | return DriverManager.getConnection(db.getConnectionString(), info);
50 | }
51 |
52 | public static Connection connect(DBInstanceInfo db, String username, String password, MyPerfContext context)
53 | throws java.sql.SQLException
54 | {
55 | java.util.Properties info = new java.util.Properties();
56 | info.put ("user", username);
57 | info.put ("password",password);
58 | if("oracle".equalsIgnoreCase(db.getDbType()))
59 | {
60 | info.put("oracle.net.CONNECT_TIMEOUT", String.valueOf(context.getConnectionTimeout()));
61 | info.put("oracle.net.READ_TIMEOUT", String.valueOf(context.getConnectionReadTimeout()));
62 | info.put("oracle.jdbc.ReadTimeout", String.valueOf(context.getConnectionReadTimeout()));
63 | }
64 | else if("mysql".equalsIgnoreCase(db.getDbType()))
65 | {
66 | info.put("connectTimeout", String.valueOf(context.getConnectionTimeout()));
67 | info.put("socketTimeout", String.valueOf(context.getConnectionReadTimeout()));
68 | }
69 | return DriverManager.getConnection(db.getConnectionString(), info);
70 | }
71 |
72 | /**
73 | * Allow the user to provide customized properties to overwrite defaults
74 | * @param db
75 | * @param username
76 | * @param password
77 | * @param context
78 | * @param myinfo
79 | * @return
80 | * @throws java.sql.SQLException
81 | */
82 | public static Connection connect(DBInstanceInfo db, String username, String password, MyPerfContext context, java.util.Properties myinfo)
83 | throws java.sql.SQLException
84 | {
85 | java.util.Properties info = new java.util.Properties();
86 | info.put ("user", username);
87 | info.put ("password",password);
88 | if("oracle".equalsIgnoreCase(db.getDbType()))
89 | {
90 | info.put("oracle.net.CONNECT_TIMEOUT", String.valueOf(context.getConnectionTimeout()));
91 | info.put("oracle.net.READ_TIMEOUT", String.valueOf(context.getConnectionReadTimeout()));
92 | info.put("oracle.jdbc.ReadTimeout", String.valueOf(context.getConnectionReadTimeout()));
93 | }
94 | else if("mysql".equalsIgnoreCase(db.getDbType()))
95 | {
96 | if(myinfo.getProperty("connectTimeout")!=null )
97 | info.put("connectTimeout",myinfo.getProperty("connectTimeout"));
98 | else
99 | info.put("connectTimeout", String.valueOf(context.getConnectionTimeout()));
100 | if(myinfo.getProperty("socketTimeout")!=null )
101 | info.put("socketTimeout", myinfo.getProperty("socketTimeout"));
102 | else
103 | info.put("socketTimeout", String.valueOf(context.getConnectionReadTimeout()));
104 | }
105 | if(myinfo!=null && myinfo.size()>0)
106 | {
107 | for(Entry e: myinfo.entrySet())
108 | {
109 | if("connectTimeout".equalsIgnoreCase(e.getKey().toString()) || "socketTimeout".equalsIgnoreCase(e.getKey().toString()))
110 | continue;
111 | info.put(e.getKey(), e.getValue());
112 | }
113 | }
114 | return DriverManager.getConnection(db.getConnectionString(), info);
115 | }
116 |
117 | }
118 |
119 |
--------------------------------------------------------------------------------
/myperf/src/main/java/com/yahoo/dba/perf/myperf/db/CustomQueryProcessor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015, Yahoo Inc.
3 | * Copyrights licensed under the Apache License.
4 | * See the accompanying LICENSE file for terms.
5 | */
6 | package com.yahoo.dba.perf.myperf.db;
7 |
8 | import java.util.Map;
9 |
10 | import com.yahoo.dba.perf.myperf.common.DBInstanceInfo;
11 | import com.yahoo.dba.perf.myperf.common.MyPerfContext;
12 | import com.yahoo.dba.perf.myperf.common.QueryParameters;
13 | import com.yahoo.dba.perf.myperf.common.ResultList;
14 |
15 | public interface CustomQueryProcessor {
16 | /**
17 | *
18 | * @param context
19 | * @param dbinfo
20 | * @param appUser
21 | * @param connWrapper
22 | * @param qps original query parameters
23 | * @param rListMap output
24 | * @throws java.sql.SQLException
25 | */
26 | void queryMultiple(MyPerfContext context, DBInstanceInfo dbinfo, String appUser, DBConnectionWrapper connWrapper, QueryParameters qps, Map rListMap)
27 | throws java.sql.SQLException;
28 |
29 | /**
30 | *
31 | * @param context
32 | * @param dbinfo
33 | * @param appUser
34 | * @param connWrapper
35 | * @param qps original input
36 | * @return result
37 | * @throws java.sql.SQLException
38 | */
39 | ResultList querySingle(MyPerfContext context, DBInstanceInfo dbinfo, String appUser, DBConnectionWrapper connWrapper, QueryParameters qps)
40 | throws java.sql.SQLException;
41 |
42 | /**
43 | * indicate if it is multiple
44 | * @return
45 | */
46 | boolean isMultiple();
47 |
48 | /**
49 | * indicate if require db connection. For example, SNMP query does not need.
50 | * @return
51 | */
52 | boolean requireDBConnection();
53 | }
54 |
--------------------------------------------------------------------------------
/myperf/src/main/java/com/yahoo/dba/perf/myperf/db/DynamicQuery.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015, Yahoo Inc.
3 | * Copyrights licensed under the Apache License.
4 | * See the accompanying LICENSE file for terms.
5 | */
6 | package com.yahoo.dba.perf.myperf.db;
7 |
8 | public interface DynamicQuery
9 | {
10 | String getQueryString(DBConnectionWrapper conn, boolean gc);
11 | }
12 |
--------------------------------------------------------------------------------
/myperf/src/main/java/com/yahoo/dba/perf/myperf/db/DynamicQueryFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015, Yahoo Inc.
3 | * Copyrights licensed under the Apache License.
4 | * See the accompanying LICENSE file for terms.
5 | */
6 | package com.yahoo.dba.perf.myperf.db;
7 |
8 | import java.util.HashMap;
9 | import java.util.Map;
10 |
11 | public class DynamicQueryFactory
12 | {
13 | private static Map queryMap = new HashMap();
14 |
15 |
16 | static
17 | {
18 | //queryMap.put("com.yahoo.dba.perf.framework.process.SharedCursorQuery", new SharedCursorQuery());
19 | //queryMap.put("com.yahoo.dba.perf.framework.process.InstanceCacheTransferSummary", new InstanceCacheTransferSummary());
20 | //queryMap.put("com.yahoo.dba.perf.framework.process.InstanceCacheTransferSummaryAll", new InstanceCacheTransferSummaryAll());
21 | }
22 | public static String getQuery(String queryClass, DBConnectionWrapper conn, boolean gc)
23 | {
24 | if(queryMap.containsKey(queryClass))
25 | return queryMap.get(queryClass).getQueryString(conn, gc);
26 | return null;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/myperf/src/main/java/com/yahoo/dba/perf/myperf/db/InnoDbMutexPostProccessor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015, Yahoo Inc.
3 | * Copyrights licensed under the Apache License.
4 | * See the accompanying LICENSE file for terms.
5 | */
6 | package com.yahoo.dba.perf.myperf.db;
7 |
8 | import java.util.List;
9 | import java.util.TreeMap;
10 |
11 | import com.yahoo.dba.perf.myperf.common.ColumnDescriptor;
12 | import com.yahoo.dba.perf.myperf.common.ColumnInfo;
13 | import com.yahoo.dba.perf.myperf.common.ResultList;
14 | import com.yahoo.dba.perf.myperf.common.ResultRow;
15 |
16 | public class InnoDbMutexPostProccessor implements PostQueryResultProcessor{
17 | static class MutexName
18 | {
19 | String type;
20 | String name;
21 | String waitType;
22 | int count = 0;
23 |
24 | int val = 0;
25 |
26 | MutexName(String type, String name, String waitType)
27 | {
28 | this.type = type;
29 | this.name = name;
30 | this.waitType = waitType;
31 | }
32 |
33 |
34 | }
35 |
36 |
37 | @Override
38 | public ResultList process(ResultList rs) {
39 | TreeMap mutexMetrics = new TreeMap();
40 | if(rs!=null && rs.getRows().size()>0)
41 | {
42 | int typeIdx = 0;
43 | int nameIdx = 1;
44 | int statusIdx = 2;
45 | List colList = rs.getColumnDescriptor().getColumns();
46 | for(int i=0;i sList = row.getColumns();
60 | String type = sList.get(typeIdx);
61 | String name = sList.get(nameIdx);
62 | String status = sList.get(statusIdx);
63 | //split status to name value pair
64 | String[] nv = status.split("=");
65 | String key = type+"|"+name+"|"+nv[0];
66 | int val = Integer.parseInt(nv[1]);
67 | if(!mutexMetrics.containsKey(key))
68 | {
69 | mutexMetrics.put(key, new MutexName(type, name, nv[0]));
70 | }
71 | mutexMetrics.get(key).val += val;
72 | mutexMetrics.get(key).count ++;
73 | }catch(Exception ex){}
74 | }
75 | }
76 | //now build new List
77 | ResultList rlist = new ResultList();
78 | ColumnDescriptor desc = new ColumnDescriptor();
79 | desc.addColumn("NAME", false, 0);
80 | desc.addColumn("VALUE", true, 1);
81 | desc.addColumn("COUNT", true, 2);
82 | rlist.setColumnDescriptor(desc);
83 | for(MutexName m: mutexMetrics.values())
84 | {
85 | ResultRow row = new ResultRow();
86 | row.setColumnDescriptor(desc);
87 | row.addColumn(m.type+"/"+m.name+"/"+m.waitType);
88 | row.addColumn(String.valueOf(m.val));
89 | row.addColumn(String.valueOf(m.count));
90 | rlist.addRow(row);
91 | }
92 | return rlist;
93 | }
94 |
95 |
96 |
97 | }
98 |
--------------------------------------------------------------------------------
/myperf/src/main/java/com/yahoo/dba/perf/myperf/db/MySQLStatusQueryProcessor.java:
--------------------------------------------------------------------------------
1 | package com.yahoo.dba.perf.myperf.db;
2 |
3 | import java.sql.SQLException;
4 | import java.util.Map;
5 | import java.util.logging.Logger;
6 |
7 | import com.yahoo.dba.perf.myperf.common.ColumnDescriptor;
8 | import com.yahoo.dba.perf.myperf.common.ColumnInfo;
9 | import com.yahoo.dba.perf.myperf.common.DBInstanceInfo;
10 | import com.yahoo.dba.perf.myperf.common.MyPerfContext;
11 | import com.yahoo.dba.perf.myperf.common.QueryParameters;
12 | import com.yahoo.dba.perf.myperf.common.ResultList;
13 | import com.yahoo.dba.perf.myperf.common.ResultRow;
14 |
15 | public class MySQLStatusQueryProcessor implements CustomQueryProcessor
16 | {
17 | protected static Logger logger = Logger.getLogger(MySQLStatusQueryProcessor.class.getName());
18 | @Override
19 | public void queryMultiple(MyPerfContext context, DBInstanceInfo dbinfo, String appUser,
20 | DBConnectionWrapper connWrapper, QueryParameters qps,
21 | Map rListMap) throws SQLException {
22 | throw new RuntimeException("Not implmented");
23 |
24 | }
25 |
26 | @Override
27 | public ResultList querySingle(MyPerfContext context, DBInstanceInfo dbinfo, String appUser,
28 | DBConnectionWrapper connWrapper, QueryParameters qps)
29 | throws SQLException {
30 | QueryParameters qps2 = new QueryParameters();
31 | qps2.setSql("mysql_global_status_metrics");
32 | for(String key: qps.getSqlParams().keySet()){
33 | qps2.getSqlParams().put(key, qps.getSqlParams().get(key));
34 | }
35 | if(!qps2.getSqlParams().containsKey("p_1")) {
36 |
37 | qps2.getSqlParams().put("p_1", "");
38 | }
39 | //mysql_global_status_metrics
40 | //mysql_show_global_status
41 | ResultList rList = null;
42 | rList = context.getQueryEngine().executeQueryGeneric(qps2, connWrapper, qps.getMaxRows());
43 | if(rList != null)
44 | {
45 |
46 | ResultList newList = new ResultList();
47 | ColumnDescriptor desc = rList.getColumnDescriptor();
48 | ColumnDescriptor newDesc = new ColumnDescriptor();
49 | int idx = 0;
50 | int nameIdx = 0;
51 | for(ColumnInfo c: desc.getColumns())
52 | {
53 | if("VARIABLE_NAME".equalsIgnoreCase(c.getName()))nameIdx =idx;
54 | if("VALUE".equalsIgnoreCase(c.getName()))
55 | newDesc.addColumn("VARIABLE_VALUE", c.isNumberType(), idx++);
56 | else
57 | newDesc.addColumn(c.getName().toUpperCase(), c.isNumberType(), idx++);
58 | }
59 |
60 | newList.setColumnDescriptor(newDesc);
61 | for(ResultRow row: rList.getRows())
62 | {
63 | ResultRow newRow = new ResultRow();
64 | newRow.setColumnDescriptor(newDesc);
65 | int cols = row.getColumns().size();
66 | for(int i=0; i rListMap)
33 | throws java.sql.SQLException
34 | {
35 | for(int i=0;i> buffer ;
24 | protected java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyyMMddHHmmss");
25 |
26 |
27 | public AlertScanner()
28 | {
29 | sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
30 | }
31 | public MyPerfContext getFrameworkContext() {
32 | return frameworkContext;
33 | }
34 |
35 | public void setFrameworkContext(MyPerfContext frameworkContext) {
36 | this.frameworkContext = frameworkContext;
37 | }
38 |
39 | public AppUser getAppUser() {
40 | return appUser;
41 | }
42 |
43 | public void setAppUser(AppUser appUser) {
44 | this.appUser = appUser;
45 | }
46 |
47 |
48 | public void scanAuto()
49 | {
50 | logger.info(new java.util.Date()+": Starting auto alert scan ...");
51 | java.util.Date startDate = null;
52 | java.util.Date endDate = null;
53 |
54 | try
55 | {
56 | startDate = new java.util.Date();
57 | scan();
58 | }catch(Exception ex)
59 | {
60 | logger.log(Level.SEVERE,"Exception", ex);
61 | }
62 | endDate = new java.util.Date();
63 | logger.info(new java.util.Date()+": Auto alert scan done and status saved. Total Time in ms: "+(endDate.getTime() - startDate.getTime()));
64 | }
65 | public void scan()
66 | {
67 | Set clusternames = frameworkContext.getDbInfoManager().getMyDatabases(appUser.getName(), false).getMyDbList();
68 | logger.info("Start scan alerts");
69 | LinkedBlockingQueue dbqueue = new LinkedBlockingQueue();
70 | for(String cl: clusternames)
71 | {
72 | DBCredential cred = DBUtils.findDBCredential(frameworkContext, cl, appUser);
73 | if(cred==null)
74 | {
75 | logger.info("No credential for group "+cl+", skip it");
76 | continue;//log the error
77 | }
78 | DBGroupInfo cls = frameworkContext.getDbInfoManager().findGroup(cl);
79 | if(cls==null)
80 | {
81 | logger.info("Group "+cl+" might have been deleted.");
82 | continue;
83 | }
84 |
85 | for(DBInstanceInfo dbinfo: cls.getInstances())
86 | {
87 | dbqueue.add(dbinfo);
88 | }
89 | }
90 |
91 | int mythreadcnt = this.threadCount;
92 | if(dbqueue.size() mydbs = this.frameworkContext.getDbInfoManager().getMyDatabases(appUser.getName(), true).getMyDbList();
53 | if(mydbs == null || !mydbs.contains(dbGroupName))
54 | return this.respondFailure("As a restricted user, you have no permission to use this db group yet: " +dbGroupName, request);
55 | }
56 | //now the only thing left is update
57 |
58 | String username = request.getParameter("username");
59 | String pw = request.getParameter("pw");
60 |
61 | if(username == null || username.isEmpty()
62 | || pw == null || pw.isEmpty())
63 | return this.respondFailure("Pleaseb provide valid MySQWL account", request);
64 |
65 | DBGroupInfo dbGroup = this.frameworkContext.getDbInfoManager().findGroup(dbGroupName);;
66 |
67 | boolean testCred = "y".equals(request.getParameter("test_cred"));
68 | String testResult = null;
69 | if(testCred)
70 | {
71 | for(DBInstanceInfo db:dbGroup.getInstances())
72 | {
73 | testResult = DBUtils.testConnection(db, username, pw);
74 | if(testResult == null)
75 | {
76 | break;
77 | }else
78 | {
79 | //TODO catch the case the first server is offline
80 | return this.respondFailure(testResult, request);
81 | }
82 | }
83 | }
84 | //either test is not required, or passed
85 | DBCredential cred = new DBCredential();
86 | cred.setDbGroupName(dbGroupName);
87 | cred.setUsername(username);
88 | cred.setPassword(pw);
89 | cred.setAppUser(appUser.getName());
90 | this.frameworkContext.getMetaDb().upsertDBCredential(cred);
91 | this.frameworkContext.getDbInfoManager().getMyDatabases(cred.getAppUser(), appUser.isRestrictedUser()).addDb(cred.getDbGroupName());
92 | logger.info("Add new credential for "+cred.getDbGroupName()+", app user "+cred.getAppUser());
93 | if(testCred && testResult == null)
94 | {
95 | //we will save the cred for default user and the user used for metrics gathering
96 | //for easy on boarding
97 | this.frameworkContext.saveManagedDBCredentialForScanner(cred.getUsername(),
98 | cred.getDbGroupName(), cred.getUsername(), cred.getPassword());
99 | }
100 | return this.respondSuccess("MySQL account to access group " + dbGroupName +" has been updated successfully." , request);
101 | }
102 |
103 | }
104 |
105 |
106 |
--------------------------------------------------------------------------------
/myperf/src/main/java/com/yahoo/dba/perf/myperf/springmvc/DbsearchController.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015, Yahoo Inc.
3 | * Copyrights licensed under the Apache License.
4 | * See the accompanying LICENSE file for terms.
5 | */
6 | package com.yahoo.dba.perf.myperf.springmvc;
7 | import java.util.HashSet;
8 | import java.util.List;
9 |
10 | import javax.servlet.http.HttpServletRequest;
11 | import javax.servlet.http.HttpServletResponse;
12 |
13 | import org.springframework.web.servlet.ModelAndView;
14 |
15 | import com.yahoo.dba.perf.myperf.common.*;
16 |
17 | public class DbsearchController extends MyPerfBaseController
18 | {
19 | //private String jsonView;
20 | //private MyPerfContext frameworkContext;
21 |
22 | @Override
23 | protected ModelAndView handleRequestImpl(HttpServletRequest req,
24 | HttpServletResponse resp) throws Exception
25 | {
26 | int status = 0;
27 | String message = "OK";
28 |
29 | List mydbs = this.frameworkContext.getDbInfoManager()
30 | .listDbsByUserInfo(WebAppUtil.findUserFromRequest(req), retrieveAppUser(req).isRestrictedUser());
31 | HashSet mydbSet = new HashSet();
32 | if(mydbs != null)
33 | {
34 | for(String s: mydbs)
35 | mydbSet.add(s);
36 | }
37 | ResultList rList = new ResultList();
38 | {
39 | String keyword = req.getParameter("keyword");
40 | List dbList = this.frameworkContext.getDbInfoManager().SearchDbInfo(keyword);
41 |
42 | ColumnDescriptor desc = new ColumnDescriptor();
43 | rList.setColumnDescriptor(desc);
44 | int idx = 0;
45 | desc.addColumn("DBTYPE", false, idx++);
46 | desc.addColumn("DBGROUPNAME", false, idx++);
47 | desc.addColumn("HOSTNAME", false, idx++);
48 | desc.addColumn("PORT", false, idx++);
49 | desc.addColumn("DATABASENAME", false, idx++);
50 |
51 | for(DBInstanceInfo urp:dbList)
52 | {
53 | if(!mydbSet.contains(urp.getDbGroupName()))
54 | continue;
55 | ResultRow row = new ResultRow();
56 | List cols = new java.util.ArrayList(8);
57 | row.setColumnDescriptor(desc);
58 | row.setColumns(cols);
59 | cols.add(urp.getDbType());
60 | cols.add(urp.getDbGroupName());
61 | cols.add(urp.getHostName());
62 | cols.add(urp.getPort());
63 | cols.add(urp.getDatabaseName());
64 | rList.addRow(row);
65 | }
66 | }
67 |
68 | ModelAndView mv = new ModelAndView(this.jsonView);
69 | mv.addObject("json_result", ResultListUtil.toJSONString(rList, null, status, message));
70 | return mv;
71 | }
72 |
73 | }
74 |
--------------------------------------------------------------------------------
/myperf/src/main/java/com/yahoo/dba/perf/myperf/springmvc/HelpController.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015, Yahoo Inc.
3 | * Copyrights licensed under the Apache License.
4 | * See the accompanying LICENSE file for terms.
5 | */
6 | package com.yahoo.dba.perf.myperf.springmvc;
7 |
8 | import javax.servlet.http.HttpServletRequest;
9 | import javax.servlet.http.HttpServletResponse;
10 |
11 | import org.springframework.web.servlet.ModelAndView;
12 | import org.springframework.web.servlet.mvc.AbstractController;
13 |
14 | public class HelpController extends AbstractController{
15 |
16 | @Override
17 | protected ModelAndView handleRequestInternal(HttpServletRequest req,
18 | HttpServletResponse resp) throws Exception {
19 |
20 | String key = req.getParameter("key");
21 | if(key==null||key.trim().length()==0)key = "about";
22 | ModelAndView mv = new ModelAndView("help/"+key);
23 | return mv;
24 |
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/myperf/src/main/java/com/yahoo/dba/perf/myperf/springmvc/LogoutController.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015, Yahoo Inc.
3 | * Copyrights licensed under the Apache License.
4 | * See the accompanying LICENSE file for terms.
5 | */
6 | package com.yahoo.dba.perf.myperf.springmvc;
7 | import javax.servlet.http.HttpServletRequest;
8 | import javax.servlet.http.HttpServletResponse;
9 | import javax.servlet.http.HttpSession;
10 |
11 | import org.springframework.web.servlet.ModelAndView;
12 | import org.springframework.web.servlet.view.RedirectView;
13 |
14 | import com.yahoo.dba.perf.myperf.db.UserDBConnections;
15 |
16 | public class LogoutController extends MyPerfBaseController{
17 |
18 | @Override
19 | protected ModelAndView handleRequestImpl(HttpServletRequest req,
20 | HttpServletResponse resp) throws Exception
21 | {
22 | HttpSession sess = req.getSession();
23 |
24 | //do we have session
25 | if(sess!=null)
26 | {
27 | UserDBConnections conns = UserDBConnections.class.cast(sess.getAttribute("UserDBConnections"));
28 | sess.removeAttribute("UserDBConnections");
29 | sess.invalidate();
30 |
31 | new Thread(new LogoutCleaner(conns)).start();//make it async.
32 | //TODO Add the thread handle for central process
33 | }
34 |
35 | ModelAndView mv = new ModelAndView(new RedirectView(this.getNosessView()));
36 | return mv;
37 | }
38 |
39 | private static class LogoutCleaner implements Runnable
40 | {
41 | private UserDBConnections conns;
42 |
43 | public LogoutCleaner(UserDBConnections conns)
44 | {
45 | this.conns = conns;
46 | }
47 |
48 | public void run()
49 | {
50 | if(conns!=null){conns.setValid(false);conns.close();}
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/myperf/src/main/java/com/yahoo/dba/perf/myperf/springmvc/PerfController.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015, Yahoo Inc.
3 | * Copyrights licensed under the Apache License.
4 | * See the accompanying LICENSE file for terms.
5 | */
6 | package com.yahoo.dba.perf.myperf.springmvc;
7 |
8 | import java.util.Map;
9 | import java.util.logging.Logger;
10 |
11 | import javax.servlet.http.HttpServletRequest;
12 | import javax.servlet.http.HttpServletResponse;
13 |
14 | import org.springframework.web.servlet.ModelAndView;
15 | import org.springframework.web.servlet.view.RedirectView;
16 |
17 | /**
18 | * A common controller to display different JSP pages
19 | * @author xrao
20 | *
21 | */
22 | public class PerfController extends MyPerfBaseController
23 | {
24 | //private static Logger logger = Logger.getLogger(PerfController.class.getName());
25 | private static String HOURS[] = {"00","01","02","03","04","05","06","07","08","09",
26 | "10","11","12","13","14","15","16","17","18","19",
27 | "20","21","22","23"};
28 | private String defaultView;//if no page is supplied, display default, should not require session
29 | //private String sessExpireView;//for page requires session
30 | private Map pageMap;//page requires session, key in lower case
31 | private Map noSessionPageMap;//pages not require session, key in lower case
32 | //private MyPerfContext frameworkContext;
33 |
34 | @Override
35 | protected ModelAndView handleRequestImpl(HttpServletRequest request,
36 | HttpServletResponse response) throws Exception
37 | {
38 | String pg = request.getParameter("pg");
39 | String tgtPage = pg;
40 | if(tgtPage != null )tgtPage = tgtPage.trim().toLowerCase();
41 | if(tgtPage == null || tgtPage.isEmpty() || (!pageMap.containsKey(tgtPage) && !noSessionPageMap.containsKey(tgtPage)))
42 | tgtPage = this.defaultView;
43 | else if(pageMap.containsKey(tgtPage) && !WebAppUtil.hasValidSession(request))
44 | {
45 | return new ModelAndView(new RedirectView(this.getNosessView()));
46 | }
47 | else if(pageMap.containsKey(tgtPage))
48 | {
49 | tgtPage = pageMap.get(tgtPage);
50 | }else
51 | tgtPage = noSessionPageMap.get(tgtPage);
52 |
53 | ModelAndView mv = new ModelAndView(tgtPage);
54 |
55 | if(WebAppUtil.hasValidSession(request))
56 | {
57 | mv.addObject("mydbs", this.frameworkContext.getDbInfoManager()
58 | .listDbsByUserInfo(WebAppUtil.findUserFromRequest(request), retrieveAppUser(request).isRestrictedUser()));
59 | mv.addObject("mydbSize", this.frameworkContext.getDbInfoManager()
60 | .getMyDatabases(WebAppUtil.findUserFromRequest(request), retrieveAppUser(request).isRestrictedUser()).size());
61 | }
62 | else
63 | {
64 | mv.addObject("mydbs", this.frameworkContext.getDbInfoManager().getClusters().keySet());
65 | mv.addObject("mydbSize", 0);
66 | }
67 | mv.addObject("hours", HOURS);
68 | mv.addObject("dbMap", this.frameworkContext.getDbInfoManager().getClusters());
69 | mv.addObject("help_key", pg);
70 | mv.addObject("config", this.frameworkContext.getMyperfConfig());
71 | mv.addObject("scanner_running", this.frameworkContext.getAutoScanner().isRunning());
72 | mv.addObject("setup", this.frameworkContext.getMyperfConfig().isConfigured()?1:0);
73 |
74 | if("sp".equals(pg)||"scatterplot".equals(pg)||"m".equals(pg)||"metrics".equalsIgnoreCase(pg))
75 | mv.addObject("udms", this.frameworkContext.getMetricsList());
76 | return mv;
77 |
78 | }
79 |
80 | public String getDefaultView()
81 | {
82 | return defaultView;
83 | }
84 |
85 | public void setDefaultView(String defaultView)
86 | {
87 | this.defaultView = defaultView;
88 | }
89 |
90 |
91 | public Map getPageMap() {
92 | return pageMap;
93 | }
94 |
95 |
96 | public void setPageMap(Map pageMap) {
97 | this.pageMap = pageMap;
98 | }
99 |
100 |
101 | public Map getNoSessionPageMap() {
102 | return noSessionPageMap;
103 | }
104 |
105 |
106 | public void setNoSessionPageMap(Map noSessionPageMap) {
107 | this.noSessionPageMap = noSessionPageMap;
108 | }
109 |
110 |
111 | }
112 |
--------------------------------------------------------------------------------
/myperf/src/main/java/com/yahoo/dba/perf/myperf/springmvc/ProfileController.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015, Yahoo Inc.
3 | * Copyrights licensed under the Apache License.
4 | * See the accompanying LICENSE file for terms.
5 | */
6 | package com.yahoo.dba.perf.myperf.springmvc;
7 |
8 |
9 | import java.util.LinkedHashMap;
10 | import java.util.logging.Level;
11 | import java.util.logging.Logger;
12 |
13 | import javax.servlet.http.HttpServletRequest;
14 | import javax.servlet.http.HttpServletResponse;
15 |
16 | import org.springframework.web.servlet.ModelAndView;
17 |
18 | import com.yahoo.dba.perf.myperf.common.*;
19 | import com.yahoo.dba.perf.myperf.process.MyProfiler;
20 |
21 | public class ProfileController extends MyPerfBaseController
22 | {
23 | private static Logger logger = Logger.getLogger(ProfileController.class.getName());
24 |
25 | @Override
26 | protected ModelAndView handleRequestImpl(HttpServletRequest req,
27 | HttpServletResponse resp) throws Exception
28 | {
29 | int status = Constants.STATUS_OK;
30 | String message = "OK";
31 |
32 | String group = req.getParameter("group");
33 | String host = req.getParameter("host");
34 | boolean explainPlan = "y".equalsIgnoreCase(req.getParameter("plan"));
35 | boolean sessionStatus = "y".equalsIgnoreCase(req.getParameter("st"));
36 | boolean profile = "y".equalsIgnoreCase(req.getParameter("pf"));
37 | String dbuser = req.getParameter("dbuser");
38 | String dbpwd = req.getParameter("dbpwd");
39 | String dbname = req.getParameter("dbname");
40 | String sqltext = req.getParameter("sqltext");
41 | String format = req.getParameter("format");
42 | boolean useJson = "json".equalsIgnoreCase(format) && explainPlan;
43 | if(useJson)
44 | {
45 | sessionStatus = false;
46 | profile = false;
47 | }
48 | logger.info("profiling "+sqltext);
49 | ResultList rList = null;
50 | LinkedHashMap listMap = new LinkedHashMap();
51 | String jsonString = null;
52 | MyProfiler profiler = new MyProfiler();
53 | DBInstanceInfo dbinfo = null;
54 | try
55 | {
56 | dbinfo = this.frameworkContext.getDbInfoManager().findDB(group,host).copy();
57 | if(dbuser==null||dbuser.isEmpty())
58 | {
59 | //use build in credential
60 | AppUser appUser = null;
61 | DBCredential cred = null;
62 | appUser = AppUser.class.cast(req.getSession().getAttribute(AppUser.SESSION_ATTRIBUTE));
63 | if(appUser==null)
64 | throw new RuntimeException("No user found. Session might not be valid.");
65 | cred = WebAppUtil.findDBCredential(this.frameworkContext, dbinfo.getDbGroupName(), appUser);
66 | if(cred!=null)
67 | {
68 | dbuser = cred.getUsername();
69 | dbpwd = cred.getPassword();
70 | }
71 | }
72 | profiler.setDbinfo(dbinfo);
73 | profiler.setFrameworkContext(frameworkContext);
74 | if(dbname!=null && !dbname.isEmpty())
75 | dbinfo.setDatabaseName(dbname);
76 | profiler.setSqlText(sqltext);
77 | profiler.connect(dbuser, dbpwd, explainPlan && !profile && !sessionStatus);
78 | if(useJson)
79 | {
80 | jsonString = profiler.runExplainPlanJson();
81 | }
82 | else if(explainPlan)listMap.put("plan", profiler.runExplainPlan());
83 | if(profile)listMap.put("profile",profiler.runProfile());
84 | if(sessionStatus)listMap.put("stats", profiler.runStats());
85 | }catch(Exception ex)
86 | {
87 | status = Constants.STATUS_BAD;
88 | message = "Error when profiling: "+ex.getMessage();
89 | logger.log(Level.WARNING, "Error when profiling", ex);
90 | }finally
91 | {
92 | if(profiler!=null)profiler.destroy();
93 | }
94 | ModelAndView mv = null;
95 | mv = new ModelAndView(this.jsonView);
96 | if(req.getParameter("callback")!=null&&req.getParameter("callback").trim().length()>0)
97 | mv.addObject("callback", req.getParameter("callback"));//YUI datasource binding
98 | if(jsonString==null)
99 | mv.addObject("json_result", ResultListUtil.toMultiListJSONStringUpper(listMap, null, status, message));
100 | else
101 | mv.addObject("json_result", jsonString);
102 | return mv;
103 | }
104 |
105 | }
106 |
--------------------------------------------------------------------------------
/myperf/src/main/java/com/yahoo/dba/perf/myperf/springmvc/ResourceSessionListener.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015, Yahoo Inc.
3 | * Copyrights licensed under the Apache License.
4 | * See the accompanying LICENSE file for terms.
5 | */
6 | package com.yahoo.dba.perf.myperf.springmvc;
7 |
8 | import java.util.logging.Logger;
9 |
10 | import javax.servlet.http.HttpSessionEvent;
11 | import javax.servlet.http.HttpSessionListener;
12 |
13 | import com.yahoo.dba.perf.myperf.common.*;
14 | import com.yahoo.dba.perf.myperf.db.*;
15 |
16 | public class ResourceSessionListener implements HttpSessionListener {
17 | private static Logger logger = Logger.getLogger(ResourceSessionListener.class.getName());
18 | public void sessionCreated(HttpSessionEvent evt) {}
19 |
20 | public void sessionDestroyed(HttpSessionEvent evt)
21 | {
22 | AppUser appUser = AppUser.class.cast(evt.getSession().getAttribute(AppUser.SESSION_ATTRIBUTE));
23 | UserDBConnections conns = UserDBConnections.class.cast(evt.getSession().getAttribute("UserDBConnections"));
24 | if(conns!=null)
25 | {
26 | if(appUser!=null)
27 | {
28 | logger.info("Session destroyed. Close all connections held by "+appUser.getName());
29 | }
30 | conns.setValid(false);
31 | conns.close();
32 | evt.getSession().removeAttribute("UserDBConnections");
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/myperf/src/main/java/com/yahoo/dba/perf/myperf/springmvc/SigninController.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015, Yahoo Inc.
3 | * Copyrights licensed under the Apache License.
4 | * See the accompanying LICENSE file for terms.
5 | */
6 | package com.yahoo.dba.perf.myperf.springmvc;
7 | import java.util.logging.Logger;
8 |
9 | import javax.servlet.http.HttpServletRequest;
10 | import javax.servlet.http.HttpServletResponse;
11 |
12 | import org.springframework.web.servlet.ModelAndView;
13 | import org.springframework.web.servlet.mvc.AbstractController;
14 | import org.springframework.web.servlet.view.RedirectView;
15 |
16 | import com.yahoo.dba.perf.myperf.common.*;
17 |
18 | /**
19 | * signin.html controller
20 | * @author xrao
21 | *
22 | */
23 | public class SigninController extends AbstractController
24 | {
25 | private MyPerfContext frameworkContext;
26 | private static final String DEFAULT_ERROR = "Invalid user name or password.";
27 | private static Logger logger = Logger.getLogger(SigninController.class.getName());
28 | private String loginFormView;
29 | private String loginSuccessView;
30 | private String setupView;
31 |
32 | public MyPerfContext getFrameworkContext()
33 | {
34 | return frameworkContext;
35 | }
36 |
37 | public void setFrameworkContext(MyPerfContext frameworkContext)
38 | {
39 | this.frameworkContext = frameworkContext;
40 | }
41 |
42 |
43 | @Override
44 | protected ModelAndView handleRequestInternal(HttpServletRequest request,
45 | HttpServletResponse resp) throws Exception
46 | {
47 | logger.info("receive url path: "+request.getContextPath()+","+request.getRequestURI()+", "+request.getServletPath()+", parameters: "+request.getQueryString());
48 | boolean failed = false;
49 | String message = null;
50 | String username = request.getParameter("name");
51 | if(username!=null)
52 | {
53 | username = username.trim().toLowerCase();
54 | //find the user from the system cache
55 | AppUser appUser = this.frameworkContext.getAuth().findUserByName(username);
56 |
57 | //sign in process
58 | boolean authed = this.frameworkContext.getAuth().login(appUser, request);
59 |
60 | if(authed)//display
61 | {
62 | String view = getLoginSuccessView();
63 | //if admin user, and setup not done yet, send to setup.
64 | if(appUser.isAdminUser() && !frameworkContext.getMyperfConfig().isConfigured())
65 | view = this.getSetupView();
66 | else if(!appUser.isAdminUser() && !appUser.isVerified())
67 | {
68 | failed = true;
69 | message = "Your signup has not been confirmed by any administrator user yet.";
70 | }
71 | if(!failed)
72 | {
73 | logger.info(appUser.getName()+" login, redirect to "+view);
74 | return new ModelAndView(new RedirectView(view));
75 | }
76 | }//if(appUser!=null && appUser.match(request.getParameter("pd"))
77 | else
78 | {
79 | failed = true;
80 | message = DEFAULT_ERROR;
81 |
82 | }
83 | }//if(username!=null)
84 |
85 | //not authenticated? Try again
86 | //TODO add retry count
87 | long server_ts = System.currentTimeMillis();
88 | int seed = (int)(Math.random()*Integer.MAX_VALUE);
89 | ModelAndView mv = new ModelAndView(getLoginFormView());
90 | mv.addObject("name", username);
91 | if(failed)mv.addObject("message", message);
92 | mv.addObject("help_key", "start");
93 | mv.addObject("server_ts", server_ts);
94 | mv.addObject("ars", seed);//ars: authentication random seed
95 | mv.addObject("setup", this.frameworkContext.getMyperfConfig().isConfigured()?1:0);
96 | //add store them in session
97 | request.getSession(true).setAttribute(AppUser.SERVER_TS, new Long(server_ts));
98 | request.getSession().setAttribute(AppUser.RANDOM_SEED, new Integer(seed));
99 |
100 | return mv;
101 | }
102 |
103 | public String getLoginFormView()
104 | {
105 | return loginFormView;
106 | }
107 |
108 | public void setLoginFormView(String loginFormView)
109 | {
110 | this.loginFormView = loginFormView;
111 | }
112 |
113 | public String getLoginSuccessView()
114 | {
115 | return loginSuccessView;
116 | }
117 |
118 | public void setLoginSuccessView(String loginSuccessView)
119 | {
120 | this.loginSuccessView = loginSuccessView;
121 | }
122 |
123 | public String getSetupView() {
124 | return setupView;
125 | }
126 |
127 | public void setSetupView(String setupView) {
128 | this.setupView = setupView;
129 | }
130 | }
131 |
--------------------------------------------------------------------------------
/myperf/src/main/java/com/yahoo/dba/perf/myperf/springmvc/TermController.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015, Yahoo Inc.
3 | * Copyrights licensed under the Apache License.
4 | * See the accompanying LICENSE file for terms.
5 | */
6 | package com.yahoo.dba.perf.myperf.springmvc;
7 | import javax.servlet.http.HttpServletRequest;
8 | import javax.servlet.http.HttpServletResponse;
9 |
10 | import org.springframework.web.servlet.ModelAndView;
11 |
12 | import com.yahoo.dba.perf.myperf.common.*;
13 |
14 | /**
15 | * Terminology lookup
16 | * @author xrao
17 | *
18 | */
19 | public class TermController extends MyPerfBaseController
20 | {
21 | @Override
22 | protected ModelAndView handleRequestImpl(HttpServletRequest req,
23 | HttpServletResponse resp) throws Exception
24 | {
25 |
26 | String[] names = req.getParameterValues("name");
27 | ModelAndView mv = new ModelAndView(jsonView);
28 | String res = "";
29 | for(String name: names)
30 | {
31 | if(name==null||name.isEmpty())continue;
32 | if(!name.startsWith("plan."))
33 | {
34 | String desc = this.frameworkContext.getStatDefManager().getStatDescription(name);
35 | if(desc==null)desc = "no description found.";
36 | if(name!=null && name.startsWith("mysql_status"))
37 | name = name.substring(13);
38 | if(res.length()>0)
39 | res += " ";
40 | res += ""+name+" : "+desc;
41 | }else
42 | {
43 | String[] names2 = name.split(";");
44 | for(String name2: names2)
45 | {
46 | if(name2==null||"plan.extra.".equals(name2)||"plan.select_type.".equals(name2)
47 | ||"plan.join_type.".equals(name2))continue;
48 | name2 = name2.trim();
49 | if(name.startsWith("plan.extra.") && !name2.startsWith("plan.extra."))
50 | name2 = "plan.extra."+name2;
51 | if(name2.indexOf('(')>=0)
52 | name2 = name2.substring(0, name2.indexOf('('));
53 | else if(name2.startsWith("plan.extra.Cost"))
54 | name2 = "plan.extra.Cost";
55 | String desc = this.frameworkContext.getStatDefManager().getStatDescription(name2);
56 | if(desc==null)desc = "no description found.";
57 | if(res.length()>0)
58 | res += " ";
59 | res += ""+name2.substring(5)+" : "+desc;
60 |
61 | }
62 | }
63 | }
64 |
65 | mv.addObject("json_result", ResultListUtil.toJSONString(null, null, 0, res));
66 | return mv;
67 | }
68 |
69 | }
70 |
--------------------------------------------------------------------------------
/myperf/src/main/webapp/WEB-INF/decorators.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 | /service/*
9 | /image/*
10 | /img/*
11 |
12 |
13 | /*
14 |
15 |
16 |
--------------------------------------------------------------------------------
/myperf/src/main/webapp/WEB-INF/jsp/commheader.jsp:
--------------------------------------------------------------------------------
1 | <%@page trimDirectiveWhitespaces="true"%>
2 | <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
3 | <%--
4 | Copyright 2015, Yahoo Inc.
5 | Copyrights licensed under the Apache License.
6 | See the accompanying LICENSE file for terms.
7 | --%>
8 | <%
9 | String protocol = System.getProperty("url_protocl", "http");
10 | if(!"https".equalsIgnoreCase(protocol))protocol="http";
11 | %>
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
51 |
--------------------------------------------------------------------------------
/myperf/src/main/webapp/WEB-INF/jsp/dashboard.jsp:
--------------------------------------------------------------------------------
1 | <%@page trimDirectiveWhitespaces="true"%>
2 | <%@page import="com.yahoo.dba.perf.myperf.common.*" %>
3 | <%@ page import="java.util.*" %>
4 | <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
5 | <%--
6 | Copyright 2015, Yahoo Inc.
7 | Copyrights licensed under the Apache License.
8 | See the accompanying LICENSE file for terms.
9 | --%>
10 |
11 |
12 |
13 | DB Status
14 |
15 |
16 |
19 |
20 | <%
21 | String rptFormat = "formatAlertNoDownload";
22 | if(session!=null && session.getAttribute(AppUser.SESSION_ATTRIBUTE) != null)
23 | rptFormat = "formatAlert";
24 | %>
25 |
26 |
27 |
28 |
Database Status
29 |
30 | All
31 |
32 |
33 | =mydbSize?"style='color:red;'":""}>${cluster}
34 |
35 |
36 | =mydbSize?"style='color:red;'":""}>${cluster}
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
49 |
50 |
53 |
54 |
Red color means the issue is still on going.
55 |
56 |
57 |
58 |
59 |
60 |
61 |
103 |
104 |
--------------------------------------------------------------------------------
/myperf/src/main/webapp/WEB-INF/jsp/datalist.jsp:
--------------------------------------------------------------------------------
1 |
2 | <%@page trimDirectiveWhitespaces="true"%>
3 | <%@page contentType="text/xml" %>
4 | <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
5 | <%--
6 | Copyright 2015, Yahoo Inc.
7 | Copyrights licensed under the Apache License.
8 | See the accompanying LICENSE file for terms.
9 | --%>
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | ${col}
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/myperf/src/main/webapp/WEB-INF/jsp/dbsearch.jsp:
--------------------------------------------------------------------------------
1 | <%@page trimDirectiveWhitespaces="true"%>
2 | <%--
3 | Copyright 2015, Yahoo Inc.
4 | Copyrights licensed under the Apache License.
5 | See the accompanying LICENSE file for terms.
6 | --%>
7 | px;left:<%= request.getParameter("x") %>px;width:640px;background-color:white;border:1px solid silver;display:none;z-index:1000;">
8 |
Database Name Search
9 |
Keyword:
10 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/myperf/src/main/webapp/WEB-INF/jsp/help/about.jsp:
--------------------------------------------------------------------------------
1 | <%--
2 | Copyright 2015, Yahoo Inc.
3 | Copyrights licensed under the Apache License.
4 | See the accompanying LICENSE file for terms.
5 | --%>
6 |
7 |
8 | About MySQL Perf Analyzer
9 |
10 |
11 |
12 | About MySQL Perf Analyzer
13 | MySQL Perf Analyzer is an open source project from Yahoo DBA team. It is a
14 | simple web application to access, gather ad analyze MySQL database performance
15 | related data. The purpose of this tool is to give the user an easy, fast and
16 | safe tool for MySQL performance monitoring and analysis.
17 |
18 | The following third party open source projects are used:
19 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/myperf/src/main/webapp/WEB-INF/jsp/help/account.jsp:
--------------------------------------------------------------------------------
1 | <%--
2 | Copyright 2015, Yahoo Inc.
3 | Copyrights licensed under the Apache License.
4 | See the accompanying LICENSE file for terms.
5 | --%>
6 |
7 |
8 | MySQL perf Analyzer Help - User Account
9 |
10 |
11 |
12 | User Account
13 | Use this page to register a new user, modify information like email or rest password, and remove users.
14 | Only a power user can update other user's information. Note while email is used for offline communication,
15 | the email is handled by Linux shell command "mailx".
16 |
17 | In general, user access control is only limited on direct target database accesses, not meta data or metrics.
18 | If it is desired to limit visibility of database groups by a specific user, the user should be created as "restricted
19 | User", and DB info page can be used to manage such type of access control.
20 |
21 |
22 |
--------------------------------------------------------------------------------
/myperf/src/main/webapp/WEB-INF/jsp/help/dbcred.jsp:
--------------------------------------------------------------------------------
1 | <%--
2 | Copyright 2015, Yahoo Inc.
3 | Copyrights licensed under the Apache License.
4 | See the accompanying LICENSE file for terms.
5 | --%>
6 |
7 |
8 | MySQL Perf Analyzer Help - Database Credential
9 |
10 |
11 |
12 | Database Credentials
13 | The current Performance Analyzer implementation does not provide common database account and credentials to access a target database.
14 | A user has to provide database accounts and passwords to access the target databases. The account needs at least the following privileges:
15 |
16 | PROCESS privilege to access INFORMATION_SCHEMA and INNODB information.
17 | To check replication status, the account needs REPLCATION_CLIENT privileges.
18 | To access PERFORMANCE_SCHEMA, at least SELECT on PERFORMANCE_SCHEMA is required.
19 | To access meta data such as database and table information, "SHOW DATABASES" privilege is required.
20 | To access table and view information of a given database, "SELECT" privilege on the given database is required.
21 | To access view definition, "SHOW VIEW" privilege on the given database is required.
22 |
23 |
24 | Fields:
25 |
26 | Database Group Name : the unique identifier for the target database. You can use DB Info page, Search DB tab to look up this information.
27 | DB User Name : the database account, for example, dbsmnp.
28 | DB Passowrd : the password of the database account.
29 | Retype Passowrd : the password of the database account.
30 | Test Passowrd : if checked, upon submit, the analyzer will connect to the target database to verify the password.
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/myperf/src/main/webapp/WEB-INF/jsp/help/m.jsp:
--------------------------------------------------------------------------------
1 | <%--
2 | Copyright 2015, Yahoo Inc.
3 | Copyrights licensed under the Apache License.
4 | See the accompanying LICENSE file for terms.
5 | --%>
6 |
7 |
8 | MySQL Perf Analyzer Help - Metrics
9 |
10 |
11 |
12 | Database Metrics Page
13 | This page displays a selected set of charts for performance metrics gathered
14 | from MySQL global status and SNMP which we think are most common for performance analysis.
15 | You can also access all the metrics gathered for any specific database server,
16 | or compare and research interrelationships among multiple metrics. Further more,
17 | you can view and compare any metrics for a set of database servers.
18 | It no time range is selected, it will display chart for past 24 hours.
19 | Additional metrics can be added using UDM .
20 |
21 |
22 |
--------------------------------------------------------------------------------
/myperf/src/main/webapp/WEB-INF/jsp/help/mt.jsp:
--------------------------------------------------------------------------------
1 | <%--
2 | Copyright 2015, Yahoo Inc.
3 | Copyrights licensed under the Apache License.
4 | See the accompanying LICENSE file for terms.
5 | --%>
6 |
7 |
8 | MySQL Perf Analyzer Help - Meta Data
9 |
10 |
11 |
12 | Database Metq Data
13 | This page is used to access meta data about databases, tables and views.
14 | To use it, first select a database server and click "Go" button" to display all databases/schemas.
15 | If the desired database/schema is not displayed, make sure the database user has "SHOW DATABASES" privilege.
16 | If "SHOW DATABASES" privilege was just added, you might need logout the analyzer and relogin to get a new connection to the database.
17 | To view tables and views, you can click the concerned database/schema to populate the database name or fill it manually.
18 | Then select "Tables" Or "Views" to display the tables or views. Because "show table status from schem_name" or access to information_schema.tables
19 | will cause MySQL to sample the tables with disk reads (controlled by INNODB_STATS_ON_METADATA, default to ON for MySQL5.1 and MySQL 5.5, and innodb_stats_sample_pages or innodb_stats_transient_sample_pages,
20 | default to 8),
21 | here we only use "show tables from schema_name" to display all tables belonging to the same schema.
22 |
23 | Once tables or views are retrieved, use context menu (right click) to view table details or view definition.
24 |
25 |
--------------------------------------------------------------------------------
/myperf/src/main/webapp/WEB-INF/jsp/help/pf.jsp:
--------------------------------------------------------------------------------
1 | <%--
2 | Copyright 2015, Yahoo Inc.
3 | Copyrights licensed under the Apache License.
4 | See the accompanying LICENSE file for terms.
5 | --%>
6 |
7 |
8 | MySQL Perf Analyzer Help - Metrics
9 |
10 |
11 |
12 | Query Profile Page
13 | This page can be used for query explain plan and profiling. MySQL does not store query performance metrics. It does not store query execution plan and query text.
14 | This page requires a MySQL user which can access the schemas (databases). The MySQL user for performance analyzer only requires to access INFORMATION_SCHEMA, PERFORMANCE_SCHEMA and INNODB status.
15 | EXPLAIN is the main tool for query tuning. From the output, the user should have pretty good idea about the issues, for example, lacking of appropriate indexes, temp table usages, etc.
16 | Once Session Status and/or Profile box is checked, the analyzer will actually run the query to gather statistics. For MySQL 5.6, profiling can be done by enabling stage level instruments.
17 |
18 |
--------------------------------------------------------------------------------
/myperf/src/main/webapp/WEB-INF/jsp/help/ps.jsp:
--------------------------------------------------------------------------------
1 | <%--
2 | Copyright 2015, Yahoo Inc.
3 | Copyrights licensed under the Apache License.
4 | See the accompanying LICENSE file for terms.
5 | --%>
6 |
7 |
8 | Database Performance Analyzer Help - Performance Schema
9 |
10 |
11 |
12 | Performance Schema Page
13 | This page is used to display performance schema setup, realtime data and summary data.
14 | Performance schema was introduced in MySQL 5.5 to simulate Oracle wait events. Performance schema is enabled by default with MySQL 5.6.
15 | But for MySQL 5.5, a line "performance_schema" has to be presented inside my.cnf to enable performance schema. The overhead with
16 | performance schema is within 10%. For MySQL 5.6, if all instruments are enabled, the overhead will be much higher.
17 | The feature of MySQL 5.5 performance schema is very limited. The basic function is to understand the waits such as kernel mutex, etc.
18 |
MySQL 5.6 has enhanced performance schema significantly. Now it can be used to find out high cost queries, and it can also be used to
19 | replace traditional profiling function. But it is still tricky to use it, for example, the tables might be required frequently truncation
20 | to hold fresh information.
21 |
22 |
--------------------------------------------------------------------------------
/myperf/src/main/webapp/WEB-INF/jsp/help/rt.jsp:
--------------------------------------------------------------------------------
1 | <%--
2 | Copyright 2015, Yahoo Inc.
3 | Copyrights licensed under the Apache License.
4 | See the accompanying LICENSE file for terms.
5 | --%>
6 |
7 |
8 | MySQL Perf Analyzer Help - Metrics
9 |
10 |
11 |
12 | Database Realtime Information Page
13 | This page display some realtime information collected from INFORMATION_SCHEMA and various "SHOW ..." command.
14 |
15 |
Tabs :
16 |
17 | Processes: the results from "SHOW PROCESSLIST". It can be used to check how busy the database is and to identify some long running queries and their status. It is not very useful for OLTP where most of the queries complete within a second.
18 | Global Status: the results from global_status table. The refresh button can be used to calculate the differences since the first time the data is displayed, and this feature can be useful to capture important metrics for a period of time to understand how the resources are consumed. To start a new period, use the menu from drop down list to re-query/refresh the data.
19 | Global Variables: this can be a convenient place to check server configurations.
20 | Variable Diffs: this can be used to compare configurations of two MySQL servers.
21 | User Stats: this is only available on Percona server and requires variable userstat_running on. It is supposed to give some time based metrics and resource usages per user base. Note MySQL does not have other time based metrics available.
22 | Innodb Engine Status: decoded data from "show engine innodb status".
23 | Innodb Statistics: data from INFORMATION_SCHEMA related to innodb, for example, transactions, mutext, locks and buffer pool statistics.
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/myperf/src/main/webapp/WEB-INF/jsp/help/settings.jsp:
--------------------------------------------------------------------------------
1 | <%--
2 | Copyright 2015, Yahoo Inc.
3 | Copyrights licensed under the Apache License.
4 | See the accompanying LICENSE file for terms.
5 | --%>
6 |
7 |
8 | MySQL perf Analyzer Help - Settings
9 |
10 |
11 |
12 | Settings For Metrics Collection Scanner, Metrics Storage and Alerts
13 | A power user can use this page to configure how metrics are collected. At minimum, a user name (of the analyzer) has to be provided.
14 | The analyzer will use the credentials (MySQL server account information for concerned MySQL server) from the selected user to query
15 | MySQL server for global status and other user defined metrics. If the purpose is to watch a large number of MySQL servers, it is recommended
16 | to pick a MySQL database as metrics storage.
17 |
18 |
19 | Scanning on dead hosts/MySQL servers can cause unnecessary delays because of network timeout or UDP wait time.
20 | To avoid such delays, you can either use this page to disable metrics and SMNMP gatherings, or remove the host
21 | from management.
22 |
23 |
24 |
--------------------------------------------------------------------------------
/myperf/src/main/webapp/WEB-INF/jsp/help/snmp.jsp:
--------------------------------------------------------------------------------
1 | <%--
2 | Copyright 2015, Yahoo Inc.
3 | Copyrights licensed under the Apache License.
4 | See the accompanying LICENSE file for terms.
5 | --%>
6 |
7 |
8 | MySQL Perf Analyzer Help - SNMP Test
9 |
10 |
11 |
12 | SNMP Test Page
13 | MySQL does not provide a SQL path to access OS level performance metrics.
14 | MySQL Perf Analyzer relies SNMP (and UDP) to gather such data, and currently
15 | only supports Linux server. You can use this page to test if SNMP data
16 | for any specific server is available. Use Settings
17 | to disable or enable SNMP data gathering.
18 |
19 |
20 |
--------------------------------------------------------------------------------
/myperf/src/main/webapp/WEB-INF/jsp/help/st.jsp:
--------------------------------------------------------------------------------
1 | <%--
2 | Copyright 2015, Yahoo Inc.
3 | Copyrights licensed under the Apache License.
4 | See the accompanying LICENSE file for terms.
5 | --%>
6 |
7 |
8 | Dashboard - MySQL Perf Analyzer
9 |
10 |
11 |
12 | Performance Dashboard
13 | This page displays most recent snapshot of major performance metrics and
14 | past 24 hours of alerts (abnormal detections) for all database server groups
15 | or a selected group. The results are displayed in colored text, if there are
16 | any performance issues requiring user attention. For login user, individual
17 | alerts will present download-able forensic data gathered at the time the
18 | abnormality was detected.
19 |
20 |
21 |
--------------------------------------------------------------------------------
/myperf/src/main/webapp/WEB-INF/jsp/help/start.jsp:
--------------------------------------------------------------------------------
1 | <%--
2 | Copyright 2015, Yahoo Inc.
3 | Copyrights licensed under the Apache License.
4 | See the accompanying LICENSE file for terms.
5 | --%>
6 |
7 |
8 | MySQL Performance Analyzer Help - Start
9 |
10 |
11 |
12 | MySQL Performance Analyzer Help - Start
13 | Account
14 | You need have an account to use MySQL Performance Analyzer, which currently uses its own simple user account management system.
15 | Information about the default power user account can be located inside README_MYPERF.TXT at the installation directory.
16 | There are two ways to add a user account:
17 |
18 | Self registration: Self registration will create a standard user. A power user can change the new user's privilege.
19 | An new user account can be added by a power user.
20 |
21 |
22 |
23 | If this is the first time MySQL performance analyzer is used, the following steps are required:
24 |
25 | Configure Metric scanner .
26 | Onboard MySQL servers .
27 |
28 |
29 |
30 | If this is the first use for any user, please note the followings.
31 |
32 | Metrics charts can always be accessed if available.
33 | If the concerned MySQL server is not listed, onboard MySQL servers and notify the admin user to add it for metrics collections.
34 | For any concerned MySQL server, use credential page to add MySQL user account with right privileges so that the user can access other tools.
35 |
36 |
37 | Please send comments, suggestions and feature requests to perf-dba@yahoo-inc.com
38 |
39 |
--------------------------------------------------------------------------------
/myperf/src/main/webapp/WEB-INF/jsp/help/top.jsp:
--------------------------------------------------------------------------------
1 | <%--
2 | Copyright 2015, Yahoo Inc.
3 | Copyrights licensed under the Apache License.
4 | See the accompanying LICENSE file for terms.
5 | --%>
6 |
7 |
8 | Top - MySQL Perf Analyzer
9 |
10 |
11 |
12 | Performance Top Metrics
13 | This page displays selected metrics changes and process list in real time. It continuously polls various resources,
14 | including SNMP data when applicable, global status, replication status, etc. Use start/stop button to start/stop
15 | this process.
16 |
17 |
18 |
--------------------------------------------------------------------------------
/myperf/src/main/webapp/WEB-INF/jsp/help/udm.jsp:
--------------------------------------------------------------------------------
1 | <%--
2 | Copyright 2015, Yahoo Inc.
3 | Copyrights licensed under the Apache License.
4 | See the accompanying LICENSE file for terms.
5 | --%>
6 |
7 |
8 | Database Performance Analyzer Help - User Defined Metrics
9 |
10 |
11 |
12 | User Defined Metrics
13 | This page is used to define simple metrics and assign database associations.
14 | To add a new UDM or modified an existing one, click link UDM to display available UMDs and the link to add new UDM.
15 | The UDM Name should be short and only alpha numeric and underscore are allowed. A SELECT SQ L statement should be provided
16 | and the Metrics are a comma separated column list from the SQL statement. If the metrics values are accumulated, for example,
17 | like bytes_sent from global status, check the Value Accumulated check box. It is strongly recommended to pick a database
18 | to test the validity.
19 | To associate a UDM to a database or remove it, use Databases link. Click the concerned database, then check any available UDM to
20 | associate the UDM to the database, or uncheck to remove it. Once selected, the UDM will be added to the scheduled metrics scan and the results
21 | will be accessible from Metrics page, link Scatter Plot And More .
22 |
23 |
--------------------------------------------------------------------------------
/myperf/src/main/webapp/WEB-INF/jsp/jsonresult.jsp:
--------------------------------------------------------------------------------
1 | <%@page trimDirectiveWhitespaces="true"%>
2 | <%@page contentType="application/json" %>
3 | <%--
4 | Copyright 2015, Yahoo Inc.
5 | Copyrights licensed under the Apache License.
6 | See the accompanying LICENSE file for terms.
7 | --%>
8 | ${json_result}
9 |
--------------------------------------------------------------------------------
/myperf/src/main/webapp/WEB-INF/jsp/resetpwd.jsp:
--------------------------------------------------------------------------------
1 | <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
2 | <%--
3 | Copyright 2015, Yahoo Inc.
4 | Copyrights licensed under the Apache License.
5 | See the accompanying LICENSE file for terms.
6 | --%>
7 |
8 |
9 |
10 | Reset Password
11 |
14 |
15 |
16 |
17 |
18 | ${message} Please go to Sign In page to sign in.
19 |
20 |
21 | ${message}
22 |
23 |
24 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/myperf/src/main/webapp/WEB-INF/jsp/signin.jsp:
--------------------------------------------------------------------------------
1 | <%@page trimDirectiveWhitespaces="true"%>
2 | <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
3 | <%--
4 | Copyright 2015, Yahoo Inc.
5 | Copyrights licensed under the Apache License.
6 | See the accompanying LICENSE file for terms.
7 | --%>
8 |
9 |
10 |
11 | User Sign In Page
12 |
13 |
14 |
15 |
16 |
17 |
18 |
60 |
61 | ${message}
62 |
63 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/myperf/src/main/webapp/WEB-INF/jsp/test.jsp:
--------------------------------------------------------------------------------
1 | <%@page trimDirectiveWhitespaces="true"%>
2 | <%@ page import="com.yahoo.dba.perf.myperf.ui.*" %>
3 | <%@ page import="java.util.*" %>
4 | <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
5 | <%--
6 | Copyright 2015, Yahoo Inc.
7 | Copyrights licensed under the Apache License.
8 | See the accompanying LICENSE file for terms.
9 | --%>
10 |
11 |
12 |
13 | Test Page
14 |
15 |
16 |
17 |
18 |
19 |
50 |
51 |
52 | You have not provided any database credential yet. Please use DB Credential page to provide access information for databases you are interested in.
53 |
54 |
55 |
56 | Database:
57 |
58 | process list
59 | global status
60 |
61 |
62 |
63 |
75 |
76 |
123 |
124 |
--------------------------------------------------------------------------------
/myperf/src/main/webapp/WEB-INF/sitemesh.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/myperf/src/main/webapp/WEB-INF/web.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 | MySQL Database Performance Tool
9 |
10 | userDbConnectionSessionListener
11 | com.yahoo.dba.perf.myperf.springmvc.ResourceSessionListener
12 |
13 |
14 | sitemesh
15 |
16 | com.opensymphony.module.sitemesh.filter.PageFilter
17 |
18 |
19 |
20 | sitemesh
21 | *.jsp
22 |
23 |
24 | sitemesh
25 | *.htm
26 |
27 |
28 | GzipFilter
29 | org.eclipse.jetty.servlets.GzipFilter
30 |
31 | mimeTypes
32 | application/json
33 |
34 |
35 |
36 | GzipFilter
37 | *.html
38 |
39 |
40 | dispatcher
41 | org.springframework.web.servlet.DispatcherServlet
42 | 1
43 |
44 |
45 | dispatcher
46 | *.json
47 |
48 |
49 | dispatcher
50 | *.htm
51 |
52 |
53 | dispatcher
54 | *.html
55 |
56 |
57 | dispatcher
58 | *.html/*
59 |
60 |
61 |
62 |
63 | /WEB-INF/taglib/messadmin-core.tld
64 |
65 | /WEB-INF/taglib/messadmin-core.tld
66 |
67 |
68 |
69 | /WEB-INF/taglib/messadmin-fmt.tld
70 |
71 | /WEB-INF/taglib/messadmin-fmt.tld
72 |
73 |
74 |
75 |
76 | 30
77 |
78 |
79 | index.jsp
80 |
81 |
--------------------------------------------------------------------------------
/myperf/src/main/webapp/css/theme.css:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015, Yahoo Inc.
3 | * Copyrights licensed under the Apache License.
4 | * See the accompanying LICENSE file for terms.
5 | */
6 | body {margin:0; padding:0; background-color: #FFFFFF;}
7 | body, td, th, select, input, li, p, span, div{
8 | font-family: "Segoe WP", "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Verdana, Arial, sans-serif;
9 | font-size: 12px;
10 | }
11 | code{font-family: Courier, monospace; font-size: 12px;}
12 | a {text-decoration: none;}
13 | a:link {color:#36a;}
14 | a:visited {color:#47a;}
15 | a:active, a:hover {color:#69c;}
16 | h2 {color: #000;font-weight:900;font-size: x-large;}
17 | h3 {color: #000;font-weight: normal;font-size: large;}
18 | h4 {color: #000;font-weight: normal;font-size: large;}
19 | h5 {color: #000;}
20 | p {line-height: 1em;}
21 | strong {font-weight: bold;}
22 |
23 | table.bodyTable th {
24 | color: white;
25 | background-color: #bbb;
26 | text-align: left;
27 | font-weight: bold;
28 | font-size: 1em;
29 | background-color: #EAEAEA;
30 | font-weight: bold;
31 | color: #000000;
32 | }
33 |
34 | table.bodyTable td {font-size: 1em; background-color: #FFFFFF;}
35 |
36 | .bodyTableSection {
37 | font-size: larger;
38 | background-color: #EAEAEA;
39 | font-weight: bolder;
40 | color: #000000;
41 | padding: 5px;
42 | }
43 |
44 | table.bodyTable tr.a { background-color: #ddd;}
45 |
46 | table.bodyTable tr.b { background-color: #eee;}
47 |
48 | .source { border: 1px solid #999;}
49 |
50 | .hide { display: none;}
51 |
52 | /* This class sets the width and position for all rows */
53 | .inside{
54 | position: relative;
55 | width:600px;
56 | max-width:85em;
57 | }
58 |
59 | #copyright {
60 | margin-top: 0px;
61 | margin-bottom: 0px;
62 | padding: 2px;
63 | text-align: center;
64 | font-size: x-small;
65 | font-style: italic;
66 | }
67 |
68 | .page-header-area {
69 | position:absolute;
70 | margin-bottom: 1px;
71 | padding-top: 2px;
72 | padding-bottom: 2px;
73 | padding-left: 2px;
74 | border: 0px solid black;
75 | height:24px;
76 | }
77 |
78 | .divScroll {
79 | padding-top: 1px;
80 | padding-bottom: 1px;
81 | border-top-width: 1px;
82 | border-left-width: 1px;
83 | border-bottom-width: 1px;
84 | border-top-style: solid;
85 | border-bottom-style: solid;
86 | border-left-style: solid;
87 | border-top-color: #22527A;
88 | border-left-color: #22527A;
89 | overflow: auto;
90 | width: 100%;
91 | margin-top: 1px;
92 | margin-bottom: 1px;
93 | height: 240px;
94 | text-align: left;
95 | }
96 | .axis path, .axis line {fill: none;stroke: #000; shape-rendering: crispEdges;}
97 | .line {fill: none;stroke: blue;stroke-width: 1px;}
98 | div.tooltip {
99 | position: absolute;
100 | text-align: center;
101 | width: 120px;
102 | font: 12px "Helvetica Neue", Helvetica, sans-serif;
103 | font-weight: bold;
104 | background-color:lightsteelblue;
105 | border: solid 1px #aa8;
106 | padding: 0.2em 0.5em 0.3em;
107 | pointer-events: none;
108 | }
109 |
110 | .legend {padding: 5px;font: 10px sans-serif;background: yellow;box-shadow: 2px 2px 1px #888;}
111 | .grid .tick{stroke:lightgrey;opacity:0.4;}
112 | .grid path {stroke-width:0;opacity:0.4;}
113 | .area {fill: steelblue;opacity:0.4;}
114 | .rightbtn{float:right;text-decoration:underline;}
115 | .clip_button {text-align: center; text-decoration:underline; background-color: #ccc; marging-left:20px; padding-left:10px;padding-right:10px;}
116 | .clip_button.zeroclipboard-is-hover { background-color: #eee; }
117 | .clip_button.zeroclipboard-is-active { background-color: #aaa; }
118 | .nav{margin:0px;padding:0px;list-style:none;}
119 | .nav li{float:left;position:relative;border-right:1px solid #4BACC6;}
120 | .nav li:last-child{border-right:none}
121 | .nav li:first-child{width:200px;}
122 | .nav li a{display:block;padding:7px 8px;text-decoration:none;}
123 | .nav li a:hover{background-color:#036;color:#fff;}
124 | .nav ul{display:none;position:absolute;margin:0px;list-style:none;padding:0px;z-index:10000;background-color:#eee;border:1px solid #4BACC6;}
125 | .nav ul li{float:left;width:200px;position:relative;border-right:none;border-top:1px solid #4BACC6;}
126 | .nav ul li a:hover{background-color:#036;color:#fff;}
127 |
--------------------------------------------------------------------------------
/myperf/src/main/webapp/decorators/main.jsp:
--------------------------------------------------------------------------------
1 | <%@page trimDirectiveWhitespaces="true"%>
2 | <%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator" prefix="decorator"%>
3 | <%--
4 | Copyright 2015, Yahoo Inc.
5 | Copyrights licensed under the Apache License.
6 | See the accompanying LICENSE file for terms.
7 | --%>
8 |
9 |
10 |
11 | MySQL Database Performance Tool:
12 | <%@ include file="/includes/style.jsp"%>
13 |
14 |
15 |
15 |
16 |
17 |
18 |
20 |
21 |
--------------------------------------------------------------------------------
/myperf/src/main/webapp/decorators/printable.jsp:
--------------------------------------------------------------------------------
1 | <%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator"
2 | prefix="decorator"%>
3 | <%--
4 | Copyright 2015, Yahoo Inc.
5 | Copyrights licensed under the Apache License.
6 | See the accompanying LICENSE file for terms.
7 | --%>
8 |
9 |
10 |