Skip to content

Commit

Permalink
Restrict attributes interfaces and solve compile
Browse files Browse the repository at this point in the history
  • Loading branch information
danieljbruce committed Jan 24, 2025
1 parent b8dff1c commit d50384f
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 187 deletions.
53 changes: 45 additions & 8 deletions common/client-side-metrics-attributes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,57 @@
// See the License for the specific language governing permissions and
// limitations under the License.

/**
* Attributes (labels) associated with a Bigtable metric. These
* attributes provide context for the metric values.
*/
export interface Attributes {
interface StandardAttributes {
projectId: string;
instanceId: string;
table: string;
cluster?: string | null;
zone?: string | null;
appProfileId?: string;
methodName: string;
attemptStatus?: string;
finalOperationStatus?: string;
streamingOperation?: string;
clientName: string;
}

/**
* Information about a Bigtable operation.
*/
export interface OperationOnlyAttributes {
/**
* The final status of the operation (e.g., 'OK', 'ERROR').
*/
finalOperationStatus: string;
streamingOperation: string;
}

/**
* Information about a single attempt of a Bigtable operation.
*/
export interface AttemptOnlyAttributes {
/**
* The final status of the operation (e.g., 'OK', 'ERROR').
*/
finalOperationStatus: string; // TODO: enum
/**
* Whether the operation is a streaming operation or not.
*/
streamingOperation: string; // TODO: enum
/**
* The attempt status of the operation.
*/
attemptStatus: string; // TODO: enum
}

export interface OnOperationCompleteAttributes
extends StandardAttributes,
OperationOnlyAttributes {
finalOperationStatus: string;
streamingOperation: string;
}

export interface OnAttemptCompleteAttributes
extends StandardAttributes,
AttemptOnlyAttributes {
attemptStatus: string;
finalOperationStatus: string;
streamingOperation: string;
}
19 changes: 11 additions & 8 deletions common/test-metrics-handler.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import {WithLogger} from './logger';
import {
onAttemptCompleteMetrics,
onOperationCompleteMetrics,
OnAttemptCompleteMetrics,
OnOperationCompleteMetrics,
} from '../src/client-side-metrics/metrics-handler';
import {Attributes} from './client-side-metrics-attributes';
import {OnAttemptCompleteAttributes, OnOperationCompleteAttributes} from './client-side-metrics-attributes';

Check failure on line 6 in common/test-metrics-handler.ts

View workflow job for this annotation

GitHub Actions / lint

Replace `OnAttemptCompleteAttributes,·OnOperationCompleteAttributes` with `⏎··OnAttemptCompleteAttributes,⏎··OnOperationCompleteAttributes,⏎`

/**
* A test implementation of the IMetricsHandler interface. Used for testing purposes.
Expand All @@ -12,12 +12,12 @@ import {Attributes} from './client-side-metrics-attributes';
export class TestMetricsHandler extends WithLogger {
/**
* Logs the metrics and attributes received for an operation completion.
* @param {onOperationCompleteMetrics} metrics Metrics related to the completed operation.
* @param {OnOperationCompleteMetrics} metrics Metrics related to the completed operation.
* @param {Attributes} attributes Attributes associated with the completed operation.
*/
onOperationComplete(
metrics: onOperationCompleteMetrics,
attributes: Attributes
metrics: OnOperationCompleteMetrics,
attributes: OnOperationCompleteAttributes
) {
attributes.clientName = 'nodejs-bigtable';
this.logger.log('Recording parameters for onOperationComplete:');
Expand All @@ -27,10 +27,13 @@ export class TestMetricsHandler extends WithLogger {

/**
* Logs the metrics and attributes received for an attempt completion.
* @param {onAttemptCompleteMetrics} metrics Metrics related to the completed attempt.
* @param {OnAttemptCompleteMetrics} metrics Metrics related to the completed attempt.
* @param {Attributes} attributes Attributes associated with the completed attempt.
*/
onAttemptComplete(metrics: onAttemptCompleteMetrics, attributes: Attributes) {
onAttemptComplete(
metrics: OnAttemptCompleteMetrics,
attributes: OnAttemptCompleteAttributes
) {
attributes.clientName = 'nodejs-bigtable';
this.logger.log('Recording parameters for onAttemptComplete:');
this.logger.log(`metrics: ${JSON.stringify(metrics)}`);
Expand Down
23 changes: 13 additions & 10 deletions src/client-side-metrics/gcp-metrics-handler.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import {
IMetricsHandler,
onAttemptCompleteMetrics,
onOperationCompleteMetrics,
OnAttemptCompleteMetrics,
OnOperationCompleteMetrics,
} from './metrics-handler';
import * as Resources from '@opentelemetry/resources';
import * as ResourceUtil from '@google-cloud/opentelemetry-resource-util';
import {MetricExporter} from '@google-cloud/opentelemetry-cloud-monitoring-exporter';
import {Attributes} from '../../common/client-side-metrics-attributes';
import {OnAttemptCompleteAttributes, OnOperationCompleteAttributes} from '../../common/client-side-metrics-attributes';

Check failure on line 9 in src/client-side-metrics/gcp-metrics-handler.ts

View workflow job for this annotation

GitHub Actions / lint

Replace `OnAttemptCompleteAttributes,·OnOperationCompleteAttributes` with `⏎··OnAttemptCompleteAttributes,⏎··OnOperationCompleteAttributes,⏎`
const {
MeterProvider,
Histogram,
Expand Down Expand Up @@ -128,12 +128,12 @@ export class GCPMetricsHandler implements IMetricsHandler {
/**
* Records metrics for a completed Bigtable operation.
* This method records the operation latency and retry count, associating them with provided attributes.
* @param {onOperationCompleteMetrics} metrics Metrics related to the completed operation.
* @param {Attributes} attributes Attributes associated with the completed operation.
* @param {OnOperationCompleteMetrics} metrics Metrics related to the completed operation.
* @param {OnOperationCompleteAttributes} attributes Attributes associated with the completed operation.
*/
onOperationComplete(
metrics: onOperationCompleteMetrics,
attributes: Attributes
metrics: OnOperationCompleteMetrics,
attributes: OnOperationCompleteAttributes
) {
this.initialize();
this.otelMetrics?.operationLatencies.record(
Expand All @@ -147,10 +147,13 @@ export class GCPMetricsHandler implements IMetricsHandler {
* Records metrics for a completed attempt of a Bigtable operation.
* This method records attempt latency, connectivity error count, server latency, and first response latency,
* along with the provided attributes.
* @param {onAttemptCompleteMetrics} metrics Metrics related to the completed attempt.
* @param {Attributes} attributes Attributes associated with the completed attempt.
* @param {OnAttemptCompleteMetrics} metrics Metrics related to the completed attempt.
* @param {OnAttemptCompleteAttributes} attributes Attributes associated with the completed attempt.
*/
onAttemptComplete(metrics: onAttemptCompleteMetrics, attributes: Attributes) {
onAttemptComplete(
metrics: OnAttemptCompleteMetrics,
attributes: OnAttemptCompleteAttributes
) {
this.initialize();
this.otelMetrics?.attemptLatencies.record(
metrics.attemptLatency,
Expand Down
84 changes: 21 additions & 63 deletions src/client-side-metrics/metrics-collector.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import {Attributes} from '../../common/client-side-metrics-attributes';
import * as fs from 'fs';
import {IMetricsHandler} from './metrics-handler';
import {
AttemptOnlyAttributes,
OnOperationCompleteAttributes,
OperationOnlyAttributes,
} from '../../common/client-side-metrics-attributes';

/**
* An interface representing a Date-like object. Provides a `getTime` method
Expand Down Expand Up @@ -52,35 +56,6 @@ export interface ITabularApiSurface {
};
}

/**
* Information about a Bigtable operation.
*/
interface OperationInfo {
/**
* The final status of the operation (e.g., 'OK', 'ERROR').
*/
finalOperationStatus: string;
/**
* Number of times a connectivity error occurred during the operation.
*/
connectivityErrorCount?: number;
streamingOperation: string;
}

/**
* Information about a single attempt of a Bigtable operation.
*/
interface AttemptInfo {
/**
* The final status of the attempt (e.g., 'OK', 'ERROR').
*/
finalOperationStatus: string;
/**
* Whether the operation is a streaming operation or not
*/
streamingOperation: string;
}

const packageJSON = fs.readFileSync('package.json');
const version = JSON.parse(packageJSON.toString()).version;

Expand Down Expand Up @@ -160,20 +135,15 @@ export class MetricsCollector {
* provide context about the Bigtable environment, the operation being performed, and the final status of the operation.
* Includes whether the operation was a streaming operation or not.
* @param {string} projectId The Google Cloud project ID.
* @param {string} finalOperationStatus The final status of the operation.
* @param {string} streamOperation Whether the operation was a streaming operation or not.
* @returns {Attributes} An object containing the attributes for operation latency metrics.
* @param {OperationOnlyAttributes} operationOnlyAttributes The attributes of the operation.
* @returns {OnOperationCompleteAttributes} An object containing the attributes for operation latency metrics.
*/
private getOperationLatencyAttributes(
projectId: string,
finalOperationStatus: string,
streamOperation?: string
): Attributes {
operationOnlyAttributes: OperationOnlyAttributes
): OnOperationCompleteAttributes {
return Object.assign(
{
finalOperationStatus: finalOperationStatus,
streamingOperation: streamOperation,
},
operationOnlyAttributes,
this.getBasicAttributes(projectId)
);
}
Expand All @@ -183,20 +153,15 @@ export class MetricsCollector {
* about the Bigtable environment, the operation being performed, and the status of the attempt.
* Includes whether the operation was a streaming operation or not.
* @param {string} projectId The Google Cloud project ID.
* @param {string} attemptStatus The status of the attempt.
* @param {string} streamingOperation Whether the operation was a streaming operation or not.
* @returns {Attributes} An object containing the attributes for attempt metrics.
* @param {AttemptOnlyAttributes} attemptOnlyAttributes The attributes of the attempt.
* @returns {OnAttemptCompleteAttributes} An object containing the attributes for attempt metrics.
*/
private getAttemptAttributes(
projectId: string,
attemptStatus: string,
streamingOperation: string
attemptOnlyAttributes: AttemptOnlyAttributes
) {
return Object.assign(
{
attemptStatus: attemptStatus,
streamingOperation: streamingOperation,
},
attemptOnlyAttributes,
this.getBasicAttributes(projectId)
);
}
Expand All @@ -210,18 +175,14 @@ export class MetricsCollector {

/**
* Called when an attempt (e.g., an RPC attempt) completes. Records attempt latencies.
* @param {AttemptInfo} info Information about the completed attempt.
* @param {AttemptOnlyAttributes} info Information about the completed attempt.
*/
onAttemptComplete(info: AttemptInfo) {
onAttemptComplete(info: AttemptOnlyAttributes) {
this.attemptCount++;
const endTime = this.dateProvider.getDate();
const projectId = this.projectId;
if (projectId && this.attemptStartTime) {
const attributes = this.getAttemptAttributes(
projectId,
info.finalOperationStatus,
info.streamingOperation
);
const attributes = this.getAttemptAttributes(projectId, info);
const totalTime = endTime.getTime() - this.attemptStartTime.getTime();
this.metricsHandlers.forEach(metricsHandler => {
if (metricsHandler.onAttemptComplete) {
Expand Down Expand Up @@ -267,26 +228,23 @@ export class MetricsCollector {
/**
* Called when an operation completes (successfully or unsuccessfully).
* Records operation latencies, retry counts, and connectivity error counts.
* @param {OperationInfo} info Information about the completed operation.
* @param {OperationOnlyAttributes} info Information about the completed operation.
*/
onOperationComplete(info: OperationInfo) {
onOperationComplete(info: OperationOnlyAttributes) {
const endTime = this.dateProvider.getDate();
const projectId = this.projectId;
this.onAttemptComplete(info);
if (projectId && this.operationStartTime) {
const totalTime = endTime.getTime() - this.operationStartTime.getTime();
{
// This block records operation latency metrics.
const operationLatencyAttributes = this.getOperationLatencyAttributes(
projectId,
info.finalOperationStatus,
info.streamingOperation
info
);
const metrics = {
operationLatency: totalTime,
firstResponseLatency: this.firstResponseLatency,
retryCount: this.attemptCount - 1,
connectivityErrorCount: info.connectivityErrorCount,
};
this.metricsHandlers.forEach(metricsHandler => {
if (metricsHandler.onOperationComplete) {
Expand All @@ -302,7 +260,7 @@ export class MetricsCollector {

/**
* Called when metadata is received. Extracts server timing information if available.
* @param {AttemptInfo} info Information about the completed attempt.
* @param {AttemptOnlyAttributes} info Information about the completed attempt.
* @param {object} metadata The received metadata.
*/
onMetadataReceived(metadata: {
Expand Down
25 changes: 14 additions & 11 deletions src/client-side-metrics/metrics-handler.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
import {Attributes} from '../../common/client-side-metrics-attributes';
import {
OnAttemptCompleteAttributes,
OnOperationCompleteAttributes,
} from '../../common/client-side-metrics-attributes';

/**
* Metrics related to the completion of a Bigtable operation.
*/
export interface onOperationCompleteMetrics {
export interface OnOperationCompleteMetrics {
operationLatency: number;
retryCount?: number;
}

/**
* Metrics related to the completion of a single attempt of a Bigtable operation.
*/
export interface onAttemptCompleteMetrics {
export interface OnAttemptCompleteMetrics {
attemptLatency: number;
serverLatency?: number;
firstResponseLatency?: number;
Expand All @@ -26,20 +29,20 @@ export interface onAttemptCompleteMetrics {
export interface IMetricsHandler {
/**
* Called when an operation completes (successfully or unsuccessfully).
* @param {onOperationCompleteMetrics} metrics Metrics related to the completed operation.
* @param {Attributes} attributes Attributes associated with the completed operation.
* @param {OnOperationCompleteMetrics} metrics Metrics related to the completed operation.
* @param {OnOperationCompleteAttributes} attributes Attributes associated with the completed operation.
*/
onOperationComplete?(
metrics: onOperationCompleteMetrics,
attributes: Attributes
metrics: OnOperationCompleteMetrics,
attributes: OnOperationCompleteAttributes
): void;
/**
* Called when an attempt (e.g., an RPC attempt) completes.
* @param {onAttemptCompleteMetrics} metrics Metrics related to the completed attempt.
* @param {Attributes} attributes Attributes associated with the completed attempt.
* @param {OnAttemptCompleteMetrics} metrics Metrics related to the completed attempt.
* @param {OnAttemptCompleteAttributes} attributes Attributes associated with the completed attempt.
*/
onAttemptComplete?(
metrics: onAttemptCompleteMetrics,
attributes: Attributes
metrics: OnAttemptCompleteMetrics,
attributes: OnAttemptCompleteAttributes
): void;
}
Loading

0 comments on commit d50384f

Please sign in to comment.