Skip to content

Commit

Permalink
Merge branch 'main' into get-session-class
Browse files Browse the repository at this point in the history
  • Loading branch information
alkatrivedi authored Dec 26, 2024
2 parents bd9cb2f + 3cc257e commit fb6a5bb
Show file tree
Hide file tree
Showing 16 changed files with 260 additions and 126 deletions.
22 changes: 21 additions & 1 deletion OBSERVABILITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,27 @@ const spanner = new Spanner({
observabilityOptions: {
tracerProvider: provider,
enableExtendedTracing: true,
},
}
}),
```

#### End to end tracing

In addition to client-side tracing, you can opt in for end-to-end tracing. End-to-end tracing helps you understand and debug latency issues that are specific to Spanner. Refer [here](https://cloud.google.com/spanner/docs/tracing-overview) for more information.

You can opt-in by either:

* Setting the environment variable `SPANNER_ENABLE_END_TO_END_TRACING=true` before your application is started
* In code, setting `enableEndToEndTracing: true` in your SpannerOptions before creating the Cloud Spanner client

```javascript
const spanner = new Spanner({
projectId: projectId,
observabilityOptions: {
tracerProvider: provider,
enableEndToEndTracing: true,
}
}),
```

#### OpenTelemetry gRPC instrumentation
Expand Down
57 changes: 57 additions & 0 deletions observability-test/spanner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import * as mockInstanceAdmin from '../test/mockserver/mockinstanceadmin';
import * as mockDatabaseAdmin from '../test/mockserver/mockdatabaseadmin';
import * as sinon from 'sinon';
import {Row} from '../src/partial-result-stream';
import {END_TO_END_TRACING_HEADER} from '../src/common';
const {
AlwaysOnSampler,
NodeTracerProvider,
Expand Down Expand Up @@ -1930,3 +1931,59 @@ describe('Traces for ExecuteStream broken stream retries', () => {
);
});
});

describe('End to end tracing headers', () => {
let server: grpc.Server;
let spanner: Spanner;
let spannerMock: mock.MockSpanner;
let observabilityOptions: typeof ObservabilityOptions;

beforeEach(async () => {
observabilityOptions = {
enableEndToEndTracing: true,
};

const setupResult = await setup(observabilityOptions);
spanner = setupResult.spanner;
server = setupResult.server;
spannerMock = setupResult.spannerMock;
});

afterEach(async () => {
spannerMock.resetRequests();
spanner.close();
server.tryShutdown(() => {});
});

it('run', done => {
const instance = spanner.instance('instance');
const database = instance.database('database');
database.getTransaction((err, tx) => {
assert.ifError(err);

tx!.run('SELECT 1', async () => {
tx!.end();
let metadataCountWithE2EHeader = 0;
let metadataCountWithTraceParent = 0;
spannerMock.getMetadata().forEach(metadata => {
if (metadata.get(END_TO_END_TRACING_HEADER)[0] !== undefined) {
metadataCountWithE2EHeader++;
assert.strictEqual(
metadata.get(END_TO_END_TRACING_HEADER)[0],
'true'
);
}
if (metadata.get('traceparent')[0] !== undefined) {
metadataCountWithTraceParent++;
}
});

// Batch Create Session request and Select 1 request.
assert.strictEqual(spannerMock.getRequests().length, 2);
assert.strictEqual(metadataCountWithE2EHeader, 2);
assert.strictEqual(metadataCountWithTraceParent, 2);
done();
});
});
});
});
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
"@google-cloud/promisify": "^4.0.0",
"@grpc/proto-loader": "^0.7.0",
"@opentelemetry/api": "^1.9.0",
"@opentelemetry/core": "^1.27.0",
"@opentelemetry/context-async-hooks": "^1.26.0",
"@opentelemetry/semantic-conventions": "^1.25.1",
"@types/big.js": "^6.0.0",
Expand Down
1 change: 1 addition & 0 deletions samples/observability-traces.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ async function main(
observabilityOptions: {
tracerProvider: provider,
enableExtendedTracing: true,
enableEndToEndTracing: true,
},
});

Expand Down
27 changes: 27 additions & 0 deletions src/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,37 @@ export const CLOUD_RESOURCE_HEADER = 'google-cloud-resource-prefix';
*/
export const LEADER_AWARE_ROUTING_HEADER = 'x-goog-spanner-route-to-leader';

/*
* END TO END TRACING header.
*/
export const END_TO_END_TRACING_HEADER = 'x-goog-spanner-end-to-end-tracing';

/**
* Add Leader aware routing header to existing header list.
* @param headers Existing header list.
*/
export function addLeaderAwareRoutingHeader(headers: {[k: string]: string}) {
headers[LEADER_AWARE_ROUTING_HEADER] = 'true';
}

/**
* Returns common headers to add.
* @param headers Common header list.
*/
export function getCommonHeaders(
resourceName: string,
enableTracing?: boolean
) {
const headers: {[k: string]: string} = {};

if (
process.env.SPANNER_ENABLE_END_TO_END_TRACING === 'true' ||
enableTracing
) {
headers[END_TO_END_TRACING_HEADER] = 'true';
}

headers[CLOUD_RESOURCE_HEADER] = resourceName;

return headers;
}
39 changes: 21 additions & 18 deletions src/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ import {
ResourceCallback,
Schema,
addLeaderAwareRoutingHeader,
getCommonHeaders,
} from './common';
import {finished, Duplex, Readable, Transform} from 'stream';
import {PreciseDate} from '@google-cloud/precise-date';
Expand Down Expand Up @@ -341,7 +342,7 @@ class Database extends common.GrpcServiceObject {
pool_: SessionPoolInterface;
sessionFactory_: SessionFactoryInterface;
queryOptions_?: spannerClient.spanner.v1.ExecuteSqlRequest.IQueryOptions;
resourceHeader_: {[k: string]: string};
commonHeaders_: {[k: string]: string};
request: DatabaseRequest;
databaseRole?: string | null;
labels?: {[k: string]: string} | null;
Expand Down Expand Up @@ -463,11 +464,13 @@ class Database extends common.GrpcServiceObject {
dbName: this.formattedName_,
};

this.resourceHeader_ = {
[CLOUD_RESOURCE_HEADER]: this.formattedName_,
};
this.request = instance.request;
this._observabilityOptions = instance._observabilityOptions;
this.commonHeaders_ = getCommonHeaders(
this.formattedName_,
this._observabilityOptions?.enableEndToEndTracing
);

// eslint-disable-next-line @typescript-eslint/no-explicit-any
this.requestStream = instance.requestStream as any;
this.sessionFactory_ = new SessionFactory(this, name, poolOptions);
Expand Down Expand Up @@ -579,7 +582,7 @@ class Database extends common.GrpcServiceObject {
method: 'updateDatabase',
reqOpts,
gaxOpts,
headers: this.resourceHeader_,
headers: this.commonHeaders_,
},
callback!
);
Expand Down Expand Up @@ -685,7 +688,7 @@ class Database extends common.GrpcServiceObject {
sessionCount: count,
};

const headers = this.resourceHeader_;
const headers = this.commonHeaders_;
if (this._getSpanner().routeToLeaderEnabled) {
addLeaderAwareRoutingHeader(headers);
}
Expand Down Expand Up @@ -986,7 +989,7 @@ class Database extends common.GrpcServiceObject {
reqOpts.session.creatorRole =
options.databaseRole || this.databaseRole || null;

const headers = this.resourceHeader_;
const headers = this.commonHeaders_;
if (this._getSpanner().routeToLeaderEnabled) {
addLeaderAwareRoutingHeader(headers);
}
Expand Down Expand Up @@ -1212,7 +1215,7 @@ class Database extends common.GrpcServiceObject {
method: 'dropDatabase',
reqOpts,
gaxOpts,
headers: this.resourceHeader_,
headers: this.commonHeaders_,
},
callback!
);
Expand Down Expand Up @@ -1444,7 +1447,7 @@ class Database extends common.GrpcServiceObject {
method: 'getDatabase',
reqOpts,
gaxOpts,
headers: this.resourceHeader_,
headers: this.commonHeaders_,
},
(err, resp) => {
if (resp) {
Expand Down Expand Up @@ -1698,7 +1701,7 @@ class Database extends common.GrpcServiceObject {
method: 'getDatabaseDdl',
reqOpts,
gaxOpts,
headers: this.resourceHeader_,
headers: this.commonHeaders_,
},
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(err, statements, ...args: any[]) => {
Expand Down Expand Up @@ -1778,7 +1781,7 @@ class Database extends common.GrpcServiceObject {
method: 'getIamPolicy',
reqOpts,
gaxOpts: options.gaxOptions,
headers: this.resourceHeader_,
headers: this.commonHeaders_,
},
(err, resp) => {
callback!(err, resp);
Expand Down Expand Up @@ -1917,7 +1920,7 @@ class Database extends common.GrpcServiceObject {
method: 'listSessions',
reqOpts,
gaxOpts,
headers: this.resourceHeader_,
headers: this.commonHeaders_,
},
(err, sessions, nextPageRequest, ...args) => {
if (err) {
Expand Down Expand Up @@ -2010,7 +2013,7 @@ class Database extends common.GrpcServiceObject {
method: 'listSessionsStream',
reqOpts,
gaxOpts,
headers: this.resourceHeader_,
headers: this.commonHeaders_,
});
}

Expand Down Expand Up @@ -2402,7 +2405,7 @@ class Database extends common.GrpcServiceObject {
method: 'listDatabaseRoles',
reqOpts,
gaxOpts,
headers: this.resourceHeader_,
headers: this.commonHeaders_,
},
(err, roles, nextPageRequest, ...args) => {
const nextQuery = nextPageRequest!
Expand Down Expand Up @@ -2612,7 +2615,7 @@ class Database extends common.GrpcServiceObject {
method: 'restoreDatabase',
reqOpts,
gaxOpts,
headers: this.resourceHeader_,
headers: this.commonHeaders_,
},
(err, operation, resp) => {
if (err) {
Expand Down Expand Up @@ -3511,7 +3514,7 @@ class Database extends common.GrpcServiceObject {
method: 'batchWrite',
reqOpts,
gaxOpts,
headers: this.resourceHeader_,
headers: this.commonHeaders_,
});
dataStream
.once('data', () => (dataReceived = true))
Expand Down Expand Up @@ -3793,7 +3796,7 @@ class Database extends common.GrpcServiceObject {
method: 'setIamPolicy',
reqOpts,
gaxOpts: gaxOpts,
headers: this.resourceHeader_,
headers: this.commonHeaders_,
},
(err, resp) => {
callback!(err, resp);
Expand Down Expand Up @@ -3923,7 +3926,7 @@ class Database extends common.GrpcServiceObject {
method: 'updateDatabaseDdl',
reqOpts,
gaxOpts,
headers: this.resourceHeader_,
headers: this.commonHeaders_,
},
callback!
);
Expand Down
Loading

0 comments on commit fb6a5bb

Please sign in to comment.