12
12
import io .opentelemetry .context .Context ;
13
13
import io .opentelemetry .instrumentation .api .instrumenter .AttributesExtractor ;
14
14
import io .opentelemetry .instrumentation .api .internal .SemconvStability ;
15
+ import java .util .Collection ;
15
16
16
17
/**
17
18
* Extractor of <a
@@ -35,6 +36,8 @@ public final class SqlClientAttributesExtractor<REQUEST, RESPONSE>
35
36
private static final AttributeKey <String > DB_QUERY_TEXT = AttributeKey .stringKey ("db.query.text" );
36
37
static final AttributeKey <String > DB_COLLECTION_NAME =
37
38
AttributeKey .stringKey ("db.collection.name" );
39
+ private static final AttributeKey <Long > DB_OPERATION_BATCH_SIZE =
40
+ AttributeKey .longKey ("db.operation.batch.size" );
38
41
39
42
/** Creates the SQL client attributes extractor with default configuration. */
40
43
public static <REQUEST , RESPONSE > AttributesExtractor <REQUEST , RESPONSE > create (
@@ -52,7 +55,7 @@ public static <REQUEST, RESPONSE> SqlClientAttributesExtractorBuilder<REQUEST, R
52
55
}
53
56
54
57
private static final String SQL_CALL = "CALL" ;
55
- // sanitizer is also used to extract operation and table name, so we have it always enable here
58
+ // sanitizer is also used to extract operation and table name, so we have it always enabled here
56
59
private static final SqlStatementSanitizer sanitizer = SqlStatementSanitizer .create (true );
57
60
58
61
private final AttributeKey <String > oldSemconvTableAttribute ;
@@ -71,30 +74,72 @@ public static <REQUEST, RESPONSE> SqlClientAttributesExtractorBuilder<REQUEST, R
71
74
public void onStart (AttributesBuilder attributes , Context parentContext , REQUEST request ) {
72
75
super .onStart (attributes , parentContext , request );
73
76
74
- String rawQueryText = getter .getRawQueryText (request );
75
- SqlStatementInfo sanitizedStatement = sanitizer .sanitize (rawQueryText );
76
- String operation = sanitizedStatement .getOperation ();
77
- if (SemconvStability .emitStableDatabaseSemconv ()) {
78
- internalSet (
79
- attributes ,
80
- DB_QUERY_TEXT ,
81
- statementSanitizationEnabled ? sanitizedStatement .getFullStatement () : rawQueryText );
82
- internalSet (attributes , DB_OPERATION_NAME , operation );
77
+ Collection <String > rawQueryTexts = getter .getRawQueryTexts (request );
78
+
79
+ if (rawQueryTexts .isEmpty ()) {
80
+ return ;
83
81
}
82
+
84
83
if (SemconvStability .emitOldDatabaseSemconv ()) {
85
- internalSet (
86
- attributes ,
87
- DB_STATEMENT ,
88
- statementSanitizationEnabled ? sanitizedStatement .getFullStatement () : rawQueryText );
89
- internalSet (attributes , DB_OPERATION , operation );
84
+ if (rawQueryTexts .size () == 1 ) { // for backcompat(?)
85
+ String rawQueryText = rawQueryTexts .iterator ().next ();
86
+ SqlStatementInfo sanitizedStatement = sanitizer .sanitize (rawQueryText );
87
+ String operation = sanitizedStatement .getOperation ();
88
+ internalSet (
89
+ attributes ,
90
+ DB_STATEMENT ,
91
+ statementSanitizationEnabled ? sanitizedStatement .getFullStatement () : rawQueryText );
92
+ internalSet (attributes , DB_OPERATION , operation );
93
+ if (!SQL_CALL .equals (operation )) {
94
+ internalSet (attributes , oldSemconvTableAttribute , sanitizedStatement .getMainIdentifier ());
95
+ }
96
+ }
90
97
}
91
- if (!SQL_CALL .equals (operation )) {
92
- if (SemconvStability .emitStableDatabaseSemconv ()) {
93
- internalSet (attributes , DB_COLLECTION_NAME , sanitizedStatement .getMainIdentifier ());
98
+
99
+ if (SemconvStability .emitStableDatabaseSemconv ()) {
100
+ Long batchSize = getter .getBatchSize (request );
101
+ boolean isBatch = batchSize != null && batchSize > 1 ;
102
+ if (isBatch ) {
103
+ internalSet (attributes , DB_OPERATION_BATCH_SIZE , batchSize );
94
104
}
95
- if (SemconvStability .emitOldDatabaseSemconv ()) {
96
- internalSet (attributes , oldSemconvTableAttribute , sanitizedStatement .getMainIdentifier ());
105
+ if (rawQueryTexts .size () == 1 ) {
106
+ String rawQueryText = rawQueryTexts .iterator ().next ();
107
+ SqlStatementInfo sanitizedStatement = sanitizer .sanitize (rawQueryText );
108
+ String operation = sanitizedStatement .getOperation ();
109
+ internalSet (
110
+ attributes ,
111
+ DB_QUERY_TEXT ,
112
+ statementSanitizationEnabled ? sanitizedStatement .getFullStatement () : rawQueryText );
113
+ internalSet (attributes , DB_OPERATION_NAME , isBatch ? "BATCH " + operation : operation );
114
+ if (!SQL_CALL .equals (operation )) {
115
+ internalSet (attributes , DB_COLLECTION_NAME , sanitizedStatement .getMainIdentifier ());
116
+ }
117
+ } else {
118
+ MultiQuery multiQuery =
119
+ MultiQuery .analyze (getter .getRawQueryTexts (request ), statementSanitizationEnabled );
120
+ internalSet (attributes , DB_QUERY_TEXT , join ("; " , multiQuery .getStatements ()));
121
+
122
+ String operation =
123
+ multiQuery .getOperation () != null ? "BATCH " + multiQuery .getOperation () : "BATCH" ;
124
+ internalSet (attributes , DB_OPERATION_NAME , operation );
125
+
126
+ if (multiQuery .getMainIdentifier () != null
127
+ && (multiQuery .getOperation () == null || !SQL_CALL .equals (multiQuery .getOperation ()))) {
128
+ internalSet (attributes , DB_COLLECTION_NAME , multiQuery .getMainIdentifier ());
129
+ }
130
+ }
131
+ }
132
+ }
133
+
134
+ // String.join is not available on android
135
+ private static String join (String delimiter , Collection <String > collection ) {
136
+ StringBuilder builder = new StringBuilder ();
137
+ for (String string : collection ) {
138
+ if (builder .length () != 0 ) {
139
+ builder .append (delimiter );
97
140
}
141
+ builder .append (string );
98
142
}
143
+ return builder .toString ();
99
144
}
100
145
}
0 commit comments