Skip to content

Commit

Permalink
intake: Add rows_affected to span db information (elastic#3095)
Browse files Browse the repository at this point in the history
Allow to include number of rows affected by a sql database statement
in the db information of a span.

closes elastic#2802
  • Loading branch information
simitt committed Jan 6, 2020
1 parent e39b87c commit 7104395
Show file tree
Hide file tree
Showing 12 changed files with 76 additions and 32 deletions.
2 changes: 1 addition & 1 deletion NOTICE.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Apm Server
Copyright 2014-2019 Elasticsearch BV
Copyright 2014-2020 Elasticsearch BV

This product includes software developed by The Apache Software
Foundation (http://www.apache.org/).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@
"db": {
"instance": "customers",
"link": "other.db.com",
"rows_affected": 2,
"statement": "SELECT * FROM product_types WHERE user_id=?",
"type": "sql",
"user": {
Expand Down
1 change: 1 addition & 0 deletions docs/data/elasticsearch/generated/spans.json
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@
"db": {
"instance": "customers",
"link": "other.db.com",
"rows_affected": 2,
"statement": "SELECT * FROM product_types WHERE user_id=?",
"type": "sql",
"user": {
Expand Down
10 changes: 10 additions & 0 deletions docs/fields.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -1442,6 +1442,16 @@ type: keyword
--
*`span.db.rows_affected`*::
+
--
Number of rows affected by the database statement.
type: long
--
[float]
=== service
Expand Down
6 changes: 5 additions & 1 deletion docs/spec/spans/span.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
"maxLength": 1024
}
},
"required": ["type", "name", "resource"]
"required": ["type", "name", "resource"]
}
}
},
Expand Down Expand Up @@ -102,6 +102,10 @@
"user": {
"type": ["string", "null"],
"description": "Username for accessing database"
},
"rows_affected": {
"type": ["integer", "null"],
"description": "Number of rows affected by the SQL statement (if applicable)"
}
}
},
Expand Down
2 changes: 1 addition & 1 deletion include/fields.go

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions model/span/_meta/fields.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@
description: >
Database link.
- name: rows_affected
type: long
description: >
Number of rows affected by the database statement.
- name: destination
type: group
dynamic: false
Expand Down
13 changes: 8 additions & 5 deletions model/span/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,12 @@ type Event struct {
}

type db struct {
Instance *string
Statement *string
Type *string
UserName *string
Link *string
Instance *string
Statement *string
Type *string
UserName *string
Link *string
RowsAffected *int
}

func decodeDB(input interface{}, err error) (*db, error) {
Expand All @@ -115,6 +116,7 @@ func decodeDB(input interface{}, err error) (*db, error) {
decoder.StringPtr(dbInput, "type"),
decoder.StringPtr(dbInput, "user"),
decoder.StringPtr(dbInput, "link"),
decoder.IntPtr(dbInput, "rows_affected"),
}
return &db, decoder.Err
}
Expand All @@ -127,6 +129,7 @@ func (db *db) fields() common.MapStr {
utility.Set(fields, "instance", db.Instance)
utility.Set(fields, "statement", db.Statement)
utility.Set(fields, "type", db.Type)
utility.Set(fields, "rows_affected", db.RowsAffected)
if db.UserName != nil {
utility.Set(fields, "user", common.MapStr{"name": db.UserName})
}
Expand Down
59 changes: 37 additions & 22 deletions model/span/event_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,16 @@ func TestDecodeSpan(t *testing.T) {
name, spType := "foo", "db"
start, duration := 1.2, 3.4
method, statusCode, url := "get", 200, "http://localhost"
instance, statement, dbType, user, link := "db01", "select *", "sql", "joe", "other.db.com"
instance, statement, dbType, user, link, rowsAffected := "db01", "select *", "sql", "joe", "other.db.com", 34
address, port := "localhost", 8080
destServiceType, destServiceName, destServiceResource := "db", "elasticsearch", "elasticsearch"
context := map[string]interface{}{
"a": "b",
"tags": map[string]interface{}{"a": "tag", "tag.key": 17},
"http": map[string]interface{}{"method": "GET", "status_code": json.Number("200"), "url": url},
"db": map[string]interface{}{"instance": instance, "statement": statement, "type": dbType, "user": user, "link": link},
"db": map[string]interface{}{
"instance": instance, "statement": statement, "type": dbType,
"user": user, "link": link, "rows_affected": json.Number("34")},
"destination": map[string]interface{}{
"address": address,
"port": float64(port),
Expand Down Expand Up @@ -220,8 +222,15 @@ func TestDecodeSpan(t *testing.T) {
ParentId: parentId,
TransactionId: &transactionId,
HTTP: &http{Method: &method, StatusCode: &statusCode, Url: &url},
DB: &db{Instance: &instance, Statement: &statement, Type: &dbType, UserName: &user, Link: &link},
Destination: &destination{Address: &address, Port: &port},
DB: &db{
Instance: &instance,
Statement: &statement,
Type: &dbType,
UserName: &user,
Link: &link,
RowsAffected: &rowsAffected,
},
Destination: &destination{Address: &address, Port: &port},
DestinationService: &destinationService{
Type: &destServiceType,
Name: &destServiceName,
Expand Down Expand Up @@ -255,7 +264,7 @@ func TestSpanTransform(t *testing.T) {
time.FixedZone("+0100", 3600))
timestampUs := timestamp.UnixNano() / 1000
method, statusCode, url := "get", 200, "http://localhost"
instance, statement, dbType, user := "db01", "select *", "sql", "jane"
instance, statement, dbType, user, rowsAffected := "db01", "select *", "sql", "jane", 5
metadataLabels := common.MapStr{"label.a": "a", "label.b": "b", "c": 1}
address, port := "127.0.0.1", 8080
destServiceType, destServiceName, destServiceResource := "db", "elasticsearch", "elasticsearch"
Expand All @@ -282,19 +291,24 @@ func TestSpanTransform(t *testing.T) {
},
{
Event: Event{
Id: hexId,
TraceId: traceId,
ParentId: parentId,
Name: "myspan",
Type: "myspantype",
Subtype: &subtype,
Action: &action,
Start: &start,
Duration: 1.20,
Stacktrace: m.Stacktrace{{AbsPath: &path}},
Labels: common.MapStr{"label.a": 12},
HTTP: &http{Method: &method, StatusCode: &statusCode, Url: &url},
DB: &db{Instance: &instance, Statement: &statement, Type: &dbType, UserName: &user},
Id: hexId,
TraceId: traceId,
ParentId: parentId,
Name: "myspan",
Type: "myspantype",
Subtype: &subtype,
Action: &action,
Start: &start,
Duration: 1.20,
Stacktrace: m.Stacktrace{{AbsPath: &path}},
Labels: common.MapStr{"label.a": 12},
HTTP: &http{Method: &method, StatusCode: &statusCode, Url: &url},
DB: &db{
Instance: &instance,
Statement: &statement,
Type: &dbType,
UserName: &user,
RowsAffected: &rowsAffected},
Destination: &destination{Address: &address, Port: &port},
DestinationService: &destinationService{
Type: &destServiceType,
Expand All @@ -320,10 +334,11 @@ func TestSpanTransform(t *testing.T) {
"updated": false,
}}},
"db": common.MapStr{
"instance": instance,
"statement": statement,
"type": dbType,
"user": common.MapStr{"name": user},
"instance": instance,
"statement": statement,
"type": dbType,
"user": common.MapStr{"name": user},
"rows_affected": rowsAffected,
},
"http": common.MapStr{
"url": common.MapStr{"original": url},
Expand Down
6 changes: 5 additions & 1 deletion model/span/generated/schema/span.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ const ModelSchema = `{
"maxLength": 1024
}
},
"required": ["type", "name", "resource"]
"required": ["type", "name", "resource"]
}
}
},
Expand Down Expand Up @@ -148,6 +148,10 @@ const ModelSchema = `{
"user": {
"type": ["string", "null"],
"description": "Username for accessing database"
},
"rows_affected": {
"type": ["integer", "null"],
"description": "Number of rows affected by the SQL statement (if applicable)"
}
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@
"db": {
"instance": "customers",
"link": "other.db.com",
"rows_affected": 2,
"statement": "SELECT * FROM product_types WHERE user_id=?",
"type": "sql",
"user": {
Expand Down
2 changes: 1 addition & 1 deletion testdata/intake-v2/spans.ndjson
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
{"span": {"trace_id": "abcdef0123456789abcdef9876543210", "parent_id": "0000000011111111", "id": "1234abcdef567895", "transaction_id": "ab45781d265894fe", "name": "GET /api/types", "type": "request", "start": 22, "duration": 32.592981, "timestamp": 1532976822281000,"context":{"service":{"environment":"prod","agent":{}}}}}
{"span": {"trace_id": "abcdef0123456789abcdef9876543210", "parent_id": "abcdefabcdef7890", "id": "0123456a89012345", "transaction_id": "ab23456a89012345", "name": "GET /api/types", "type": "request.http", "start": 1.845, "duration": 3.5642981, "stacktrace": [], "context":{"tags": {"tag1": "value1", "tag2": 123, "tag3": 12.34, "tag4": true, "tag5": null},"service":{}}}}}
{"span": {"trace_id": "abcdef0123456789abcdef9876543210", "parent_id": "ababcdcdefefabde", "id": "abcde56a89012345", "transaction_id": null, "name": "get /api/types", "sync": false, "type": "request", "subtype": "http", "action": "call", "start": 0, "duration": 13.9802981, "stacktrace": null, "context": null }}
{"span": {"trace_id": "abcdef0123456789abcdef9876543210", "parent_id": "abcdef0123456789", "id": "1234567890aaaade", "sync": true, "name": "SELECT FROM product_types", "type": "db.postgresql.query", "start": 2.83092, "duration": 3.781912, "stacktrace": [{ "filename": "net.js", "lineno": 547},{"filename": "file2.js", "lineno": 12, "post_context": [ " ins.currentTransaction = prev", "}"]}, { "function": "onread", "abs_path": "net.js", "filename": "net.js", "lineno": 547, "library_frame": true, "vars": { "key": "value" }, "module": "some module", "colno": 4, "context_line": "line3", "pre_context": [ " var trans = this.currentTransaction", "" ], "post_context": [ " ins.currentTransaction = prev", " return result"] }], "context": { "db": { "instance": "customers", "statement": "SELECT * FROM product_types WHERE user_id=?", "type": "sql", "user": "readonly_user", "link": "other.db.com" }, "http": { "url": "http://localhost:8000", "status_code": 200, "method": "GET" }, "destination": {"address": "0:0::0:1", "port": 5432, "service": {"type": "db", "name": "postgresql", "resource": "postgresql"}}, "service":{"name":"service1","agent":{"version":"2.2","name":"elastic-ruby", "ephemeral_id": "justanid"}}}}}
{"span": {"trace_id": "abcdef0123456789abcdef9876543210", "parent_id": "abcdef0123456789", "id": "1234567890aaaade", "sync": true, "name": "SELECT FROM product_types", "type": "db.postgresql.query", "start": 2.83092, "duration": 3.781912, "stacktrace": [{ "filename": "net.js", "lineno": 547},{"filename": "file2.js", "lineno": 12, "post_context": [ " ins.currentTransaction = prev", "}"]}, { "function": "onread", "abs_path": "net.js", "filename": "net.js", "lineno": 547, "library_frame": true, "vars": { "key": "value" }, "module": "some module", "colno": 4, "context_line": "line3", "pre_context": [ " var trans = this.currentTransaction", "" ], "post_context": [ " ins.currentTransaction = prev", " return result"] }], "context": { "db": { "instance": "customers", "statement": "SELECT * FROM product_types WHERE user_id=?", "type": "sql", "user": "readonly_user", "link": "other.db.com", "rows_affected": 2 }, "http": { "url": "http://localhost:8000", "status_code": 200, "method": "GET" }, "destination": {"address": "0:0::0:1", "port": 5432, "service": {"type": "db", "name": "postgresql", "resource": "postgresql"}}, "service":{"name":"service1","agent":{"version":"2.2","name":"elastic-ruby", "ephemeral_id": "justanid"}}}}}

0 comments on commit 7104395

Please sign in to comment.