馃槃1.鍓嶈█鏄墖闈㈢殑锛佷竴鏈堜笁鑸燂紝鎵樺皵鏂嘲璇达細鈥滃涔堜紵澶х殑浣滃锛屼絾浠栧彧鏄湪鍐欎粬鑷繁鐨勪竴闈€傗€濇洿浣曞喌鏄垜锛屾洿浣曞喌鏄垜浠紒鎴戜滑铏界劧涓嶅啓鏂囩珷锛屼絾鏄啓闇€姹傦紝鍐欎唬鐮侊紝鍐欒瘎璁恒€傚綋鎴戜滑閬囧埌闇€瑕佽璁虹殑闂鏃讹紝瀹冧滑寰€寰€浼氭垚涓轰簤璁虹殑鐒︾偣銆傝繖涓ソ閭d釜鍧忥紝闅忎究浣犵敤锛佸綋浣犳妸璺彉绐勭殑鏃跺€欙紝浣犺兘寰楀埌鐨勬柊鎬濇兂銆佹柊鎯虫硶銆佹柊瑙嗛噹锛屼互鍙婇潪甯搁噸瑕佺殑鏀跺叆涔熶細鍑忓皯銆傚彧鏈夋í鍚戞瘮杈冦€佸€熼壌銆佹煡婕忚ˉ缂猴紝鎵嶈兘璁╀綘鐨勫ご鑴戞湁鏇村鐨勬兂娉曪紝鏃犺鏄啓浠g爜銆佺悊璐紝杩樻槸鐢熸椿銆?.闇€姹傜殑鐩殑浣犳槸涓嶆槸鍦ㄥ紑鍙戣繃绋嬩腑浣跨敤IntelliJIDEA锛岄渶瑕佽幏鍙栬鎵ц鐨凷QL璇彞锛屽鍒跺嚭鏉ラ獙璇佺殑鏃跺€欙紝鎬绘槸杩欐牱鐨勮鍙ワ細SELECT*FROMUSERWHERE韬唤璇?锛熷拰鍚嶅瓧=锛熸崲涓€庝箞鏍凤紵杈撳叆鍙傛暟鐨勭紪鍙凤紵褰撶劧杩欎釜闇€姹傚叾瀹炲苟涓嶅ぇ锛岀敋鑷冲彲浠ョ敤鍏朵粬鐨勬柟娉曟潵瑙e喅銆傜劧鍚庢湰绔犲皢涓烘偍鎻愪緵涓€涓柊鐨勬兂娉曪紝鍙兘浼氫互鎮ㄥ嚑涔庝粠鏈綋楠岃繃鐨勬柟寮忓鐞嗐€傛墍浠ュ湪鏈珷鐨勬渚嬩腑锛屾垜浠娇鐢ㄥ熀浜嶪DEAPlugin鐨勫紑鍙戣兘鍔涳紝灏嗗熀浜嶫avaagent鑳藉姏鐨勫瓧鑺傜爜鎻掓々鎺㈤拡娉ㄥ叆鍒颁唬鐮佷腑銆傜劧鍚庨€氳繃澧炲己鐨勫瓧鑺傜爜锛屽緱鍒癱om.mysql.jdbc.PreparedStatement->executeInternal鎵ц瀵硅薄锛屼粠鑰屽緱鍒板彲浠ョ洿鎺ユ祴璇曠殑SQL璇彞銆備笁銆佹渚嬪紑鍙?.椤圭洰缁撴瀯guide-idea-plugin-probe鈹溾攢鈹€.gradle鈹溾攢鈹€probe-agent鈹傗敎鈹€鈹€src鈹傗攤鈹斺攢鈹€main鈹傗攤鈹斺攢鈹€java鈹傗攤鈹斺攢鈹€cn.bugstack.guide.idea.plugin鈹傗攤鈹溾攢鈹€MonitorMethod.java鈹傗攤鈹斺攢鈹€PreAgent.java鈹傗敂鈹€鈹€build.gradle鈹斺攢鈹€probe-plugin鈹傗敂鈹€鈹€src鈹傗攤鈹斺攢鈹€main鈹傗攤鈹溾攢鈹€java鈹傗攤鈹傗敂鈹€鈹€cn.bugstack.guide.idea.plugin鈹傗攤鈹傗敂鈹€鈹€瀹炵敤绋嬪簭鈹傗攤鈹傗攤鈹斺攢鈹€PluginUtil.java鈹傗攤鈹傗敂鈹€鈹€PerRun.java鈹傗攤鈹斺攢鈹€璧勬簮鈹傗攤鈹斺攢鈹€META-INF鈹傗攤鈹斺攢鈹€plugin.xml鈹傗敂鈹€鈹€build.gradle鈹溾攢鈹€build.gradle鈹斺攢鈹€gradle.properties婧愮爜鑾峰彇锛?鍏紬鍙?bugstack铏礊鏍堝洖澶?idea鍙互涓嬭浇鎵€鏈塈DEA鎻掍欢寮€鍙戞簮鐮佸湪杩欎釜IDEA鎻掍欢椤圭洰涓紝椤圭洰缁撴瀯鍒嗕负2閮ㄥ垎锛歱robe-agent锛氭帰娴嬫ā鍧楋紝鐢ㄤ簬缂栬瘧鎵撳寘鎻愪緵瀛楄妭鐮佸寮烘湇鍔★紝浣跨敤probe-plugin瀵逛簬probe-plugin妯″潡锛氭彃浠舵ā鍧楅€氳繃java.programPatcher鍔犺浇瀛楄妭鐮佸寮哄寘锛岃幏鍙栧苟鎵撳嵃鎵ц鏁版嵁搴撴搷浣滅殑SQL璇彞銆?.瀛楄妭鐮佸寮哄湪SQL杩欓噷鑾峰彇瀛楄妭鐮佸寮虹殑鏂规硶锛屼娇鐢˙yte-Buddy瀛楄妭鐮佹鏋讹紝瀹冪殑浣跨敤鏂规硶鏇寸畝鍗曪紝鍦ㄤ娇鐢ㄧ殑杩囩▼涓紝鏈夌偣鍍忎娇鐢ˋOP鎷︽埅鐨勬柟娉曟潵鑾峰彇浣犻渶瑕佺殑淇℃伅銆傚彟澶栵紝鍦╣radle鎵撳寘鏋勫缓鐨勬椂鍊欙紝闇€瑕佹坊鍔爏hadowJar妯″潡鏉ユ墦鍖匬remain-Class銆傝繖閮ㄥ垎浠g爜鍙互鏌ョ湅2.1Probe鍏ュ彛cn.bugstack.guide.idea.plugin.PreAgent//JVM棣栧厛灏濊瘯鍦╝gent绫讳笂璋冪敤濡備笅鏂规硶publicstaticvoidpremain(StringagentArgs,Instrumentationinst){AgentBuilder.Transformertransformer=(builder,typeDescription,classLoader,javaModule)->{returnbuilder.method(ElementMatchers.named("executeInternal"))//鎷︽埅浠讳綍鏂规硶銆傛嫤鎴紙MethodDelegation.to锛圡onitorMethod.class锛夛級锛?/浠h〃};newAgentBuilder.Default().type(ElementMatchers.nameStartsWith("com.mysql.jdbc.PreparedStatement")).transform(transformer).installOn(inst);}閫氳繃Byte-buddy閰嶇疆锛屾嫤鎴尮閰嶇殑绫诲拰鏂规硶锛屽洜涓鸿繖涓湪绫诲拰鏂规硶涓嬶紝鍙互寰楀埌瀹屾暣鐨勬墽琛岃繃鐨凷QL璇彞銆?.2鎷︽埅SQLcn.bugstack.guide.idea.plugin.MonitorMethod@RuntimeTypepublicstaticObjectintercept(@ThisObjectobj,@OriginMethodmethod,@SuperCallCallable>callable,@AllArgumentsObject...args)throwsException{try{杩斿洖callable.call();}finally{StringoriginalSql=(String)BeanUtil.getFieldValue(obj,"originalSql");StringreplaceSql=ReflectUtil.invoke(obj,"asSql");System.out.println("鏁版嵁搴撳悕绉帮細Mysql");System.out.println("绾跨▼ID锛?+Thread.currentThread().getId());System.out.println("鏃堕棿锛?+newDate());System.out.println("鍘熷SQL:\r\n"+originalSql);System.out.println("鏇挎崲SQL:\r\n"+replaceSql);}}鎷︽埅鏂规硶鍏ュ彛鏄彲閰嶇疆鐨勬搷浣滐紝姣斿@ThisObjectobj鏄幏鍙栧綋鍓嶇被鐨勬墽琛屽璞★紝@OriginMethodmethod鏄幏鍙栨墽琛屾柟娉曘€傚湪finally鍧椾腑锛屾垜浠彲浠ラ€氳繃鍙嶅皠鑾峰彇褰撳墠绫荤殑灞炴€т俊鎭紝閫氳繃鍙嶅皠鑾峰彇鎵ц鐨凷QL锛屽苟鎵撳嵃鍑烘潵銆?.3缂栬瘧鎵撳寘鍦ㄦ祴璇曞紑鍙慖DEAPlugin鎻掍欢涔嬪墠锛屾垜浠渶瑕佽繘琛屼竴娆℃墦鍖呮搷浣溿€傝繖涓墦鍖呭氨鏄妸瀛楄妭鐮佸寮虹殑浠g爜鎵撳寘鎴愪竴涓狫ar鍖呫€傚湪build.gradle->shadowJar涓墦鍖呯紪璇戝悗锛屽湪build->libs涓嬪彲浠ョ湅鍒癑ar:probe-agent-1.0-SNAPSHOT-all.jar璇ar鐢ㄤ簬瀛楄妭鐮佸寮哄鐞嗐€?.4娴嬭瘯楠岃瘉灏嗙紪鍐欏ソ鐨勫瓧鑺傜爜澧炲己缁勪欢浣跨敤鍒版彃浠朵箣鍓嶏紝鍙互鍏堝仛涓€娆℃祴璇曢獙璇侊紝閬垮厤姣忔閮介渶瑕佸惎鍔ㄦ彃浠惰繘琛屾祴璇曘€傚崟鍏冩祴璇昿ublicclassApiTest{publicstaticvoidmain(String[]args)throwsException{StringURL="jdbc:mysql://127.0.0.1:3306/itstack?characterEncoding=utf-8";瀛楃涓睻SER="root";瀛楃涓插瘑鐮?"123456";Class.forName("com.mysql.jdbc.Driver");杩炴帴conn=DriverManager.getConnection(URL,USER,PASSWORD);Stringsql="SELECT*FROMUSERWHEREid=?ANDname=?";PreparedStatement璇彞=conn.prepareStatement(sql);statement.setLong(1,1L);statement.setString(2,"璋㈤鏈?);缁撴灉闆唕s=statement.executeQuery();while(rs.next()){System.out.println(rs.getString("name")+""+rs.getString("address"));}}}VMoptions:-javaagent:yourpath\libs\probe-agent-1.0-SNAPSHOT-all.jar娉ㄦ剰锛屽湪娴嬭瘯杩愯鏃讹紝闇€瑕佷负ApiTest閰嶇疆VM閫夐」锛屼互渚挎墦鍗版埅鑾风殑SQL淇℃伅娴嬭瘯缁撴灉鍘熷SQL锛歋ELECT*FROMUSERWHEREid=?鍜屽悕瀛?锛熸浛鎹QL锛歋ELECT*FROMUSERWHEREid=1ANDname='璋㈢户椋?璋㈢户椋炲寳浜€傚ぇ鍏村尯銆傞€氭槑婀栧叕鍥噯澶囧ソ浜嗭紝杩欐牱鎴戜滑灏卞彲浠ユ嫤鎴彲浠ュ鍒舵墽琛岀殑SQL璇彞銆備笅闈㈡垜浠潵鍋欼DEAPlugin鐨勫鐞嗐€?.閫氳繃鎻掍欢寮€鍙戝紩鍏ユ帰閽圝ar銆傛浠g爜澧炲己Jar鍖咃紝鎷疯礉鍒癐DEAPlugin鎻掍欢寮€鍙戞ā鍧椾腑鐨刲ibs锛堝彲浠ヨ嚜宸卞垱寤猴級锛岀劧鍚庡姞杞藉疄鐜癴ileTree(dir:'libs',includes:['*jar'])鍦╬lugin.xml閰嶇疆涓€傚彲浠ュ湪绋嬪簭涓壘鍒拌繖涓猨ar鍖咃紝鍦ㄧ▼搴忎腑杩涜閰嶇疆銆?.1澶嶅埗jar鍒發ibs3.2build.gradle閰嶇疆鍔犺浇渚濊禆{implementationfileTree(dir:'libs',includes:['*jar'])}浠嬬粛閫氳繃implementationfileTree鍔犺浇鏂囦欢鏍戠殑鏂瑰紡锛屽皢鎴戜滑閰嶇疆濂界殑Jar鍔犺浇鍒扮▼搴忎腑璺戞銆?.3绋嬪簭涓紩鍏avaagentcn.bugstack.guide.idea.plugin.PerRunpublicclassPerRunextendsJavaProgramPatcher{@OverridepublicvoidpatchJavaParameters(Executorexecutor,RunProfileconfiguration,JavaParametersjavaParameters){RunConfigurationrunConfiguration=(RunConfiguration)configuration;ParametersListvmParametersList=javaParameters.getVMParametersList();vmParametersList.addParametersString("-javaagent:"+agentCoreJarPath);vmParametersList.addNotEmptyProperty("guide-idea-plugin-probe.projectId",runConfiguration.getProject().getLocationHash());}}閫氳繃缁ф壙JavaProgramPatcher绫伙紝瀹炵幇patchJavaParameters鏂规硶锛岄€氳繃閰嶇疆灞炴€ч厤缃垜浠嚜宸遍渶瑕佸姞杞界殑-javaagent鍖呫€傝繖鏍凤紝褰撻€氳繃IDEA瀹夎濂芥彃浠讹紝杩愯浠g爜鍚庯紝灏变細鎵ц鎷︽埅鎵撳嵃SQL鐨勫姛鑳姐€?.4plugin.xml娣诲姞閰嶇疆
