Closed lrwh closed 1 year ago
oracle 脱敏问题其实并不是oracle的问题 在mysql中也会出现。这是代码的写法问题。 比如 :
ps = conn.prepareStatement("SELECT name,password,id FROM student where name=? and password=?");
ps.setString(1,username); -- set 替换第一个?
ps.setString(2,pw); ---- 替换第二个?
这是jdbc的写法,与库无关(oracle和mysql都是这么写的)。
这种写法 ddtrace拿到的就是 两个 ?
的 resource。
另一种写法
ps = conn.prepareStatement("SELECT name,password,id FROM student where name='guance' and password='123456'");
// ps.setString(1,username); 不再使用 set
// ps.setString(2,pw);
这时候 ddtrace 拿到的就是 不带问号的sql语句。
究其原因,是因为 ddtrace的探针 是在函数 prepareStatement
上。
总结:代码写法不同,拿到的 sql 语句就会不同。与数据库无关
是否可以针对set这种方式也做下集成,探究下可行性方案
通过启动参数开启该功能:
-Ddd.jdbc.sql.obfuscation=true
目前探针的位置在 java.sql.PreparedStatement set(two args), 这里有两个参数,启动第一个是整型,第二个为 Object 类型,在调用 set 方法之后,会将 Object 类型 toString() 之后放到 map中。
在sql最终被执行的方法中,将 map 放置 span 中。
最终的 span 数据格式:
"meta": {
"component":
"java-jdbc-prepared_statement",
"db.instance":"tmalldemodb",
"db.operation":"INSERT",
"db.sql.origin":"INSERT product (product_id,product_name,product_title,product_price,product_sale_price,product_create_date,product_isEnabled,product_category_id) VALUES( null, ?, ?, ?, ?, ?, ?, ?)",
"db.type":"mysql",
"db.user":"root",
"env":"test",
"peer.hostname":"49.232.153.84",
"span.kind":"client",
"sql.params.index_1":"图书",
"sql.params.index_2":"十万个为什么",
"sql.params.index_3":"100.0",
"sql.params.index_4":"99.0",
"sql.params.index_5":"2022-11-10 14:08:21",
"sql.params.index_6":"0",
"sql.params.index_7":"16",
"thread.name":
"http-nio-8080-exec-6"
}
q1: 为什么没有放在原始 sql 中,而是使用 sql.params.index_x :
在调用 set* 时插入的值并不是有序的, 参数 index 是从1开始的而不是0。所以需要先存入map, 再插入span时 进行排序、替换等操作。并且无法保证所有的问号完美对应值。 所以单独的使用 k:v 形式,
目前数据库SQL 脱敏开关配置只支持MySQL,需要对 PostgreSQL 和 Oracle 都支持这种开关配置。