├── 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 | 40 | 41 | 42 |
43 | 44 |
45 | 49 | 50 |
51 |
52 |
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 |
11 | 12 |
13 |
14 |
15 |
16 |
17 |
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 |
  1. PROCESS privilege to access INFORMATION_SCHEMA and INNODB information.
  2. 17 |
  3. To check replication status, the account needs REPLCATION_CLIENT privileges.
  4. 18 |
  5. To access PERFORMANCE_SCHEMA, at least SELECT on PERFORMANCE_SCHEMA is required.
  6. 19 |
  7. To access meta data such as database and table information, "SHOW DATABASES" privilege is required. 20 |
  8. To access table and view information of a given database, "SELECT" privilege on the given database is required.
  9. 21 |
  10. To access view definition, "SHOW VIEW" privilege on the given database is required.
  11. 22 |
23 |

24 |

Fields: 25 |

    26 |
  1. Database Group Name: the unique identifier for the target database. You can use DB Info page, Search DB tab to look up this information.
  2. 27 |
  3. DB User Name: the database account, for example, dbsmnp.
  4. 28 |
  5. DB Passowrd: the password of the database account.
  6. 29 |
  7. Retype Passowrd: the password of the database account.
  8. 30 |
  9. Test Passowrd: if checked, upon submit, the analyzer will connect to the target database to verify the password.
  10. 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 |
    1. 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.
    2. 18 |
    3. 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.
    4. 19 |
    5. Global Variables: this can be a convenient place to check server configurations.
    6. 20 |
    7. Variable Diffs: this can be used to compare configurations of two MySQL servers.
    8. 21 |
    9. 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.
    10. 22 |
    11. Innodb Engine Status: decoded data from "show engine innodb status".
    12. 23 |
    13. Innodb Statistics: data from INFORMATION_SCHEMA related to innodb, for example, transactions, mutext, locks and buffer pool statistics.
    14. 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 |
    1. Self registration: Self registration will create a standard user. A power user can change the new user's privilege.
    2. 19 |
    3. An new user account can be added by a power user.
    4. 20 |
    21 |

    22 |

    23 | If this is the first time MySQL performance analyzer is used, the following steps are required: 24 |

      25 |
    1. Configure Metric scanner.
    2. 26 |
    3. Onboard MySQL servers.
    4. 27 |
    28 |

    29 |

    30 | If this is the first use for any user, please note the followings. 31 |

      32 |
    1. Metrics charts can always be accessed if available.
    2. 33 |
    3. If the concerned MySQL server is not listed, onboard MySQL servers and notify the admin user to add it for metrics collections.
    4. 34 |
    5. For any concerned MySQL server, use credential page to add MySQL user account with right privileges so that the user can access other tools.
    6. 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 SQL 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 |
    25 |
    26 | Reset Password: 27 | 28 | 29 | 30 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 |
    31 |
    Note: If the server has problem to send out email, please contact administrator to change your password.
    44 |
    45 |
    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 |
    19 |
    20 | 21 | 22 | 45 | 57 | 58 |
    23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 36 | 37 | 38 | 43 |
    User Name: 
     
    Password:  32 | 33 | 34 | 35 |
     
    39 | 40 |   Forget Password? 41 | 42 |
    44 |
    46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 |
    No Account Yet?
    Sign Up Here
    Status Dash Board
    (Please login to complete setup first, check the simple doc for detail.)
    56 |
    59 | 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 |
    20 | DB Group 21 | 32 | 33 | DB Host 34 | 47 | 48 | 49 |
    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 |   61 | 62 |
    63 |
    64 | 68 |
    69 |
    70 |
    71 |
    72 |
    73 |
    74 |
    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: <decorator:title /> 12 | <%@ include file="/includes/style.jsp"%> 13 | 14 | 15 | > 16 | <%@ include file="/includes/header.jsp"%> 17 |
    18 | <%@ include file="/includes/footer.jsp"%> 19 |
    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 | 11 | <decorator:title default="print - DBA Perf" /> 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /myperf/src/main/webapp/fonts/adsdata-icons.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/mysql_perf_analyzer/94a9292bd4cf07062ec6211e8da9077079db0f79/myperf/src/main/webapp/fonts/adsdata-icons.eot -------------------------------------------------------------------------------- /myperf/src/main/webapp/fonts/adsdata-icons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/mysql_perf_analyzer/94a9292bd4cf07062ec6211e8da9077079db0f79/myperf/src/main/webapp/fonts/adsdata-icons.ttf -------------------------------------------------------------------------------- /myperf/src/main/webapp/fonts/adsdata-icons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/mysql_perf_analyzer/94a9292bd4cf07062ec6211e8da9077079db0f79/myperf/src/main/webapp/fonts/adsdata-icons.woff -------------------------------------------------------------------------------- /myperf/src/main/webapp/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/mysql_perf_analyzer/94a9292bd4cf07062ec6211e8da9077079db0f79/myperf/src/main/webapp/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /myperf/src/main/webapp/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/mysql_perf_analyzer/94a9292bd4cf07062ec6211e8da9077079db0f79/myperf/src/main/webapp/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /myperf/src/main/webapp/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/mysql_perf_analyzer/94a9292bd4cf07062ec6211e8da9077079db0f79/myperf/src/main/webapp/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /myperf/src/main/webapp/fonts/helveticaneue-light.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/mysql_perf_analyzer/94a9292bd4cf07062ec6211e8da9077079db0f79/myperf/src/main/webapp/fonts/helveticaneue-light.eot -------------------------------------------------------------------------------- /myperf/src/main/webapp/fonts/helveticaneue-light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/mysql_perf_analyzer/94a9292bd4cf07062ec6211e8da9077079db0f79/myperf/src/main/webapp/fonts/helveticaneue-light.ttf -------------------------------------------------------------------------------- /myperf/src/main/webapp/fonts/helveticaneue-light.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/mysql_perf_analyzer/94a9292bd4cf07062ec6211e8da9077079db0f79/myperf/src/main/webapp/fonts/helveticaneue-light.woff -------------------------------------------------------------------------------- /myperf/src/main/webapp/fonts/helveticaneue-thin.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/mysql_perf_analyzer/94a9292bd4cf07062ec6211e8da9077079db0f79/myperf/src/main/webapp/fonts/helveticaneue-thin.eot -------------------------------------------------------------------------------- /myperf/src/main/webapp/fonts/helveticaneue-thin.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/mysql_perf_analyzer/94a9292bd4cf07062ec6211e8da9077079db0f79/myperf/src/main/webapp/fonts/helveticaneue-thin.ttf -------------------------------------------------------------------------------- /myperf/src/main/webapp/fonts/helveticaneue-thin.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/mysql_perf_analyzer/94a9292bd4cf07062ec6211e8da9077079db0f79/myperf/src/main/webapp/fonts/helveticaneue-thin.woff -------------------------------------------------------------------------------- /myperf/src/main/webapp/fonts/helveticaneue.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/mysql_perf_analyzer/94a9292bd4cf07062ec6211e8da9077079db0f79/myperf/src/main/webapp/fonts/helveticaneue.eot -------------------------------------------------------------------------------- /myperf/src/main/webapp/fonts/helveticaneue.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/mysql_perf_analyzer/94a9292bd4cf07062ec6211e8da9077079db0f79/myperf/src/main/webapp/fonts/helveticaneue.ttf -------------------------------------------------------------------------------- /myperf/src/main/webapp/fonts/helveticaneue.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/mysql_perf_analyzer/94a9292bd4cf07062ec6211e8da9077079db0f79/myperf/src/main/webapp/fonts/helveticaneue.woff -------------------------------------------------------------------------------- /myperf/src/main/webapp/images/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/mysql_perf_analyzer/94a9292bd4cf07062ec6211e8da9077079db0f79/myperf/src/main/webapp/images/loading.gif -------------------------------------------------------------------------------- /myperf/src/main/webapp/img/next_arrow.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/mysql_perf_analyzer/94a9292bd4cf07062ec6211e8da9077079db0f79/myperf/src/main/webapp/img/next_arrow.gif -------------------------------------------------------------------------------- /myperf/src/main/webapp/img/save.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/mysql_perf_analyzer/94a9292bd4cf07062ec6211e8da9077079db0f79/myperf/src/main/webapp/img/save.gif -------------------------------------------------------------------------------- /myperf/src/main/webapp/img/ui_active_tab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/mysql_perf_analyzer/94a9292bd4cf07062ec6211e8da9077079db0f79/myperf/src/main/webapp/img/ui_active_tab.png -------------------------------------------------------------------------------- /myperf/src/main/webapp/includes/footer.jsp: -------------------------------------------------------------------------------- 1 | <%-- 2 | Copyright 2015, Yahoo Inc. 3 | Copyrights licensed under the Apache License. 4 | See the accompanying LICENSE file for terms. 5 | --%> 6 | -------------------------------------------------------------------------------- /myperf/src/main/webapp/includes/style.jsp: -------------------------------------------------------------------------------- 1 | <%-- 2 | Copyright 2015, Yahoo Inc. 3 | Copyrights licensed under the Apache License. 4 | See the accompanying LICENSE file for terms. 5 | --%> 6 | -------------------------------------------------------------------------------- /myperf/src/main/webapp/index.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 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /myperf/src/main/webapp/jquery/css/themes/tooltipster-light.css: -------------------------------------------------------------------------------- 1 | .tooltipster-light { 2 | border-radius: 5px; 3 | border: 1px solid #cccccc; 4 | background: #ededed; 5 | color: #666666; 6 | } 7 | .tooltipster-light .tooltipster-content { 8 | font-family: Arial, sans-serif; 9 | font-size: 14px; 10 | line-height: 16px; 11 | padding: 8px 10px; 12 | } -------------------------------------------------------------------------------- /myperf/src/main/webapp/jquery/css/themes/tooltipster-noir.css: -------------------------------------------------------------------------------- 1 | .tooltipster-noir { 2 | border-radius: 0px; 3 | border: 3px solid #2c2c2c; 4 | background: #fff; 5 | color: #2c2c2c; 6 | } 7 | .tooltipster-noir .tooltipster-content { 8 | font-family: 'Georgia', serif; 9 | font-size: 14px; 10 | line-height: 16px; 11 | padding: 8px 10px; 12 | } -------------------------------------------------------------------------------- /myperf/src/main/webapp/jquery/css/themes/tooltipster-punk.css: -------------------------------------------------------------------------------- 1 | .tooltipster-punk { 2 | border-radius: 5px; 3 | border-bottom: 3px solid #f71169; 4 | background: #2a2a2a; 5 | color: #fff; 6 | } 7 | .tooltipster-punk .tooltipster-content { 8 | font-family: 'Courier', monospace; 9 | font-size: 14px; 10 | line-height: 16px; 11 | padding: 8px 10px; 12 | } -------------------------------------------------------------------------------- /myperf/src/main/webapp/jquery/css/themes/tooltipster-shadow.css: -------------------------------------------------------------------------------- 1 | .tooltipster-shadow { 2 | border-radius: 5px; 3 | background: #fff; 4 | box-shadow: 0px 0px 14px rgba(0,0,0,0.3); 5 | color: #2c2c2c; 6 | } 7 | .tooltipster-shadow .tooltipster-content { 8 | font-family: 'Arial', sans-serif; 9 | font-size: 14px; 10 | line-height: 16px; 11 | padding: 8px 10px; 12 | } -------------------------------------------------------------------------------- /myperf/src/main/webapp/jquery/css/zTreeStyle/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/mysql_perf_analyzer/94a9292bd4cf07062ec6211e8da9077079db0f79/myperf/src/main/webapp/jquery/css/zTreeStyle/.DS_Store -------------------------------------------------------------------------------- /myperf/src/main/webapp/jquery/css/zTreeStyle/img/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/mysql_perf_analyzer/94a9292bd4cf07062ec6211e8da9077079db0f79/myperf/src/main/webapp/jquery/css/zTreeStyle/img/.DS_Store -------------------------------------------------------------------------------- /myperf/src/main/webapp/jquery/css/zTreeStyle/img/diy/1_close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/mysql_perf_analyzer/94a9292bd4cf07062ec6211e8da9077079db0f79/myperf/src/main/webapp/jquery/css/zTreeStyle/img/diy/1_close.png -------------------------------------------------------------------------------- /myperf/src/main/webapp/jquery/css/zTreeStyle/img/diy/1_open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/mysql_perf_analyzer/94a9292bd4cf07062ec6211e8da9077079db0f79/myperf/src/main/webapp/jquery/css/zTreeStyle/img/diy/1_open.png -------------------------------------------------------------------------------- /myperf/src/main/webapp/jquery/css/zTreeStyle/img/diy/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/mysql_perf_analyzer/94a9292bd4cf07062ec6211e8da9077079db0f79/myperf/src/main/webapp/jquery/css/zTreeStyle/img/diy/2.png -------------------------------------------------------------------------------- /myperf/src/main/webapp/jquery/css/zTreeStyle/img/diy/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/mysql_perf_analyzer/94a9292bd4cf07062ec6211e8da9077079db0f79/myperf/src/main/webapp/jquery/css/zTreeStyle/img/diy/3.png -------------------------------------------------------------------------------- /myperf/src/main/webapp/jquery/css/zTreeStyle/img/diy/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/mysql_perf_analyzer/94a9292bd4cf07062ec6211e8da9077079db0f79/myperf/src/main/webapp/jquery/css/zTreeStyle/img/diy/4.png -------------------------------------------------------------------------------- /myperf/src/main/webapp/jquery/css/zTreeStyle/img/diy/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/mysql_perf_analyzer/94a9292bd4cf07062ec6211e8da9077079db0f79/myperf/src/main/webapp/jquery/css/zTreeStyle/img/diy/5.png -------------------------------------------------------------------------------- /myperf/src/main/webapp/jquery/css/zTreeStyle/img/diy/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/mysql_perf_analyzer/94a9292bd4cf07062ec6211e8da9077079db0f79/myperf/src/main/webapp/jquery/css/zTreeStyle/img/diy/6.png -------------------------------------------------------------------------------- /myperf/src/main/webapp/jquery/css/zTreeStyle/img/diy/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/mysql_perf_analyzer/94a9292bd4cf07062ec6211e8da9077079db0f79/myperf/src/main/webapp/jquery/css/zTreeStyle/img/diy/7.png -------------------------------------------------------------------------------- /myperf/src/main/webapp/jquery/css/zTreeStyle/img/diy/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/mysql_perf_analyzer/94a9292bd4cf07062ec6211e8da9077079db0f79/myperf/src/main/webapp/jquery/css/zTreeStyle/img/diy/8.png -------------------------------------------------------------------------------- /myperf/src/main/webapp/jquery/css/zTreeStyle/img/diy/9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/mysql_perf_analyzer/94a9292bd4cf07062ec6211e8da9077079db0f79/myperf/src/main/webapp/jquery/css/zTreeStyle/img/diy/9.png -------------------------------------------------------------------------------- /myperf/src/main/webapp/jquery/css/zTreeStyle/img/line_conn.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/mysql_perf_analyzer/94a9292bd4cf07062ec6211e8da9077079db0f79/myperf/src/main/webapp/jquery/css/zTreeStyle/img/line_conn.gif -------------------------------------------------------------------------------- /myperf/src/main/webapp/jquery/css/zTreeStyle/img/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/mysql_perf_analyzer/94a9292bd4cf07062ec6211e8da9077079db0f79/myperf/src/main/webapp/jquery/css/zTreeStyle/img/loading.gif -------------------------------------------------------------------------------- /myperf/src/main/webapp/jquery/css/zTreeStyle/img/zTreeStandard.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/mysql_perf_analyzer/94a9292bd4cf07062ec6211e8da9077079db0f79/myperf/src/main/webapp/jquery/css/zTreeStyle/img/zTreeStandard.gif -------------------------------------------------------------------------------- /myperf/src/main/webapp/jquery/css/zTreeStyle/img/zTreeStandard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/mysql_perf_analyzer/94a9292bd4cf07062ec6211e8da9077079db0f79/myperf/src/main/webapp/jquery/css/zTreeStyle/img/zTreeStandard.png -------------------------------------------------------------------------------- /myperf/src/main/webapp/jquery/datatables/images/Sorting icons.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/mysql_perf_analyzer/94a9292bd4cf07062ec6211e8da9077079db0f79/myperf/src/main/webapp/jquery/datatables/images/Sorting icons.psd -------------------------------------------------------------------------------- /myperf/src/main/webapp/jquery/datatables/images/back_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/mysql_perf_analyzer/94a9292bd4cf07062ec6211e8da9077079db0f79/myperf/src/main/webapp/jquery/datatables/images/back_disabled.png -------------------------------------------------------------------------------- /myperf/src/main/webapp/jquery/datatables/images/back_enabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/mysql_perf_analyzer/94a9292bd4cf07062ec6211e8da9077079db0f79/myperf/src/main/webapp/jquery/datatables/images/back_enabled.png -------------------------------------------------------------------------------- /myperf/src/main/webapp/jquery/datatables/images/back_enabled_hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/mysql_perf_analyzer/94a9292bd4cf07062ec6211e8da9077079db0f79/myperf/src/main/webapp/jquery/datatables/images/back_enabled_hover.png -------------------------------------------------------------------------------- /myperf/src/main/webapp/jquery/datatables/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/mysql_perf_analyzer/94a9292bd4cf07062ec6211e8da9077079db0f79/myperf/src/main/webapp/jquery/datatables/images/favicon.ico -------------------------------------------------------------------------------- /myperf/src/main/webapp/jquery/datatables/images/forward_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/mysql_perf_analyzer/94a9292bd4cf07062ec6211e8da9077079db0f79/myperf/src/main/webapp/jquery/datatables/images/forward_disabled.png -------------------------------------------------------------------------------- /myperf/src/main/webapp/jquery/datatables/images/forward_enabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/mysql_perf_analyzer/94a9292bd4cf07062ec6211e8da9077079db0f79/myperf/src/main/webapp/jquery/datatables/images/forward_enabled.png -------------------------------------------------------------------------------- /myperf/src/main/webapp/jquery/datatables/images/forward_enabled_hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/mysql_perf_analyzer/94a9292bd4cf07062ec6211e8da9077079db0f79/myperf/src/main/webapp/jquery/datatables/images/forward_enabled_hover.png -------------------------------------------------------------------------------- /myperf/src/main/webapp/jquery/datatables/images/sort_asc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/mysql_perf_analyzer/94a9292bd4cf07062ec6211e8da9077079db0f79/myperf/src/main/webapp/jquery/datatables/images/sort_asc.png -------------------------------------------------------------------------------- /myperf/src/main/webapp/jquery/datatables/images/sort_asc_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/mysql_perf_analyzer/94a9292bd4cf07062ec6211e8da9077079db0f79/myperf/src/main/webapp/jquery/datatables/images/sort_asc_disabled.png -------------------------------------------------------------------------------- /myperf/src/main/webapp/jquery/datatables/images/sort_both.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/mysql_perf_analyzer/94a9292bd4cf07062ec6211e8da9077079db0f79/myperf/src/main/webapp/jquery/datatables/images/sort_both.png -------------------------------------------------------------------------------- /myperf/src/main/webapp/jquery/datatables/images/sort_desc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/mysql_perf_analyzer/94a9292bd4cf07062ec6211e8da9077079db0f79/myperf/src/main/webapp/jquery/datatables/images/sort_desc.png -------------------------------------------------------------------------------- /myperf/src/main/webapp/jquery/datatables/images/sort_desc_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/mysql_perf_analyzer/94a9292bd4cf07062ec6211e8da9077079db0f79/myperf/src/main/webapp/jquery/datatables/images/sort_desc_disabled.png -------------------------------------------------------------------------------- /myperf/src/main/webapp/jquery/js/ZeroClipboard.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yahoo/mysql_perf_analyzer/94a9292bd4cf07062ec6211e8da9077079db0f79/myperf/src/main/webapp/jquery/js/ZeroClipboard.swf -------------------------------------------------------------------------------- /myperf/src/main/webapp/js/common.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015, Yahoo Inc. 3 | * Copyrights licensed under the Apache License. 4 | * See the accompanying LICENSE file for terms. 5 | */ 6 | //so we don't send clear password for login 7 | function auth() 8 | { 9 | var s1; 10 | try 11 | { 12 | s1 = document.getElementById("ts").value +":" 13 | +md5(document.getElementById("name").value+":"+document.getElementById("pd").value)+":" 14 | +document.getElementById("ars").value; 15 | }catch(e){console.log(e); return false;} 16 | document.getElementById("s").value = md5(s1); 17 | document.getElementById("pd").value = ""; 18 | return true; 19 | } 20 | 21 | //style: none, block, inline-block, etc 22 | function showHideOne(nodeId, showStyle) 23 | { 24 | document.getElementById(nodeId).style.display=showStyle; 25 | } 26 | 27 | function mydom(id) 28 | { 29 | return document.getElementById(id); 30 | } 31 | function mydomval(id) 32 | { 33 | return document.getElementById(id).value; 34 | } 35 | 36 | function showHide(allDivs, showDiv, displayStyle) 37 | { 38 | if(allDivs && allDivs.length>0) 39 | { 40 | for(var i=0;i 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 | com.yahoo.dba.tools 16 | myperfserver 17 | jar 18 | 19 | myperfserver 20 | http://maven.apache.org 21 | 22 | 23 | UTF-8 24 | 9.2.7.v20150116 25 | 26 | 27 | 28 | 29 | javax.servlet 30 | javax.servlet-api 31 | 3.1.0 32 | 33 | 34 | org.eclipse.jetty 35 | jetty-annotations 36 | ${jetty-version} 37 | 38 | 39 | org.eclipse.jetty 40 | jetty-webapp 41 | ${jetty-version} 42 | 43 | 44 | org.eclipse.jetty 45 | apache-jsp 46 | ${jetty-version} 47 | jar 48 | 49 | 50 | org.eclipse.jetty 51 | apache-jstl 52 | ${jetty-version} 53 | pom 54 | 55 | 56 | commons-cli 57 | commons-cli 58 | 1.2 59 | 60 | 61 | junit 62 | junit 63 | 3.8.1 64 | test 65 | 66 | 67 | 68 | 69 | central-maven 70 | Central Maven 71 | https://central.maven.org/maven2 72 | 73 | 74 | thirdparty-releases 75 | JBoss Thirdparty Releases 76 | https://repository.jboss.org/nexus/content/repositories/thirdparty-releases 77 | 78 | 79 | maven2-repository.dev.java.net 80 | Java.net Maven 2 Repository 81 | https://download.java.net/maven/2/ 82 | 83 | 84 | jboss-repository.maven2 85 | JBoss Maven 2 Repository 86 | https://repository.jboss.com/maven2/ 87 | 88 | 89 | 90 | myperfserver 91 | 92 | 93 | maven-compiler-plugin 94 | 95 | 1.6 96 | 1.6 97 | true 98 | true 99 | true 100 | ${maven.compiler.executable} 101 | 1.6 102 | 103 | 104 | 105 | maven-source-plugin 106 | 107 | 108 | source-jar 109 | deploy 110 | 111 | jar 112 | 113 | 114 | 115 | 116 | true 117 | 118 | 119 | 120 | maven-assembly-plugin 121 | org.apache.maven.plugins 122 | 2.2-beta-1 123 | 124 | 125 | 126 | src/main/assemble/executable-jar-with-dependencies.xml 127 | 128 | 129 | src/main/assemble/deployable-package.xml 130 | 131 | 132 | 133 | 134 | 135 | 136 | make-assembly 137 | package 138 | 139 | directory-inline 140 | attached 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | -------------------------------------------------------------------------------- /perfJettyServer/src/main/assemble/deployable-package.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | server 8 | 9 | zip 10 | 11 | false 12 | 13 | 14 | 15 | target 16 | 17 | 18 | myperfserver-executable-jar-with-dependencies.jar 19 | 20 | 21 | 22 | 23 | 24 | 25 | src/main/assemble/scripts/start_myperf.sh 26 | 27 | lf 28 | true 29 | 0755 30 | 31 | 32 | src/main/assemble/scripts/stop_myperf.sh 33 | 34 | lf 35 | true 36 | 0755 37 | 38 | 39 | src/main/assemble/scripts/jetty_ssl_sample.sh 40 | 41 | lf 42 | true 43 | 0700 44 | 45 | 46 | src/main/assemble/scripts/config_sample.properties 47 | 48 | lf 49 | true 50 | 0700 51 | 52 | 53 | src/main/assemble/scripts/config_default.properties 54 | 55 | lf 56 | true 57 | 0700 58 | 59 | 60 | ../myperf/target/myperf.war 61 | webapps 62 | true 63 | 64 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /perfJettyServer/src/main/assemble/executable-jar-with-dependencies.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | executable-jar-with-dependencies 8 | 9 | jar 10 | 11 | false 12 | 13 | 14 | 15 | 16 | true 17 | runtime 18 | 19 | 20 | 21 | 22 | target/classes 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /perfJettyServer/src/main/assemble/scripts/config_default.properties: -------------------------------------------------------------------------------- 1 | jettyHome=. 2 | port=9092 3 | webcontextroot=/myperf 4 | workdir=./work 5 | logpath=./logs 6 | warfile=myperf.war 7 | -------------------------------------------------------------------------------- /perfJettyServer/src/main/assemble/scripts/config_sample.properties: -------------------------------------------------------------------------------- 1 | jettyHome=. 2 | useHttps=yes 3 | port=9092 4 | webcontextroot=/myperf 5 | workdir=./work 6 | logpath=./logs 7 | warfile=myperf.war 8 | certKeyStorePath=./jetty_ssl/keystore 9 | certKeyStorePassword=mypassword -------------------------------------------------------------------------------- /perfJettyServer/src/main/assemble/scripts/jetty_ssl_sample.sh: -------------------------------------------------------------------------------- 1 | mkdir jetty_ssl 2 | cd jetty_ssl/ 3 | openssl genrsa -aes128 -out jetty.key 4 | openssl req -new -x509 -newkey rsa:2048 -sha256 -key jetty.key -out jetty.crt 5 | openssl req -new -key jetty.key -out jetty.csr 6 | keytool -keystore keystore -import -alias jetty -file jetty.crt -trustcacerts 7 | openssl pkcs12 -inkey jetty.key -in jetty.crt -export -out jetty.pkcs12 8 | keytool -importkeystore -srckeystore jetty.pkcs12 -srcstoretype PKCS12 -destkeystore keystore -------------------------------------------------------------------------------- /perfJettyServer/src/main/assemble/scripts/start_myperf.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | bin=`dirname "$0"` 4 | cd $bin 5 | 6 | defport=9092 7 | PORT=${1:-$defport} 8 | 9 | rm logs/myperf.log.*.lck 10 | #nohup java -Xms128m -classpath myperfserver-executable-jar-with-dependencies.jar com.yahoo.dba.tools.myperfserver.App -j $bin -p $PORT -w myperf.war -k work -c /myperf & 11 | nohup java -Xms128m -classpath myperfserver-executable-jar-with-dependencies.jar com.yahoo.dba.tools.myperfserver.App -f config_default.properties & -------------------------------------------------------------------------------- /perfJettyServer/src/main/assemble/scripts/stop_myperf.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ######################################### 3 | # Script to stop perf analyzer 4 | ######################################### 5 | bin=`dirname "$0"` 6 | cd $bin 7 | 8 | APPNAME="MySQL Perf Analyzer" 9 | echo "check and stop $APPNAME" 10 | curdir=`pwd` 11 | PID_FILE=$curdir/myperf.pid 12 | 13 | #softshutdown first 14 | touch "myserver.shutdown" 15 | 16 | if [ -e $PID_FILE ]; then 17 | FILE_PID=`cat $PID_FILE` 18 | OS_PID=`ps -p $FILE_PID -o pid=` 19 | 20 | if [ "x$OS_PID" = "x" ]; then 21 | OS_PID=-1 22 | fi 23 | 24 | if [ $OS_PID != $FILE_PID ]; then 25 | echo "$APPNAME is not running, removing orphaned $PID_FILE file" 26 | rm $PID_FILE 27 | else 28 | 29 | echo "$APPNAME is running, stop it" 30 | kill -9 $FILE_PID 31 | # Wait for the app process to exit before returning. 32 | 33 | OS_PID=$FILE_PID 34 | 35 | until [ $OS_PID != $FILE_PID ]; do 36 | sleep 1 37 | OS_PID=`ps -p $FILE_PID -o pid=` 38 | 39 | if [ "x$OS_PID" = "x" ]; then 40 | OS_PID=-1 41 | fi 42 | done 43 | 44 | rm $PID_FILE 45 | 46 | fi 47 | else 48 | echo "$APPNAME is not running" 49 | fi 50 | -------------------------------------------------------------------------------- /perfJettyServer/src/test/java/com/yahoo/dba/tools/myperfserver/AppTest.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.tools.myperfserver; 7 | 8 | import junit.framework.Test; 9 | import junit.framework.TestCase; 10 | import junit.framework.TestSuite; 11 | 12 | /** 13 | * Unit test for simple App. 14 | */ 15 | public class AppTest 16 | extends TestCase 17 | { 18 | /** 19 | * Create the test case 20 | * 21 | * @param testName name of the test case 22 | */ 23 | public AppTest( String testName ) 24 | { 25 | super( testName ); 26 | } 27 | 28 | /** 29 | * @return the suite of tests being tested 30 | */ 31 | public static Test suite() 32 | { 33 | return new TestSuite( AppTest.class ); 34 | } 35 | 36 | /** 37 | * Rigourous Test :-) 38 | */ 39 | public void testApp() 40 | { 41 | assertTrue( true ); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | com.yahoo.dba.perf 7 | myperf-project 8 | 2.0.0-SNAPSHOT 9 | project/pom.xml 10 | 11 | myperfapp 12 | MySQL Perf Analyzer 13 | pom 14 | 15 | project 16 | myperf 17 | perfJettyServer 18 | 19 | 20 | 21 | 22 | distribution 23 | 24 | 25 | 26 | 27 | maven-assembly-plugin 28 | 2.3 29 | false 30 | 31 | 32 | create-distribution 33 | package 34 | 35 | single 36 | 37 | 38 | myperf-${project.version} 39 | 40 | package-descriptor.xml 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | doc 51 | 52 | 53 | 54 | maven-javadoc-plugin 55 | 56 | 57 | javadoc 58 | package 59 | 60 | aggregate-jar 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /project/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | com.yahoo.dba.perf 6 | myperf-project 7 | 2.0.0-SNAPSHOT 8 | pom 9 | MySQL Performance Analyzer 10 | http://jclouds.apache.org/ 11 | MySQL Performance Analyzer 12 | 2013 13 | --------------------------------------------------------------------------------