diff --git a/CHANGELOG.md b/CHANGELOG.md index f6a290f32..7dec31d24 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ ### New features - Display scheduler run queue latency on Trace-Profiling chart. To learn more about the concept of 'Run Queue Latency', refer to [this blog post](https://www.brendangregg.com/blog/2016-10-08/linux-bcc-runqlat.html). You can also find a use case for this feature in [this blog post](http://kindling.harmonycloud.cn/blogs/use-cases/optimize-cpu/). ([#494](https://github.com/KindlingProject/kindling/pull/494)) ### Enhancements +- MySQL CommandLine Case: Ignore quit command and get sql with CLIENT_QUERY_ATTRIBUTES([#523](https://github.com/KindlingProject/kindling/pull/523)) - ⚠️Breaking change: Refactor the data format of on/off CPU events from "string" to "array". Note that the old data format cannot be parsed using the new version of the front-end.([#512](https://github.com/KindlingProject/kindling/pull/512) [#520](https://github.com/KindlingProject/kindling/pull/520)) ### Bug fixes - Fix panic: send on closed channel. ([#519](https://github.com/KindlingProject/kindling/pull/519)) diff --git a/collector/pkg/component/analyzer/network/network_analyzer.go b/collector/pkg/component/analyzer/network/network_analyzer.go index adf91d7a0..505cd3a47 100644 --- a/collector/pkg/component/analyzer/network/network_analyzer.go +++ b/collector/pkg/component/analyzer/network/network_analyzer.go @@ -449,6 +449,9 @@ func (na *NetworkAnalyzer) parseProtocol(mps *messagePairs, parser *protocol.Pro } if mps.responses == nil { + if requestMsg.GetAttributes().GetBoolValue(constlabels.Oneway) { + return []*model.DataGroup{} + } return na.getRecords(mps, parser.GetProtocol(), requestMsg.GetAttributes()) } diff --git a/collector/pkg/component/analyzer/network/network_analyzer_test.go b/collector/pkg/component/analyzer/network/network_analyzer_test.go index af1d0946e..19f7abe52 100644 --- a/collector/pkg/component/analyzer/network/network_analyzer_test.go +++ b/collector/pkg/component/analyzer/network/network_analyzer_test.go @@ -33,7 +33,10 @@ func TestMySqlProtocol(t *testing.T) { testProtocol(t, "mysql/server-event.yml", "mysql/server-trace-commit.yml", "mysql/server-trace-query-split.yml", - "mysql/server-trace-query.yml") + "mysql/server-trace-query.yml", + "mysql/server-trace-oneway.yml", + "mysql/server-trace-query-cmd.yml", + ) } func TestRedisProtocol(t *testing.T) { diff --git a/collector/pkg/component/analyzer/network/protocol/mysql/mysql_parser.go b/collector/pkg/component/analyzer/network/protocol/mysql/mysql_parser.go index 7d180eaaa..f107a96f5 100644 --- a/collector/pkg/component/analyzer/network/protocol/mysql/mysql_parser.go +++ b/collector/pkg/component/analyzer/network/protocol/mysql/mysql_parser.go @@ -5,14 +5,15 @@ import ( ) /* - Request Response - / \ / | \ -prepare query err ok eof + Request Response + / | \ / | \ + prepare query quit err ok eof */ func NewMysqlParser() *protocol.ProtocolParser { requestParser := protocol.CreatePkgParser(fastfailMysqlRequest(), parseMysqlRequest()) requestParser.Add(fastfailMysqlPrepare(), parseMysqlPrepare()) requestParser.Add(fastfailMysqlQuery(), parseMysqlQuery()) + requestParser.Add(fastfailMysqlQuit(), parseMysqlQuit()) responseParser := protocol.CreatePkgParser(fastfailMysqlResponse(), parseMysqlResponse()) responseParser.Add(fastfailMysqlErr(), parseMysqlErr()) diff --git a/collector/pkg/component/analyzer/network/protocol/mysql/mysql_request.go b/collector/pkg/component/analyzer/network/protocol/mysql/mysql_request.go index 726911005..b371e0647 100644 --- a/collector/pkg/component/analyzer/network/protocol/mysql/mysql_request.go +++ b/collector/pkg/component/analyzer/network/protocol/mysql/mysql_request.go @@ -51,6 +51,12 @@ func parseMysqlPrepare() protocol.ParsePkgFn { /* ===== PayLoad ===== 1 COM_QUERY<03> +CLIENT_QUERY_ATTRIBUTES + + 1 Number of parameters + 1 Number of parameter sets. Currently always 1 + ... + string[EOF] the query the server shall execute */ func fastfailMysqlQuery() protocol.FastFailFn { @@ -62,6 +68,11 @@ func fastfailMysqlQuery() protocol.FastFailFn { func parseMysqlQuery() protocol.ParsePkgFn { return func(message *protocol.PayloadMessage) (bool, bool) { sql := string(message.Data[5:]) + if len(sql) > 2 && sql[0] == 0x00 && sql[1] == 0x01 { + // Only Fix Zero params Case. + // TODO Fix One more params case. + sql = sql[2:] + } if !isSql(sql) { return false, true } @@ -72,6 +83,23 @@ func parseMysqlQuery() protocol.ParsePkgFn { } } +/* +===== PayLoad ===== +1 COM_QUIT<01> +*/ +func fastfailMysqlQuit() protocol.FastFailFn { + return func(message *protocol.PayloadMessage) bool { + return message.Data[4] != 1 + } +} + +func parseMysqlQuit() protocol.ParsePkgFn { + return func(message *protocol.PayloadMessage) (bool, bool) { + message.AddBoolAttribute(constlabels.Oneway, true) + return true, true + } +} + var sqlPrefixs = []string{ "select", "insert", diff --git a/collector/pkg/component/analyzer/network/protocol/testdata/mysql/server-trace-oneway.yml b/collector/pkg/component/analyzer/network/protocol/testdata/mysql/server-trace-oneway.yml new file mode 100644 index 000000000..af310cd16 --- /dev/null +++ b/collector/pkg/component/analyzer/network/protocol/testdata/mysql/server-trace-oneway.yml @@ -0,0 +1,14 @@ +trace: + key: oneway + requests: + - + name: "recvfrom" + timestamp: 100000000 + user_attributes: + latency: 2000 + res: 24 + data: + - "hex|14000000" + - "hex|01" + expects: + # No Result, Ignore it. \ No newline at end of file diff --git a/collector/pkg/component/analyzer/network/protocol/testdata/mysql/server-trace-query-cmd.yml b/collector/pkg/component/analyzer/network/protocol/testdata/mysql/server-trace-query-cmd.yml new file mode 100644 index 000000000..3e5666853 --- /dev/null +++ b/collector/pkg/component/analyzer/network/protocol/testdata/mysql/server-trace-query-cmd.yml @@ -0,0 +1,65 @@ +trace: + key: query-cmd + requests: + - + name: "recvfrom" + timestamp: 100000000 + user_attributes: + latency: 2000 + res: 24 + data: + - "hex|14000000" + - "030001|SELECT * FROM dummy" + responses: + - + name: "sendto" + timestamp: 100020000 + user_attributes: + latency: 15000 + res: 160 + data: + - "hex|0100000102" + - "hex|39000002" + - "03|def" + - "11|container-monitor" + - "05|dummy" + - "05|dummy" + - "04|name" + - "04|name" + - "hex|0c2d00b4000000fd0110000000" + - "hex|3b000003" + - "03|def" + - "11|conta" + expects: + - + Timestamp: 99998000 + Values: + request_total_time: 22000 + connect_time: 0 + request_sent_time: 2000 + waiting_ttfb_time: 5000 + content_download_time: 15000 + request_io: 24 + response_io: 160 + Labels: + comm: "mysqld" + pid: 903 + request_tid: 2744 + response_tid: 2744 + src_ip: "127.0.0.1" + src_port: 49368 + dst_ip: "127.0.0.1" + dst_port: 3306 + dnat_ip: "" + dnat_port: -1 + container_id: "" + is_slow: false + is_server: true + protocol: "mysql" + content_key: "select dummy *" + sql: "SELECT * FROM dummy" + request_payload: ".......SELECT * FROM dummy" + response_payload: ".....9....def.container-monitor.dummy.dummy.name.name.-...........;....def.conta" + is_error: false + error_type: 0 + end_timestamp: 100020000 diff --git a/collector/pkg/model/constlabels/protocols.go b/collector/pkg/model/constlabels/protocols.go index 06fb29e4f..a4a986db8 100644 --- a/collector/pkg/model/constlabels/protocols.go +++ b/collector/pkg/model/constlabels/protocols.go @@ -17,6 +17,8 @@ const ( DnsRcode = "dns_rcode" DnsIp = "dns_ip" + Oneway = "one_way" + Sql = "sql" SqlErrCode = "sql_error_code" SqlErrMsg = "sql_error_msg"