-
Notifications
You must be signed in to change notification settings - Fork 93
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add built in metrics measure and views
- Loading branch information
Showing
8 changed files
with
1,110 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
92 changes: 92 additions & 0 deletions
92
...bigtable-stats/src/main/java/com/google/cloud/bigtable/stats/BuiltinMeasureConstants.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
/* | ||
* Copyright 2022 Google LLC | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package com.google.cloud.bigtable.stats; | ||
|
||
import static io.opencensus.stats.Measure.MeasureLong; | ||
|
||
import com.google.api.core.InternalApi; | ||
import io.opencensus.tags.TagKey; | ||
|
||
@InternalApi("For internal use only") | ||
public class BuiltinMeasureConstants { | ||
// TagKeys | ||
public static final TagKey PROJECT_ID = TagKey.create("project_id"); | ||
public static final TagKey INSTANCE_ID = TagKey.create("instance_id"); | ||
public static final TagKey APP_PROFILE = TagKey.create("app_profile"); | ||
public static final TagKey METHOD = TagKey.create("method"); | ||
public static final TagKey STREAMING = TagKey.create("streaming"); | ||
public static final TagKey STATUS = TagKey.create("status"); | ||
public static final TagKey CLIENT_NAME = TagKey.create("client_name"); | ||
public static final TagKey CLIENT_ID = TagKey.create("client_id"); | ||
|
||
// Monitored resource TagKeys | ||
public static final TagKey TABLE = TagKey.create("table"); | ||
public static final TagKey CLUSTER = TagKey.create("cluster"); | ||
public static final TagKey ZONE = TagKey.create("zone"); | ||
|
||
// Units | ||
private static final String COUNT = "1"; | ||
private static final String MILLISECOND = "ms"; | ||
|
||
// Measurements | ||
static final MeasureLong OPERATION_LATENCIES = | ||
MeasureLong.create( | ||
"bigtable.googleapis.com/internal/client/operation_latencies", | ||
"Total time until final operation success or failure, including retries and backoff.", | ||
MILLISECOND); | ||
|
||
static final MeasureLong ATTEMPT_LATENCIES = | ||
MeasureLong.create( | ||
"bigtable.googleapis.com/internal/client/attempt_latencies", | ||
"Client observed latency per RPC attempt.", | ||
MILLISECOND); | ||
|
||
static final MeasureLong RETRY_COUNT = | ||
MeasureLong.create( | ||
"bigtable.googleapis.com/internal/client/retry_count", | ||
"The number of additional RPCs sent after the initial attempt.", | ||
COUNT); | ||
|
||
static final MeasureLong FIRST_RESPONSE_LATENCIES = | ||
MeasureLong.create( | ||
"bigtable.googleapis.com/internal/client/first_response_latencies", | ||
"Latency from operation start until the response headers were received. The publishing of the measurement will be delayed until the attempt response has been received.", | ||
MILLISECOND); | ||
|
||
static final MeasureLong SERVER_LATENCIES = | ||
MeasureLong.create( | ||
"bigtable.googleapis.com/internal/client/server_latencies", | ||
"The latency measured from the moment that the RPC entered the Google data center until the RPC was completed.", | ||
MILLISECOND); | ||
|
||
static final MeasureLong CONNECTIVITY_ERROR_COUNT = | ||
MeasureLong.create( | ||
"bigtable.googleapis.com/internal/client/connectivity_error_count", | ||
"Number of requests that failed to reach the Google datacenter. (Requests without google response headers).", | ||
COUNT); | ||
|
||
static final MeasureLong APPLICATION_LATENCIES = | ||
MeasureLong.create( | ||
"bigtable.googleapis.com/internal/client/application_latencies", | ||
"The latency of the client application consuming available response data.", | ||
MILLISECOND); | ||
|
||
static final MeasureLong THROTTLING_LATENCIES = | ||
MeasureLong.create( | ||
"bigtable.googleapis.com/internal/client/throttling_latencies", | ||
"The artificial latency introduced by the client to limit the number of outstanding requests. The publishing of the measurement will be delayed until the attempt trailers have been received.", | ||
MILLISECOND); | ||
} |
170 changes: 170 additions & 0 deletions
170
...-bigtable-stats/src/main/java/com/google/cloud/bigtable/stats/BuiltinMetricsRecorder.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
/* | ||
* Copyright 2022 Google LLC | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package com.google.cloud.bigtable.stats; | ||
|
||
import com.google.api.core.InternalApi; | ||
import com.google.api.gax.tracing.ApiTracerFactory.OperationType; | ||
import com.google.api.gax.tracing.SpanName; | ||
import io.opencensus.stats.MeasureMap; | ||
import io.opencensus.stats.StatsRecorder; | ||
import io.opencensus.tags.TagContext; | ||
import io.opencensus.tags.TagContextBuilder; | ||
import io.opencensus.tags.TagKey; | ||
import io.opencensus.tags.TagValue; | ||
import io.opencensus.tags.Tagger; | ||
import io.opencensus.tags.Tags; | ||
import java.util.Map; | ||
|
||
/** Add built-in metrics to the measure map * */ | ||
@InternalApi("For internal use only") | ||
public class BuiltinMetricsRecorder { | ||
|
||
private final OperationType operationType; | ||
|
||
private final Tagger tagger; | ||
private final StatsRecorder statsRecorder; | ||
private final TagContext parentContext; | ||
private final SpanName spanName; | ||
private final Map<String, String> statsAttributes; | ||
|
||
private MeasureMap attemptLevelNoStreaming; | ||
private MeasureMap attemptLevelWithStreaming; | ||
private MeasureMap operationLevelNoStreaming; | ||
private MeasureMap operationLevelWithStreaming; | ||
|
||
public BuiltinMetricsRecorder( | ||
OperationType operationType, | ||
SpanName spanName, | ||
Map<String, String> statsAttributes, | ||
StatsWrapper builtinMetricsWrapper) { | ||
this.operationType = operationType; | ||
this.tagger = Tags.getTagger(); | ||
this.statsRecorder = builtinMetricsWrapper.getStatsRecorder(); | ||
this.spanName = spanName; | ||
this.parentContext = tagger.getCurrentTagContext(); | ||
this.statsAttributes = statsAttributes; | ||
|
||
this.attemptLevelNoStreaming = statsRecorder.newMeasureMap(); | ||
this.attemptLevelWithStreaming = statsRecorder.newMeasureMap(); | ||
this.operationLevelNoStreaming = statsRecorder.newMeasureMap(); | ||
this.operationLevelWithStreaming = statsRecorder.newMeasureMap(); | ||
} | ||
|
||
public void recordAttemptLevelWithoutStreaming( | ||
String status, String tableId, String zone, String cluster) { | ||
TagContextBuilder tagCtx = | ||
newTagContextBuilder(tableId, zone, cluster) | ||
.putLocal(BuiltinMeasureConstants.STATUS, TagValue.create(status)); | ||
|
||
attemptLevelNoStreaming.record(tagCtx.build()); | ||
} | ||
|
||
public void recordAttemptLevelWithStreaming( | ||
String status, String tableId, String zone, String cluster) { | ||
TagContextBuilder tagCtx = | ||
newTagContextBuilder(tableId, zone, cluster) | ||
.putLocal(BuiltinMeasureConstants.STATUS, TagValue.create(status)); | ||
|
||
if (operationType == OperationType.ServerStreaming | ||
&& spanName.getMethodName().equals("ReadRows")) { | ||
tagCtx.putLocal(BuiltinMeasureConstants.STREAMING, TagValue.create("true")); | ||
} else { | ||
tagCtx.putLocal(BuiltinMeasureConstants.STREAMING, TagValue.create("false")); | ||
} | ||
|
||
attemptLevelWithStreaming.record(tagCtx.build()); | ||
} | ||
|
||
public void recordOperationLevelWithoutStreaming( | ||
String status, String tableId, String zone, String cluster) { | ||
TagContextBuilder tagCtx = | ||
newTagContextBuilder(tableId, zone, cluster) | ||
.putLocal(BuiltinMeasureConstants.STATUS, TagValue.create(status)); | ||
|
||
operationLevelNoStreaming.record(tagCtx.build()); | ||
} | ||
|
||
public void recordOperationLevelWithStreaming( | ||
String status, String tableId, String zone, String cluster) { | ||
TagContextBuilder tagCtx = | ||
newTagContextBuilder(tableId, zone, cluster) | ||
.putLocal(BuiltinMeasureConstants.STATUS, TagValue.create(status)); | ||
|
||
if (operationType == OperationType.ServerStreaming | ||
&& spanName.getMethodName().equals("ReadRows")) { | ||
tagCtx.putLocal(BuiltinMeasureConstants.STREAMING, TagValue.create("true")); | ||
} else { | ||
tagCtx.putLocal(BuiltinMeasureConstants.STREAMING, TagValue.create("false")); | ||
} | ||
|
||
operationLevelWithStreaming.record(tagCtx.build()); | ||
} | ||
|
||
public void recordOperationLatencies(long operationLatency) { | ||
operationLevelWithStreaming.put(BuiltinMeasureConstants.OPERATION_LATENCIES, operationLatency); | ||
} | ||
|
||
public void recordAttemptLatency(long attemptLatency) { | ||
attemptLevelWithStreaming.put(BuiltinMeasureConstants.ATTEMPT_LATENCIES, attemptLatency); | ||
} | ||
|
||
public void recordRetryCount(int attemptCount) { | ||
operationLevelNoStreaming.put(BuiltinMeasureConstants.RETRY_COUNT, attemptCount); | ||
} | ||
|
||
public void recordApplicationLatency(long applicationLatency) { | ||
operationLevelWithStreaming.put( | ||
BuiltinMeasureConstants.APPLICATION_LATENCIES, applicationLatency); | ||
} | ||
|
||
public void recordFirstResponseLatency(long firstResponseLatency) { | ||
operationLevelNoStreaming.put( | ||
BuiltinMeasureConstants.FIRST_RESPONSE_LATENCIES, firstResponseLatency); | ||
} | ||
|
||
public void recordGfeLatencies(long serverLatency) { | ||
attemptLevelWithStreaming.put(BuiltinMeasureConstants.SERVER_LATENCIES, serverLatency); | ||
} | ||
|
||
public void recordGfeMissingHeaders(long connectivityErrors) { | ||
attemptLevelNoStreaming.put( | ||
BuiltinMeasureConstants.CONNECTIVITY_ERROR_COUNT, connectivityErrors); | ||
} | ||
|
||
public void recordBatchRequestThrottled( | ||
long throttledTimeMs, String tableId, String zone, String cluster) { | ||
MeasureMap measures = | ||
statsRecorder | ||
.newMeasureMap() | ||
.put(BuiltinMeasureConstants.THROTTLING_LATENCIES, throttledTimeMs); | ||
measures.record(newTagContextBuilder(tableId, zone, cluster).build()); | ||
} | ||
|
||
private TagContextBuilder newTagContextBuilder(String tableId, String zone, String cluster) { | ||
TagContextBuilder tagContextBuilder = | ||
tagger | ||
.toBuilder(parentContext) | ||
.putLocal(BuiltinMeasureConstants.CLIENT_NAME, TagValue.create("bigtable-java")) | ||
.putLocal(BuiltinMeasureConstants.METHOD, TagValue.create(spanName.toString())) | ||
.putLocal(BuiltinMeasureConstants.TABLE, TagValue.create(tableId)) | ||
.putLocal(BuiltinMeasureConstants.ZONE, TagValue.create(zone)) | ||
.putLocal(BuiltinMeasureConstants.CLUSTER, TagValue.create(cluster)); | ||
for (Map.Entry<String, String> entry : statsAttributes.entrySet()) { | ||
tagContextBuilder.putLocal(TagKey.create(entry.getKey()), TagValue.create(entry.getValue())); | ||
} | ||
return tagContextBuilder; | ||
} | ||
} |
Oops, something went wrong.