This is an automated email from the ASF dual-hosted git repository.

wusheng pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/skywalking-go.git


The following commit(s) were added to refs/heads/main by this push:
     new 850a4cb  feat: add tracing.TagDBStatement and 
tracing.TagDBSqlParameters for gorm (#189)
850a4cb is described below

commit 850a4cb4133538da23c0cfc9e806f268a2a6f68a
Author: Hair1ossTeenager <45008570+hair1ossteena...@users.noreply.github.com>
AuthorDate: Wed Jul 31 18:21:49 2024 +0800

    feat: add tracing.TagDBStatement and tracing.TagDBSqlParameters for gorm 
(#189)
---
 CHANGES.md                                      |  1 +
 plugins/gorm/entry/callback.go                  | 19 +++++++++++++++++++
 plugins/gorm/entry/config.go                    | 23 +++++++++++++++++++++++
 plugins/gorm/entry/interceptor_test.go          | 17 ++++++++++++++++-
 test/plugins/scenarios/gorm/bin/startup.sh      |  2 ++
 test/plugins/scenarios/gorm/config/excepted.yml | 10 ++++++++++
 tools/go-agent/config/agent.default.yaml        |  3 +++
 7 files changed, 74 insertions(+), 1 deletion(-)

diff --git a/CHANGES.md b/CHANGES.md
index 26f08f9..e7080b9 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -16,6 +16,7 @@ Release Notes.
 * Support higher versions of grpc.
 * Support [go-elasticsearchv8](https://github.com/elastic/go-elasticsearch) 
database client framework.
 * Support `http.Hijacker` interface for mux plugin.
+* Support collect statements and parameters in the Gorm plugin. 
 
 ### Bug Fixes
 * Fix panic error when root span finished.
diff --git a/plugins/gorm/entry/callback.go b/plugins/gorm/entry/callback.go
index 5aa2b2b..51b6686 100644
--- a/plugins/gorm/entry/callback.go
+++ b/plugins/gorm/entry/callback.go
@@ -57,8 +57,27 @@ func afterCallback(dbInfo DatabaseInfo) func(db *gorm.DB) {
 
                defer span.End()
 
+               span.Tag(tracing.TagDBStatement, db.Statement.SQL.String())
+               if config.CollectParameter && len(db.Statement.Vars) > 0 {
+                       span.Tag(tracing.TagDBSqlParameters, 
argsToString(db.Statement.Vars))
+               }
                if db.Statement.Error != nil {
                        span.Error(db.Statement.Error.Error())
                }
        }
 }
+
+func argsToString(args []interface{}) string {
+       switch len(args) {
+       case 0:
+               return ""
+       case 1:
+               return fmt.Sprintf("%v", args[0])
+       }
+
+       res := fmt.Sprintf("%v", args[0])
+       for _, arg := range args[1:] {
+               res += fmt.Sprintf(", %v", arg)
+       }
+       return res
+}
diff --git a/plugins/gorm/entry/config.go b/plugins/gorm/entry/config.go
new file mode 100644
index 0000000..bd2c2dd
--- /dev/null
+++ b/plugins/gorm/entry/config.go
@@ -0,0 +1,23 @@
+// Licensed to Apache Software Foundation (ASF) under one or more contributor
+// license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright
+// ownership. Apache Software Foundation (ASF) licenses this file to you under
+// the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package entry
+
+//skywalking:config gorm
+var config struct {
+       CollectParameter bool `config:"collect_parameter"`
+}
diff --git a/plugins/gorm/entry/interceptor_test.go 
b/plugins/gorm/entry/interceptor_test.go
index 9321b5f..76600ca 100644
--- a/plugins/gorm/entry/interceptor_test.go
+++ b/plugins/gorm/entry/interceptor_test.go
@@ -25,6 +25,7 @@ import (
        "time"
 
        "github.com/apache/skywalking-go/plugins/core"
+       "github.com/apache/skywalking-go/plugins/core/tracing"
        "github.com/apache/skywalking-go/plugins/gorm/mysql"
 
        "github.com/stretchr/testify/assert"
@@ -51,7 +52,11 @@ func TestInterceptor(t *testing.T) {
        err = interceptor.AfterInvoke(nil, db, err)
        assert.Nil(t, err, "failed to invoke AfterInvoke")
 
-       res := db.Exec("select * from test")
+       config.CollectParameter = true
+       id := "1"
+       name := "test"
+       sqlString := "select * from test where id = ? and name = ?"
+       res := db.Exec(sqlString, id, name)
 
        assert.Equal(t, errConnectionExecute, res.Error, "failed to invoke 
Rows")
        time.Sleep(100 * time.Millisecond)
@@ -64,6 +69,16 @@ func TestInterceptor(t *testing.T) {
        assert.Nil(t, spans[0].Refs(), "refs should be nil")
        assert.Greater(t, spans[0].StartTime(), int64(0), "end time should be 
greater than zero")
        assert.Greater(t, spans[0].EndTime(), int64(0), "end time should be 
greater than zero")
+       tagsKV := map[string]string{
+               tracing.TagDBType:          "mysql",
+               tracing.TagDBStatement:     sqlString,
+               tracing.TagDBSqlParameters: fmt.Sprintf("%s, %s", id, name),
+       }
+       for _, tag := range spans[0].Tags() {
+               if v, ok := tagsKV[tag.Key]; ok {
+                       assert.Equal(t, v, tag.Value, fmt.Sprintf("%s should be 
%s, not %s", tag.Key, v, tag.Value))
+               }
+       }
 }
 
 type TestDialector struct {
diff --git a/test/plugins/scenarios/gorm/bin/startup.sh 
b/test/plugins/scenarios/gorm/bin/startup.sh
index fffd7b4..ad57f6d 100755
--- a/test/plugins/scenarios/gorm/bin/startup.sh
+++ b/test/plugins/scenarios/gorm/bin/startup.sh
@@ -19,4 +19,6 @@
 home="$(cd "$(dirname $0)"; pwd)"
 go build ${GO_BUILD_OPTS} -o gorm
 
+export SW_AGENT_PLUGIN_CONFIG_GORM_COLLECT_PARAMETER=true
+
 ./gorm
\ No newline at end of file
diff --git a/test/plugins/scenarios/gorm/config/excepted.yml 
b/test/plugins/scenarios/gorm/config/excepted.yml
index bdd59d2..2fb524e 100644
--- a/test/plugins/scenarios/gorm/config/excepted.yml
+++ b/test/plugins/scenarios/gorm/config/excepted.yml
@@ -33,6 +33,7 @@ segmentItems:
             skipAnalysis: false
             tags:
               - { key: db.type, value: mysql }
+              - { key: db.statement, value: 'CREATE TABLE IF NOT EXISTS users 
(id char(255), name VARCHAR(255), age INTEGER)' }
           - operationName: Mysql/BeginTx
             parentSpanId: 0
             spanId: 2
@@ -59,6 +60,8 @@ segmentItems:
             skipAnalysis: false
             tags:
               - { key: db.type, value: mysql }
+              - { key: db.statement, value: 'INSERT INTO `users` 
(`name`,`age`) VALUES (?,?)' }
+              - { key: db.sql.parameters, value: 'Jinzhu, 18' }
           - operationName: Mysql/Tx/Commit
             parentSpanId: 0
             spanId: 4
@@ -85,6 +88,7 @@ segmentItems:
             skipAnalysis: false
             tags:
               - { key: db.type, value: mysql }
+              - { key: db.statement, value: 'SELECT * FROM `users` ORDER BY 
`users`.`id` LIMIT 1' }
           - operationName: users/row
             parentSpanId: 0
             spanId: 6
@@ -98,6 +102,8 @@ segmentItems:
             skipAnalysis: false
             tags:
               - { key: db.type, value: mysql }
+              - { key: db.statement, value: 'SELECT name,age FROM `users` 
WHERE name = ?' }
+              - { key: db.sql.parameters, value: 'jinzhu' }
           - operationName: Mysql/BeginTx
             parentSpanId: 0
             spanId: 7
@@ -124,6 +130,8 @@ segmentItems:
             skipAnalysis: false
             tags:
               - { key: db.type, value: mysql }
+              - { key: db.statement, value: 'UPDATE `users` SET `name`=? WHERE 
name = ?' }
+              - { key: db.sql.parameters, value: 'hello, jinzhu' }
           - operationName: Mysql/Tx/Commit
             parentSpanId: 0
             spanId: 9
@@ -163,6 +171,8 @@ segmentItems:
             skipAnalysis: false
             tags:
               - { key: db.type, value: mysql }
+              - { key: db.statement, value: 'DELETE FROM `users` WHERE 
`users`.`id` = ?' }
+              - { key: db.sql.parameters, value: '1' }
           - operationName: Mysql/Tx/Commit
             parentSpanId: 0
             spanId: 12
diff --git a/tools/go-agent/config/agent.default.yaml 
b/tools/go-agent/config/agent.default.yaml
index 38c1cdf..c7e3f81 100644
--- a/tools/go-agent/config/agent.default.yaml
+++ b/tools/go-agent/config/agent.default.yaml
@@ -97,6 +97,9 @@ plugin:
     mongo:
       # Collect the statement of the MongoDB request
       collect_statement: 
${SW_AGENT_PLUGIN_CONFIG_MONGO_COLLECT_STATEMENT:false}
+    gorm:
+      # Collect the parameter of the gorm SQL request
+      collect_parameter: ${SW_AGENT_PLUGIN_CONFIG_GORM_COLLECT_PARAMETER:false}
     sql:
       # Collect the parameter of the SQL request
       collect_parameter: ${SW_AGENT_PLUGIN_CONFIG_SQL_COLLECT_PARAMETER:false}

Reply via email to