001/* 002 * Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com). 003 * <p> 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * <p> 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * <p> 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package com.mybatisflex.core.audit; 017 018import com.mybatisflex.core.mybatis.TypeHandlerObject; 019import com.mybatisflex.core.util.ClassUtil; 020import com.mybatisflex.core.util.SqlUtil; 021 022import java.io.Serializable; 023import java.lang.reflect.Array; 024import java.lang.reflect.Proxy; 025import java.sql.PreparedStatement; 026import java.sql.SQLException; 027import java.sql.Statement; 028import java.util.ArrayList; 029import java.util.HashMap; 030import java.util.List; 031import java.util.Map; 032 033/** 034 * SQL 审计详细消息。 035 */ 036public class AuditMessage implements Serializable { 037 038 /** 039 * 平台,或者是运行的应用。 040 */ 041 private String platform; 042 043 /** 044 * 应用模块。 045 */ 046 private String module; 047 048 /** 049 * 执行这个 SQL 涉及的 URL 地址。 050 */ 051 private String url; 052 053 /** 054 * 自定义业务 ID。 055 */ 056 private String bizId; 057 058 /** 059 * 执行这个 SQL 涉及的平台用户。 060 */ 061 private String user; 062 063 /** 064 * 执行这个 SQL 的平台用户 IP 地址。 065 */ 066 private String userIp; 067 068 /** 069 * 执行这个 SQL 的服务器 IP 地址。 070 */ 071 private String hostIp; 072 073 /** 074 * SQL 内容。 075 */ 076 private String query; 077 078 /** 079 * SQL 参数。 080 */ 081 private List<Object> queryParams; 082 083 /** 084 * SQL 查询出来数据的数量。 085 */ 086 private int queryCount; 087 088 /** 089 * SQL 执行的时间点(当前时间,毫秒)。 090 */ 091 private long queryTime; 092 093 /** 094 * SQL 执行的消耗时间(毫秒)。 095 */ 096 private long elapsedTime; 097 098 /** 099 * 其他扩展元信息。 100 */ 101 private Map<String, Object> metas; 102 103 public String getPlatform() { 104 return platform; 105 } 106 107 public void setPlatform(String platform) { 108 this.platform = platform; 109 } 110 111 public String getModule() { 112 return module; 113 } 114 115 public void setModule(String module) { 116 this.module = module; 117 } 118 119 public String getUrl() { 120 return url; 121 } 122 123 public void setUrl(String url) { 124 this.url = url; 125 } 126 127 public String getBizId() { 128 return bizId; 129 } 130 131 public void setBizId(String bizId) { 132 this.bizId = bizId; 133 } 134 135 public String getUser() { 136 return user; 137 } 138 139 public void setUser(String user) { 140 this.user = user; 141 } 142 143 public String getUserIp() { 144 return userIp; 145 } 146 147 public void setUserIp(String userIp) { 148 this.userIp = userIp; 149 } 150 151 public String getHostIp() { 152 return hostIp; 153 } 154 155 public void setHostIp(String hostIp) { 156 this.hostIp = hostIp; 157 } 158 159 public String getQuery() { 160 return query; 161 } 162 163 public void setQuery(String query) { 164 this.query = query; 165 } 166 167 public List<Object> getQueryParams() { 168 return queryParams; 169 } 170 171 public void setQueryParams(List<Object> queryParams) { 172 this.queryParams = queryParams; 173 } 174 175 public void addParams(Statement statement, Object... objects) { 176 if (queryParams == null) { 177 queryParams = new ArrayList<>(); 178 } 179 180 for (Object object : objects) { 181 if (object != null && ClassUtil.isArray(object.getClass())) { 182 for (int i = 0; i < Array.getLength(object); i++) { 183 doAddParam(statement, Array.get(object, i)); 184 } 185 } else { 186 doAddParam(statement, object); 187 } 188 } 189 } 190 191 private void doAddParam(Statement statement, Object object) { 192 try { 193 if (object instanceof TypeHandlerObject) { 194 ((TypeHandlerObject) object).setParameter(createPreparedStatement(statement), 0); 195 } else if (object instanceof java.sql.Array) { 196 Object array = ((java.sql.Array) object).getArray(); 197 queryParams.add(array); 198 } else { 199 queryParams.add(object); 200 } 201 } catch (SQLException e) { 202 //ignore 203 } 204 } 205 206 public String getFullSql() { 207 List<Object> queryParams = getQueryParams(); 208 return SqlUtil.replaceSqlParams(getQuery(), queryParams == null ? null : queryParams.toArray()); 209 } 210 211 private PreparedStatement createPreparedStatement(Statement statement) { 212 return (PreparedStatement) Proxy.newProxyInstance( 213 AuditMessage.class.getClassLoader(), 214 new Class[]{PreparedStatement.class}, (proxy, method, args) -> { 215 if (args != null && (args.length == 2 || args.length == 3)) { 216 doAddParam(statement, args[1]); 217 } else if ("getConnection".equals(method.getName())) { 218 return statement.getConnection(); 219 } 220 return null; 221 }); 222 } 223 224 public int getQueryCount() { 225 return queryCount; 226 } 227 228 public void setQueryCount(int queryCount) { 229 this.queryCount = queryCount; 230 } 231 232 public long getQueryTime() { 233 return queryTime; 234 } 235 236 public void setQueryTime(long queryTime) { 237 this.queryTime = queryTime; 238 } 239 240 public long getElapsedTime() { 241 return elapsedTime; 242 } 243 244 public void setElapsedTime(long elapsedTime) { 245 this.elapsedTime = elapsedTime; 246 } 247 248 public Map<String, Object> getMetas() { 249 return metas; 250 } 251 252 public void setMetas(Map<String, Object> metas) { 253 this.metas = metas; 254 } 255 256 public void addMeta(String key, Object value) { 257 if (metas == null) { 258 metas = new HashMap<>(); 259 } 260 metas.put(key, value); 261 } 262 263 @Override 264 public String toString() { 265 return "AuditMessage{" + 266 "platform='" + platform + '\'' + 267 ", module='" + module + '\'' + 268 ", url='" + url + '\'' + 269 ", bizId='" + bizId + '\'' + 270 ", user='" + user + '\'' + 271 ", userIp='" + userIp + '\'' + 272 ", hostIp='" + hostIp + '\'' + 273 ", query='" + query + '\'' + 274 ", queryParams=" + queryParams + 275 ", queryCount=" + queryCount + 276 ", queryTime=" + queryTime + 277 ", elapsedTime=" + elapsedTime + 278 ", metas=" + metas + 279 '}'; 280 } 281 282}