Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,15 @@ export class {{ service.name }}Client {
),
};
{%- endfor %}
{%- endif %}
{%- if api.enableTelemetryTracing %}

const internalTelemetryInfo = {
gcpClientService: '{{ api.loggingName }}',
gcpVersion: '{{ api.naming.version }}',
gcpRepo: 'googleapis/google-cloud-node',
gcpArtifact: '{{ api.publishName }}',
};
{%- endif %}

// Put together the default options sent with requests.
Expand All @@ -396,7 +405,7 @@ export class {{ service.name }}Client {
opts.clientConfig || {}, {'x-goog-api-client': clientHeader.join(' ')
{%- if service.apiVersion -%}
, 'x-goog-api-version': '{{ service.apiVersion }}'
{%- endif -%}});
{%- endif -%}}{% if api.enableTelemetryTracing %}, opts.enableTelemetryTracing, internalTelemetryInfo{% endif %});

// Set up a dictionary of "inner API calls"; the core implementation
// of calling the API is handled in `google-gax`, with this code
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,15 @@ export class {{ service.name }}Client {
),
};
{%- endfor %}
{%- endif %}
{%- if api.enableTelemetryTracing %}

const internalTelemetryInfo = {
gcpClientService: '{{ api.loggingName }}',
gcpVersion: '{{ api.naming.version }}',
gcpRepo: 'googleapis/google-cloud-node',
gcpArtifact: '{{ api.publishName }}',
};
{%- endif %}

// Put together the default options sent with requests.
Expand All @@ -407,7 +416,7 @@ export class {{ service.name }}Client {
opts.clientConfig || {}, {'x-goog-api-client': clientHeader.join(' ')
{%- if service.apiVersion -%}
, 'x-goog-api-version': '{{ service.apiVersion }}'
{%- endif %}});
{%- endif %}}{% if api.enableTelemetryTracing %}, opts.enableTelemetryTracing, internalTelemetryInfo{% endif %});

// Set up a dictionary of "inner API calls"; the core implementation
// of calling the API is handled in `google-gax`, with this code
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -300,10 +300,10 @@ apis:
{name: 'google/cloud/test/v1/test.proto'},
{name: 'google/cloud/test/v1/other.proto'},
],
} as unknown as protos.google.protobuf.compiler.CodeGeneratorRequest;
} as protos.google.protobuf.compiler.CodeGeneratorRequest;
generator.response = {
file: [],
} as unknown as protos.google.protobuf.compiler.CodeGeneratorResponse;
} as protos.google.protobuf.compiler.CodeGeneratorResponse;

getTestGenerator(generator).addProtosToResponse();

Expand Down Expand Up @@ -367,6 +367,192 @@ apis:
await generator.processTemplates(api);
}, /Template directory .* does not exist\./);
});

it('should generate telemetry tracing configuration in service client when enableTelemetryTracing is true (CJS)', async () => {
generator.request = {
protoFile: [
{
name: 'google/cloud/test/v1/test.proto',
package: 'google.cloud.test.v1',
messageType: [{name: 'TestRequest'}, {name: 'TestResponse'}],
service: [
{
name: 'TestService',
options: {
'.google.api.defaultHost': 'test.googleapis.com',
},
method: [
{
name: 'TestMethod',
inputType: '.google.cloud.test.v1.TestRequest',
outputType: '.google.cloud.test.v1.TestResponse',
},
],
},
],
},
],
fileToGenerate: ['google/cloud/test/v1/test.proto'],
} as protos.google.protobuf.compiler.CodeGeneratorRequest;
generator.templates = ['typescript_gapic'];
generator.enableTelemetryTracing = true;
generator.publishName = '@google-cloud/test';
generator.response = {
file: [],
} as protos.google.protobuf.compiler.CodeGeneratorResponse;

const api = getTestGenerator(generator).buildAPIObject();
await generator.processTemplates(api);

const clientFile = generator.response.file.find(f =>
f.name?.includes('test_service_client.ts'),
);
assert.ok(clientFile);
assert.ok(clientFile.content?.includes('internalTelemetryInfo'));
assert.ok(clientFile.content?.includes("gcpClientService: 'test',"));
assert.ok(clientFile.content?.includes("gcpVersion: 'v1',"));
assert.ok(
clientFile.content?.includes(
"gcpRepo: 'googleapis/google-cloud-node',",
),
);
assert.ok(
clientFile.content?.includes("gcpArtifact: '@google-cloud/test',"),
);
assert.ok(
/constructSettings\([\s\S]*opts\.enableTelemetryTracing[\s\S]*internalTelemetryInfo[\s\S]*\)/.test(
clientFile.content || '',
),
);
assert.strictEqual(
clientFile.content?.includes(
'this._defaults[methodName].enableTelemetryTracing',
),
false,
);
assert.strictEqual(
clientFile.content?.includes('this._defaults[methodName].otherArgs'),
false,
);
});

it('should generate telemetry tracing configuration in service client when enableTelemetryTracing is true (ESM)', async () => {
generator.request = {
protoFile: [
{
name: 'google/cloud/test/v1/test.proto',
package: 'google.cloud.test.v1',
messageType: [{name: 'TestRequest'}, {name: 'TestResponse'}],
service: [
{
name: 'TestService',
options: {
'.google.api.defaultHost': 'test.googleapis.com',
},
method: [
{
name: 'TestMethod',
inputType: '.google.cloud.test.v1.TestRequest',
outputType: '.google.cloud.test.v1.TestResponse',
},
],
},
],
},
],
fileToGenerate: ['google/cloud/test/v1/test.proto'],
} as protos.google.protobuf.compiler.CodeGeneratorRequest;
generator.templates = ['typescript_gapic'];
generator.format = ['esm'];
generator.enableTelemetryTracing = true;
generator.publishName = '@google-cloud/test';
generator.response = {
file: [],
} as protos.google.protobuf.compiler.CodeGeneratorResponse;

const api = getTestGenerator(generator).buildAPIObject();
await generator.processTemplates(api);

const clientFile = generator.response.file.find(f =>
f.name?.includes('test_service_client.ts'),
);
assert.ok(clientFile);
assert.ok(clientFile.content?.includes('internalTelemetryInfo'));
assert.ok(clientFile.content?.includes("gcpClientService: 'test',"));
assert.ok(clientFile.content?.includes("gcpVersion: 'v1',"));
assert.ok(
clientFile.content?.includes(
"gcpRepo: 'googleapis/google-cloud-node',",
),
);
assert.ok(
clientFile.content?.includes("gcpArtifact: '@google-cloud/test',"),
);
assert.ok(
/constructSettings\([\s\S]*opts\.enableTelemetryTracing[\s\S]*internalTelemetryInfo[\s\S]*\)/.test(
clientFile.content || '',
),
);
assert.strictEqual(
clientFile.content?.includes(
'this._defaults[methodName].enableTelemetryTracing',
),
false,
);
assert.strictEqual(
clientFile.content?.includes('this._defaults[methodName].otherArgs'),
false,
);
});

it('should not generate telemetry tracing configuration when enableTelemetryTracing is false', async () => {
generator.request = {
protoFile: [
{
name: 'google/cloud/test/v1/test.proto',
package: 'google.cloud.test.v1',
messageType: [{name: 'TestRequest'}, {name: 'TestResponse'}],
service: [
{
name: 'TestService',
options: {
'.google.api.defaultHost': 'test.googleapis.com',
},
method: [
{
name: 'TestMethod',
inputType: '.google.cloud.test.v1.TestRequest',
outputType: '.google.cloud.test.v1.TestResponse',
},
],
},
],
},
],
fileToGenerate: ['google/cloud/test/v1/test.proto'],
} as protos.google.protobuf.compiler.CodeGeneratorRequest;
generator.templates = ['typescript_gapic'];
generator.enableTelemetryTracing = false;
generator.response = {
file: [],
} as protos.google.protobuf.compiler.CodeGeneratorResponse;

const api = getTestGenerator(generator).buildAPIObject();
await generator.processTemplates(api);

const clientFile = generator.response.file.find(f =>
f.name?.includes('test_service_client.ts'),
);
assert.ok(clientFile);
assert.strictEqual(
clientFile.content?.includes('internalTelemetryInfo'),
false,
);
assert.strictEqual(
clientFile.content?.includes('opts.enableTelemetryTracing'),
false,
);
});
});

describe('generate', () => {
Expand All @@ -382,7 +568,7 @@ apis:
try {
generator.request = {
protoFile: [],
} as unknown as protos.google.protobuf.compiler.CodeGeneratorRequest;
} as protos.google.protobuf.compiler.CodeGeneratorRequest;

await generator.generate();

Expand Down
12 changes: 9 additions & 3 deletions core/packages/gax/src/fallback.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import * as fallbackRest from './fallbackRest';
import {isNodeJS} from './featureDetection';
import {generateServiceStub} from './fallbackServiceStub';
import {StreamType} from './streamingCalls/streaming';
import {toLowerCamelCase} from './util';
import {toLowerCamelCase, StaticTraceContext} from './util';
import {google} from '../protos/http';
import * as IamProtos from '../protos/iam_service';
import * as LocationProtos from '../protos/locations';
Expand Down Expand Up @@ -188,21 +188,25 @@ export class GrpcClient {

/**
* gRPC-fallback version of constructSettings
* A wrapper of {@link constructSettings} function under the gRPC context.
* A wrapper of {@link constructSettings} function under the gRPC-fallback context.
*
* Most of parameters are common among constructSettings, please take a look.
* @param {string} serviceName - The fullly-qualified name of the service.
* @param {string} serviceName - The fully-qualified name of the service.
* @param {Object} clientConfig - A dictionary of the client config.
* @param {Object} configOverrides - A dictionary of overriding configs.
* @param {Object} headers - A dictionary of additional HTTP header name to
* its value.
* @param {boolean} [enableTelemetryTracing] - Flag to enable telemetry tracing.
* @param {StaticTraceContext} [internalTelemetryInfo] - Static trace context for telemetry.
* @return {Object} A mapping of method names to CallSettings.
*/
constructSettings(
serviceName: string,
clientConfig: gax.ClientConfig,
configOverrides: gax.ClientConfig,
headers: OutgoingHttpHeaders,
enableTelemetryTracing?: boolean,
internalTelemetryInfo?: StaticTraceContext,
) {
function buildMetadata(abTests: {}, moreHeaders: OutgoingHttpHeaders) {
const metadata: OutgoingHttpHeaders = {};
Expand Down Expand Up @@ -267,6 +271,8 @@ export class GrpcClient {
configOverrides,
Status,
{metadataBuilder: buildMetadata},
enableTelemetryTracing,
internalTelemetryInfo,
);
}

Expand Down
13 changes: 10 additions & 3 deletions core/packages/gax/src/gax.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import type {Message} from 'protobufjs';
import {warn} from './warnings';
import {GoogleError} from './googleError';
import {BundleOptions} from './bundlingCalls/bundleExecutor';
import {toLowerCamelCase} from './util';
import {toLowerCamelCase, StaticTraceContext} from './util';
import {Status} from './status';
import {RequestType} from './apitypes';

Expand Down Expand Up @@ -788,8 +788,10 @@ export interface ClientConfig {
* @param {Object.<string, string[]>} retryNames - A dictionary mapping the strings
* referring to response status codes to objects representing
* those codes.
* @param {Object} otherArgs - the non-request arguments to be passed to the API
* @param {Object} [otherArgs] - the non-request arguments to be passed to the API
* calls.
* @param {boolean} [enableTelemetryTracing] - Flag to enable telemetry tracing.
* @param {StaticTraceContext} [internalTelemetryInfo] - Static trace context for telemetry.
* @return {Object} A mapping from method name to CallSettings, or null if the
* service is not found in the config.
*/
Expand All @@ -799,8 +801,12 @@ export function constructSettings(
configOverrides: ClientConfig,
retryNames: {},
otherArgs?: {},
enableTelemetryTracing?: boolean,
internalTelemetryInfo?: StaticTraceContext,
) {
otherArgs = otherArgs || {};
otherArgs = internalTelemetryInfo
? {...otherArgs, internalTelemetryInfo}
: otherArgs || {};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const defaults: any = {};

Expand Down Expand Up @@ -859,6 +865,7 @@ export function constructSettings(
: null,
otherArgs,
apiName,
enableTelemetryTracing,
});
}

Expand Down
9 changes: 8 additions & 1 deletion core/packages/gax/src/grpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import * as protobuf from 'protobufjs';
import objectHash from 'object-hash';

import * as gax from './gax';
import {StaticTraceContext} from './util';
import {ClientOptions} from '@grpc/grpc-js/build/src/client';

const googleProtoFilesDir = path.join(__dirname, '..', '..', 'build', 'protos');
Expand Down Expand Up @@ -370,25 +371,31 @@ export class GrpcClient {
* A wrapper of {@link constructSettings} function under the gRPC context.
*
* Most of parameters are common among constructSettings, please take a look.
* @param {string} serviceName - The fullly-qualified name of the service.
* @param {string} serviceName - The fully-qualified name of the service.
* @param {Object} clientConfig - A dictionary of the client config.
* @param {Object} configOverrides - A dictionary of overriding configs.
* @param {Object} headers - A dictionary of additional HTTP header name to
* its value.
* @param {boolean} [enableTelemetryTracing] - Flag to enable telemetry tracing.
* @param {StaticTraceContext} [internalTelemetryInfo] - Static trace context for telemetry.
* @return {Object} A mapping of method names to CallSettings.
*/
constructSettings(
serviceName: string,
clientConfig: gax.ClientConfig,
configOverrides: gax.ClientConfig,
headers: OutgoingHttpHeaders,
enableTelemetryTracing?: boolean,
internalTelemetryInfo?: StaticTraceContext,
) {
return gax.constructSettings(
serviceName,
clientConfig,
configOverrides,
this.grpc.status,
{metadataBuilder: this.metadataBuilder(headers)},
enableTelemetryTracing,
internalTelemetryInfo,
);
}

Expand Down
Loading
Loading