Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(couchbase): added support for raw sql queries #1187

Merged
merged 3 commits into from
Jun 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 66 additions & 13 deletions packages/collector/test/tracing/database/couchbase/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ const verifyCouchbaseSpan = (controls, entrySpan, options = {}) => [
// eslint-disable-next-line no-nested-ternary
'type' in options ? (options.type === '' ? undefined : options.type) : 'membase'
),
span => expect(span.data.couchbase.sql).to.equal(options.sql || 'GET'),
span => expect(span.data.couchbase.sql).to.contain(options.sql || 'GET'),
span =>
options.error
? expect(span.data.couchbase.error).to.equal(options.error)
Expand Down Expand Up @@ -393,15 +393,15 @@ mochaSuiteFn('tracing/couchbase', function () {
);
}));

// flaky on CI
it.skip('[analyticsindexes] must trace', () =>
it('[analyticsindexes] must trace', () =>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI un-skipped for now. I want to see if they are still flaky.

controls
.sendRequest({
method: 'post',
path: `/analyticsindexes-${apiType}`
})
.then(resp => {
expect(resp.success).to.eql(true);

return retry(() =>
verifySpans(agentControls, controls, {
spanLength: 9,
Expand All @@ -411,25 +411,78 @@ mochaSuiteFn('tracing/couchbase', function () {
verifyCouchbaseSpan(controls, entrySpan, {
bucket: 'projects',
type: 'membase',
sql: 'ANALYTICSQUERY'
sql: 'SELECT '
})
);
expectExactlyNMatching(
spans,
1,
verifyCouchbaseSpan(controls, entrySpan, {
bucket: '',
type: '',
sql: 'CREATE DATAVERSE '
})
);
expectExactlyNMatching(
spans,
1,
verifyCouchbaseSpan(controls, entrySpan, {
bucket: '',
type: '',
sql: 'CREATE DATASET '
})
);
expectExactlyNMatching(
spans,
1,
verifyCouchbaseSpan(controls, entrySpan, {
bucket: '',
type: '',
sql: 'CREATE INDEX '
})
);
expectExactlyNMatching(
spans,
7,
1,
verifyCouchbaseSpan(controls, entrySpan, {
bucket: '',
type: '',
sql: 'SELECT'
})
);
expectExactlyNMatching(
spans,
1,
verifyCouchbaseSpan(controls, entrySpan, {
bucket: '',
type: '',
sql: 'DROP INDEX '
})
);
expectExactlyNMatching(
spans,
1,
verifyCouchbaseSpan(controls, entrySpan, {
bucket: '',
type: '',
sql: 'DROP DATASET '
})
);
expectExactlyNMatching(
spans,
1,
verifyCouchbaseSpan(controls, entrySpan, {
bucket: '',
type: '',
sql: 'ANALYTICSQUERY'
sql: 'DROP DATAVERSE '
})
);
}
})
);
}));

// flaky on CI
it.skip('[searchquery] must trace', () =>
it('[searchquery] must trace', () =>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI un-skipped for now. I want to see if they are still flaky.

controls
.sendRequest({
method: 'get',
Expand Down Expand Up @@ -575,7 +628,7 @@ mochaSuiteFn('tracing/couchbase', function () {
verifyCouchbaseSpan(controls, entrySpan, {
bucket: '',
type: '',
sql: 'QUERY'
sql: 'SELECT * FROM projects WHERE name='
})
);

Expand All @@ -586,7 +639,7 @@ mochaSuiteFn('tracing/couchbase', function () {
verifyCouchbaseSpan(controls, entrySpan, {
bucket: 'companies',
type: 'ephemeral',
sql: 'QUERY'
sql: 'SELECT * FROM _default WHERE name='
})
);

Expand All @@ -599,7 +652,7 @@ mochaSuiteFn('tracing/couchbase', function () {
// FYI: this error msg does not come from us.
error: 'bucket not found',
type: 'ephemeral',
sql: 'QUERY'
sql: 'SELECT * FROM TABLE_DOES_NOT_EXIST WHERE name'
})
);

Expand Down Expand Up @@ -649,7 +702,7 @@ mochaSuiteFn('tracing/couchbase', function () {
verifyCouchbaseSpan(controls, entrySpan, {
bucket: '',
type: '',
sql: 'QUERY'
sql: 'SELECT * FROM'
})
);
expectExactlyOneMatching(
Expand All @@ -658,7 +711,7 @@ mochaSuiteFn('tracing/couchbase', function () {
bucket: '',
hostname: connStr2,
type: '',
sql: 'QUERY'
sql: 'SELECT * FROM'
})
);
}
Expand Down
113 changes: 72 additions & 41 deletions packages/core/src/tracing/instrumentation/database/couchbase.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ function instrumentCluster(cluster, connectionStr) {
if (!cluster) return;

// #### SEARCH QUERY
shimmer.wrap(cluster, 'searchQuery', instrumentOperation.bind(null, { connectionStr, sqlType: 'SEARCHQUERY' }));
shimmer.wrap(cluster, 'searchQuery', instrumentOperation.bind(null, { connectionStr, sql: 'SEARCHQUERY' }));

// #### CRUD
instrumentCollection(cluster, connectionStr);
Expand All @@ -101,23 +101,44 @@ function instrumentCluster(cluster, connectionStr) {
instrumentTransactions(cluster, connectionStr);

// cluster.query
shimmer.wrap(cluster, 'query', instrumentOperation.bind(null, { connectionStr, sqlType: 'QUERY' }));
shimmer.wrap(cluster, 'query', function insatanClusterQuery(original) {
return function instanaClusterQueryWrapped() {
const originalThis = this;
const originalArgs = arguments;
const sqlStatement = originalArgs[0] || '';

return instrumentOperation(
{
connectionStr,
sql: tracingUtil.shortenDatabaseStatement(sqlStatement)
},
original
).apply(originalThis, originalArgs);
};
});

// #### ANALYTICS SERVICE
shimmer.wrap(
cluster,
'analyticsQuery',
instrumentOperation.bind(null, {
connectionStr,
sqlType: 'ANALYTICSQUERY',
resultHandler: (span, result) => {
if (result && result.rows && result.rows.length > 0 && result.rows[0].BucketName) {
span.data.couchbase.bucket = result.rows[0].BucketName;
span.data.couchbase.type = bucketLookup[span.data.couchbase.bucket];
}
}
})
);
shimmer.wrap(cluster, 'analyticsQuery', function instanaClusterAnalyticsQuery(original) {
return function instanaClusterAnalyticsQueryWrapped() {
const originalThis = this;
const originalArgs = arguments;
const sqlStatement = originalArgs[0] || '';

return instrumentOperation(
{
connectionStr,
sql: tracingUtil.shortenDatabaseStatement(sqlStatement),
resultHandler: (span, result) => {
if (result && result.rows && result.rows.length > 0 && result.rows[0].BucketName) {
span.data.couchbase.bucket = result.rows[0].BucketName;
span.data.couchbase.type = bucketLookup[span.data.couchbase.bucket];
}
}
},
original
).apply(originalThis, originalArgs);
};
});
}

function instrumentCollection(cluster, connectionStr) {
Expand Down Expand Up @@ -145,32 +166,42 @@ function instrumentCollection(cluster, connectionStr) {
// https://github.com/couchbase/couchnode/blob/v4.2.2/src/connection.hpp#L208
['get', 'remove', 'insert', 'upsert', 'replace', 'mutateIn', 'lookupIn', 'exists', 'getAndTouch'].forEach(
op => {
shimmer.wrap(
collection,
op,
instrumentOperation.bind(null, {
connectionStr,
bucketName,
getBucketTypeFn,
sqlType: op.toUpperCase()
})
);
shimmer.wrap(collection, op, function instanaCollectionWrapped(original) {
return function instanaCollectionWrappedInner() {
return instrumentOperation(
{
connectionStr,
bucketName,
getBucketTypeFn,
sql: op.toUpperCase()
},
original
).apply(this, arguments);
};
});
}
);

return collection;
};

shimmer.wrap(
scope,
'query',
instrumentOperation.bind(null, {
connectionStr,
sqlType: 'QUERY',
bucketName,
getBucketTypeFn: getBucketType(cluster, bucketName)
})
);
shimmer.wrap(scope, 'query', function instanaScopeQuery(original) {
return function instanaScopeQueryWrapped() {
const originalThis = this;
const originalArgs = arguments;
const sqlStatement = originalArgs[0] || '';

return instrumentOperation(
{
connectionStr,
bucketName,
getBucketTypeFn: getBucketType(cluster, bucketName),
sql: tracingUtil.shortenDatabaseStatement(sqlStatement)
},
original
).apply(originalThis, originalArgs);
};
});

return scope;
};
Expand Down Expand Up @@ -207,7 +238,7 @@ function instrumentSearchIndexes(cluster, connectionStr) {
return instrumentOperation(
{
connectionStr,
sqlType: fnName.toUpperCase(),
sql: fnName.toUpperCase(),
bucketName,
getBucketTypeFn,
resultHandler: (span, result) => {
Expand Down Expand Up @@ -252,7 +283,7 @@ function instrumentQueryIndexes(cluster, connectionStr) {
return instrumentOperation(
{
connectionStr,
sqlType: fnName.toUpperCase(),
sql: fnName.toUpperCase(),
bucketName,
getBucketTypeFn
},
Expand Down Expand Up @@ -302,7 +333,7 @@ function instrumentTransactions(cluster, connectionStr) {
connectionStr,
bucketName,
getBucketTypeFn,
sqlType: op.toUpperCase()
sql: op.toUpperCase()
},
original
).apply(originalThis1, originalArgs1);
Expand Down Expand Up @@ -358,7 +389,7 @@ function instrumentTransactions(cluster, connectionStr) {
};
}

function instrumentOperation({ connectionStr, bucketName, getBucketTypeFn, sqlType, resultHandler }, original) {
function instrumentOperation({ connectionStr, bucketName, getBucketTypeFn, sql, resultHandler }, original) {
return function instanaOpOverride() {
const originalThis = this;
const originalArgs = arguments;
Expand All @@ -376,7 +407,7 @@ function instrumentOperation({ connectionStr, bucketName, getBucketTypeFn, sqlTy
hostname: connectionStr,
bucket: bucketName,
type: bucketType,
sql: sqlType
sql
};

const { originalCallback, callbackIndex } = tracingUtil.findCallback(originalArgs);
Expand Down