diff --git a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/BucketEndpoint.java b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/BucketEndpoint.java index 81a1cea265df..095b160c8e56 100644 --- a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/BucketEndpoint.java +++ b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/BucketEndpoint.java @@ -40,6 +40,7 @@ import org.apache.hadoop.ozone.s3.util.ContinueToken; import org.apache.hadoop.ozone.s3.util.S3StorageType; import org.apache.hadoop.ozone.security.acl.IAccessAuthorizer; +import org.apache.hadoop.util.Time; import org.apache.http.HttpStatus; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -102,6 +103,7 @@ public Response get( @QueryParam("uploads") String uploads, @QueryParam("acl") String aclMarker, @Context HttpHeaders hh) throws OS3Exception, IOException { + long startNanos = Time.monotonicNowNanos(); S3GAction s3GAction = S3GAction.GET_BUCKET; Iterator ozoneKeyIterator; ContinueToken decodedToken = @@ -111,7 +113,7 @@ public Response get( if (aclMarker != null) { s3GAction = S3GAction.GET_ACL; S3BucketAcl result = getAcl(bucketName); - getMetrics().incGetAclSuccess(); + getMetrics().updateGetAclSuccessStats(startNanos); AUDIT.logReadSuccess( buildAuditMessageForSuccess(s3GAction, getAuditParameters())); return Response.ok(result, MediaType.APPLICATION_XML_TYPE).build(); @@ -130,7 +132,7 @@ public Response get( if (startAfter == null && marker != null) { startAfter = marker; } - + OzoneBucket bucket = getBucket(bucketName); if (startAfter != null && continueToken != null) { // If continuation token and start after both are provided, then we @@ -146,14 +148,14 @@ public Response get( } catch (OMException ex) { AUDIT.logReadFailure( buildAuditMessageForFailure(s3GAction, getAuditParameters(), ex)); - getMetrics().incGetBucketFailure(); + getMetrics().updateGetBucketFailureStats(startNanos); if (isAccessDenied(ex)) { throw newError(S3ErrorTable.ACCESS_DENIED, bucketName, ex); } else { throw ex; } } catch (Exception ex) { - getMetrics().incGetBucketFailure(); + getMetrics().updateGetBucketFailureStats(startNanos); AUDIT.logReadFailure( buildAuditMessageForFailure(s3GAction, getAuditParameters(), ex)); throw ex; @@ -247,7 +249,7 @@ public Response get( AUDIT.logReadSuccess(buildAuditMessageForSuccess(s3GAction, getAuditParameters())); - getMetrics().incGetBucketSuccess(); + getMetrics().updateGetBucketSuccessStats(startNanos); response.setKeyCount( response.getCommonPrefixes().size() + response.getContents().size()); return Response.ok(response).build(); @@ -258,6 +260,7 @@ public Response put(@PathParam("bucket") String bucketName, @QueryParam("acl") String aclMarker, @Context HttpHeaders httpHeaders, InputStream body) throws IOException, OS3Exception { + long startNanos = Time.monotonicNowNanos(); S3GAction s3GAction = S3GAction.CREATE_BUCKET; try { @@ -271,12 +274,12 @@ public Response put(@PathParam("bucket") String bucketName, String location = createS3Bucket(bucketName); AUDIT.logWriteSuccess( buildAuditMessageForSuccess(s3GAction, getAuditParameters())); - getMetrics().incCreateBucketSuccess(); + getMetrics().updateCreateBucketSuccessStats(startNanos); return Response.status(HttpStatus.SC_OK).header("Location", location) .build(); } catch (OMException exception) { auditWriteFailure(s3GAction, exception); - getMetrics().incCreateBucketFailure(); + getMetrics().updateCreateBucketFailureStats(startNanos); if (exception.getResult() == ResultCodes.INVALID_BUCKET_NAME) { throw newError(S3ErrorTable.INVALID_BUCKET_NAME, bucketName, exception); } @@ -292,6 +295,7 @@ public Response listMultipartUploads( @PathParam("bucket") String bucketName, @QueryParam("prefix") String prefix) throws OS3Exception, IOException { + long startNanos = Time.monotonicNowNanos(); S3GAction s3GAction = S3GAction.LIST_MULTIPART_UPLOAD; OzoneBucket bucket = getBucket(bucketName); @@ -312,13 +316,13 @@ public Response listMultipartUploads( ))); AUDIT.logReadSuccess(buildAuditMessageForSuccess(s3GAction, getAuditParameters())); - getMetrics().incListMultipartUploadsSuccess(); + getMetrics().updateListMultipartUploadsSuccessStats(startNanos); return Response.ok(result).build(); } catch (OMException exception) { AUDIT.logReadFailure( buildAuditMessageForFailure(s3GAction, getAuditParameters(), exception)); - getMetrics().incListMultipartUploadsFailure(); + getMetrics().updateListMultipartUploadsFailureStats(startNanos); if (isAccessDenied(exception)) { throw newError(S3ErrorTable.ACCESS_DENIED, prefix, exception); } @@ -339,12 +343,13 @@ public Response listMultipartUploads( @HEAD public Response head(@PathParam("bucket") String bucketName) throws OS3Exception, IOException { + long startNanos = Time.monotonicNowNanos(); S3GAction s3GAction = S3GAction.HEAD_BUCKET; try { getBucket(bucketName); AUDIT.logReadSuccess( buildAuditMessageForSuccess(s3GAction, getAuditParameters())); - getMetrics().incHeadBucketSuccess(); + getMetrics().updateHeadBucketSuccessStats(startNanos); return Response.ok().build(); } catch (Exception e) { AUDIT.logReadFailure( @@ -362,6 +367,7 @@ public Response head(@PathParam("bucket") String bucketName) @DELETE public Response delete(@PathParam("bucket") String bucketName) throws IOException, OS3Exception { + long startNanos = Time.monotonicNowNanos(); S3GAction s3GAction = S3GAction.DELETE_BUCKET; try { @@ -369,7 +375,7 @@ public Response delete(@PathParam("bucket") String bucketName) } catch (OMException ex) { AUDIT.logWriteFailure( buildAuditMessageForFailure(s3GAction, getAuditParameters(), ex)); - getMetrics().incDeleteBucketFailure(); + getMetrics().updateDeleteBucketFailureStats(startNanos); if (ex.getResult() == ResultCodes.BUCKET_NOT_EMPTY) { throw newError(S3ErrorTable.BUCKET_NOT_EMPTY, bucketName, ex); } else if (ex.getResult() == ResultCodes.BUCKET_NOT_FOUND) { @@ -387,7 +393,7 @@ public Response delete(@PathParam("bucket") String bucketName) AUDIT.logWriteSuccess(buildAuditMessageForSuccess(s3GAction, getAuditParameters())); - getMetrics().incDeleteBucketSuccess(); + getMetrics().updateDeleteBucketSuccessStats(startNanos); return Response .status(HttpStatus.SC_NO_CONTENT) .build(); @@ -454,6 +460,7 @@ public MultiDeleteResponse multiDelete(@PathParam("bucket") String bucketName, */ public S3BucketAcl getAcl(String bucketName) throws OS3Exception, IOException { + long startNanos = Time.monotonicNowNanos(); S3BucketAcl result = new S3BucketAcl(); try { OzoneBucket bucket = getBucket(bucketName); @@ -478,7 +485,7 @@ public S3BucketAcl getAcl(String bucketName) new S3BucketAcl.AccessControlList(grantList)); return result; } catch (OMException ex) { - getMetrics().incGetAclFailure(); + getMetrics().updateGetAclFailureStats(startNanos); auditReadFailure(S3GAction.GET_ACL, ex); if (ex.getResult() == ResultCodes.BUCKET_NOT_FOUND) { throw newError(S3ErrorTable.NO_SUCH_BUCKET, bucketName, ex); @@ -488,7 +495,7 @@ public S3BucketAcl getAcl(String bucketName) throw newError(S3ErrorTable.INTERNAL_ERROR, bucketName, ex); } } catch (OS3Exception ex) { - getMetrics().incGetAclFailure(); + getMetrics().updateGetAclFailureStats(startNanos); throw ex; } } @@ -500,6 +507,7 @@ public S3BucketAcl getAcl(String bucketName) */ public Response putAcl(String bucketName, HttpHeaders httpHeaders, InputStream body) throws IOException, OS3Exception { + long startNanos = Time.monotonicNowNanos(); String grantReads = httpHeaders.getHeaderString(S3Acl.GRANT_READ); String grantWrites = httpHeaders.getHeaderString(S3Acl.GRANT_WRITE); String grantReadACP = httpHeaders.getHeaderString(S3Acl.GRANT_READ_CAP); @@ -580,7 +588,7 @@ public Response putAcl(String bucketName, HttpHeaders httpHeaders, volume.addAcl(acl); } } catch (OMException exception) { - getMetrics().incPutAclFailure(); + getMetrics().updatePutAclFailureStats(startNanos); auditWriteFailure(S3GAction.PUT_ACL, exception); if (exception.getResult() == ResultCodes.BUCKET_NOT_FOUND) { throw newError(S3ErrorTable.NO_SUCH_BUCKET, bucketName, exception); @@ -589,10 +597,10 @@ public Response putAcl(String bucketName, HttpHeaders httpHeaders, } throw exception; } catch (OS3Exception ex) { - getMetrics().incPutAclFailure(); + getMetrics().updatePutAclFailureStats(startNanos); throw ex; } - getMetrics().incPutAclSuccess(); + getMetrics().updatePutAclSuccessStats(startNanos); return Response.status(HttpStatus.SC_OK).build(); } diff --git a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/EndpointBase.java b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/EndpointBase.java index 77b7211a3a4b..6063d8bc5be2 100644 --- a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/EndpointBase.java +++ b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/EndpointBase.java @@ -58,6 +58,7 @@ import org.apache.hadoop.ozone.s3.metrics.S3GatewayMetrics; import org.apache.hadoop.ozone.s3.util.AuditUtils; +import org.apache.hadoop.util.Time; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -159,10 +160,11 @@ protected OzoneVolume getVolume() throws IOException { */ protected String createS3Bucket(String bucketName) throws IOException, OS3Exception { + long startNanos = Time.monotonicNowNanos(); try { client.getObjectStore().createS3Bucket(bucketName); } catch (OMException ex) { - getMetrics().incCreateBucketFailure(); + getMetrics().updateCreateBucketFailureStats(startNanos); if (ex.getResult() == ResultCodes.PERMISSION_DENIED) { throw newError(S3ErrorTable.ACCESS_DENIED, bucketName, ex); } else if (ex.getResult() == ResultCodes.INVALID_TOKEN) { diff --git a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/ObjectEndpoint.java b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/ObjectEndpoint.java index 200989a24715..d88c61b795db 100644 --- a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/ObjectEndpoint.java +++ b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/ObjectEndpoint.java @@ -177,7 +177,7 @@ public Response put( @QueryParam("partNumber") int partNumber, @QueryParam("uploadId") @DefaultValue("") String uploadID, InputStream body) throws IOException, OS3Exception { - + long startNanos = Time.monotonicNowNanos(); S3GAction s3GAction = S3GAction.CREATE_KEY; boolean auditSuccess = true; @@ -238,16 +238,16 @@ public Response put( keyPath, length, replicationConfig, customMetadata); IOUtils.copy(body, output); - getMetrics().incCreateKeySuccess(); + getMetrics().updateCreateKeySuccessStats(startNanos); return Response.ok().status(HttpStatus.SC_OK) .build(); } catch (OMException ex) { auditSuccess = false; auditWriteFailure(s3GAction, ex); if (copyHeader != null) { - getMetrics().incCopyObjectFailure(); + getMetrics().updateCopyObjectFailureStats(startNanos); } else { - getMetrics().incCreateKeyFailure(); + getMetrics().updateCreateKeyFailureStats(startNanos); } if (ex.getResult() == ResultCodes.NOT_A_FILE) { OS3Exception os3Exception = newError(INVALID_REQUEST, keyPath, ex); @@ -269,9 +269,9 @@ public Response put( auditSuccess = false; auditWriteFailure(s3GAction, ex); if (copyHeader != null) { - getMetrics().incCopyObjectFailure(); + getMetrics().updateCopyObjectFailureStats(startNanos); } else { - getMetrics().incCreateKeyFailure(); + getMetrics().updateCreateKeyFailureStats(startNanos); } throw ex; } finally { @@ -302,7 +302,7 @@ public Response get( @QueryParam("max-parts") @DefaultValue("1000") int maxParts, @QueryParam("part-number-marker") String partNumberMarker) throws IOException, OS3Exception { - + long startNanos = Time.monotonicNowNanos(); S3GAction s3GAction = S3GAction.GET_KEY; boolean auditSuccess = true; @@ -399,7 +399,7 @@ public Response get( } } addLastModifiedDate(responseBuilder, keyDetails); - getMetrics().incGetKeySuccess(); + getMetrics().updateGetKeySuccessStats(startNanos); return responseBuilder.build(); } catch (OMException ex) { auditSuccess = false; @@ -407,9 +407,9 @@ public Response get( buildAuditMessageForFailure(s3GAction, getAuditParameters(), ex) ); if (uploadId != null) { - getMetrics().incListPartsFailure(); + getMetrics().updateListPartsFailureStats(startNanos); } else { - getMetrics().incGetKeyFailure(); + getMetrics().updateGetKeyFailureStats(startNanos); } if (ex.getResult() == ResultCodes.KEY_NOT_FOUND) { throw newError(S3ErrorTable.NO_SUCH_KEY, keyPath, ex); @@ -456,7 +456,7 @@ static void addLastModifiedDate( public Response head( @PathParam("bucket") String bucketName, @PathParam("path") String keyPath) throws IOException, OS3Exception { - + long startNanos = Time.monotonicNowNanos(); S3GAction s3GAction = S3GAction.HEAD_KEY; OzoneKey key; @@ -466,7 +466,7 @@ public Response head( } catch (OMException ex) { AUDIT.logReadFailure( buildAuditMessageForFailure(s3GAction, getAuditParameters(), ex)); - getMetrics().incHeadKeyFailure(); + getMetrics().updateHeadKeyFailureStats(startNanos); if (ex.getResult() == ResultCodes.KEY_NOT_FOUND) { // Just return 404 with no content return Response.status(Status.NOT_FOUND).build(); @@ -489,7 +489,7 @@ public Response head( .header("Content-Type", "binary/octet-stream"); addLastModifiedDate(response, key); addCustomMetadataHeaders(response, key); - getMetrics().incHeadKeySuccess(); + getMetrics().updateHeadKeySuccessStats(startNanos); AUDIT.logReadSuccess(buildAuditMessageForSuccess(s3GAction, getAuditParameters())); return response.build(); @@ -507,6 +507,7 @@ public Response head( private Response abortMultipartUpload(OzoneVolume volume, String bucket, String key, String uploadId) throws IOException, OS3Exception { + long startNanos = Time.monotonicNowNanos(); try { getClientProtocol().abortMultipartUpload(volume.getName(), bucket, key, uploadId); @@ -518,7 +519,7 @@ private Response abortMultipartUpload(OzoneVolume volume, String bucket, } throw ex; } - getMetrics().incAbortMultiPartUploadSuccess(); + getMetrics().updateAbortMultipartUploadSuccessStats(startNanos); return Response .status(Status.NO_CONTENT) .build(); @@ -540,7 +541,7 @@ public Response delete( @PathParam("path") String keyPath, @QueryParam("uploadId") @DefaultValue("") String uploadId) throws IOException, OS3Exception { - + long startNanos = Time.monotonicNowNanos(); S3GAction s3GAction = S3GAction.DELETE_KEY; try { @@ -555,9 +556,9 @@ public Response delete( AUDIT.logWriteFailure( buildAuditMessageForFailure(s3GAction, getAuditParameters(), ex)); if (uploadId != null && !uploadId.equals("")) { - getMetrics().incAbortMultiPartUploadFailure(); + getMetrics().updateAbortMultipartUploadFailureStats(startNanos); } else { - getMetrics().incDeleteKeyFailure(); + getMetrics().updateDeleteKeyFailureStats(startNanos); } if (ex.getResult() == ResultCodes.BUCKET_NOT_FOUND) { throw newError(S3ErrorTable.NO_SUCH_BUCKET, bucketName, ex); @@ -578,13 +579,13 @@ public Response delete( AUDIT.logWriteFailure( buildAuditMessageForFailure(s3GAction, getAuditParameters(), ex)); if (uploadId != null && !uploadId.equals("")) { - getMetrics().incAbortMultiPartUploadFailure(); + getMetrics().updateAbortMultipartUploadFailureStats(startNanos); } else { - getMetrics().incDeleteKeyFailure(); + getMetrics().updateDeleteKeyFailureStats(startNanos); } throw ex; } - getMetrics().incDeleteKeySuccess(); + getMetrics().updateDeleteKeySuccessStats(startNanos); AUDIT.logWriteSuccess(buildAuditMessageForSuccess(s3GAction, getAuditParameters())); return Response @@ -605,6 +606,7 @@ public Response initializeMultipartUpload( @PathParam("path") String key ) throws IOException, OS3Exception { + long startNanos = Time.monotonicNowNanos(); S3GAction s3GAction = S3GAction.INIT_MULTIPART_UPLOAD; try { @@ -626,12 +628,12 @@ public Response initializeMultipartUpload( AUDIT.logWriteSuccess( buildAuditMessageForSuccess(s3GAction, getAuditParameters())); - getMetrics().incInitMultiPartUploadSuccess(); + getMetrics().updateInitMultipartUploadSuccessStats(startNanos); return Response.status(Status.OK).entity( multipartUploadInitiateResponse).build(); } catch (OMException ex) { auditWriteFailure(s3GAction, ex); - getMetrics().incInitMultiPartUploadFailure(); + getMetrics().updateInitMultipartUploadFailureStats(startNanos); if (isAccessDenied(ex)) { throw newError(S3ErrorTable.ACCESS_DENIED, key, ex); } @@ -639,7 +641,7 @@ public Response initializeMultipartUpload( } catch (Exception ex) { AUDIT.logWriteFailure( buildAuditMessageForFailure(s3GAction, getAuditParameters(), ex)); - getMetrics().incInitMultiPartUploadFailure(); + getMetrics().updateInitMultipartUploadFailureStats(startNanos); throw ex; } } @@ -672,6 +674,7 @@ public Response completeMultipartUpload(@PathParam("bucket") String bucket, @QueryParam("uploadId") @DefaultValue("") String uploadID, CompleteMultipartUploadRequest multipartUploadRequest) throws IOException, OS3Exception { + long startNanos = Time.monotonicNowNanos(); S3GAction s3GAction = S3GAction.COMPLETE_MULTIPART_UPLOAD; OzoneVolume volume = getVolume(); // Using LinkedHashMap to preserve ordering of parts list. @@ -701,12 +704,12 @@ public Response completeMultipartUpload(@PathParam("bucket") String bucket, completeMultipartUploadResponse.setLocation(bucket); AUDIT.logWriteSuccess( buildAuditMessageForSuccess(s3GAction, getAuditParameters())); - getMetrics().incCompleteMultiPartUploadSuccess(); + getMetrics().updateCompleteMultipartUploadSuccessStats(startNanos); return Response.status(Status.OK).entity(completeMultipartUploadResponse) .build(); } catch (OMException ex) { auditWriteFailure(s3GAction, ex); - getMetrics().incCompleteMultiPartUploadFailure(); + getMetrics().updateCompleteMultipartUploadFailureStats(startNanos); if (ex.getResult() == ResultCodes.INVALID_PART) { throw newError(S3ErrorTable.INVALID_PART, key, ex); } else if (ex.getResult() == ResultCodes.INVALID_PART_ORDER) { @@ -743,6 +746,7 @@ private Response createMultipartKey(OzoneVolume volume, String bucket, String key, long length, int partNumber, String uploadID, InputStream body) throws IOException, OS3Exception { + long startNanos = Time.monotonicNowNanos(); try { String copyHeader; OzoneOutputStream ozoneOutputStream = null; @@ -810,7 +814,7 @@ private Response createMultipartKey(OzoneVolume volume, String bucket, ozoneOutputStream.getCommitUploadPartInfo(); String eTag = omMultipartCommitUploadPartInfo.getPartName(); - getMetrics().incCreateMultipartKeySuccess(); + getMetrics().updateCreateMultipartKeySuccessStats(startNanos); if (copyHeader != null) { return Response.ok(new CopyPartResult(eTag)).build(); } else { @@ -819,7 +823,7 @@ private Response createMultipartKey(OzoneVolume volume, String bucket, } } catch (OMException ex) { - getMetrics().incCreateMultipartKeyFailure(); + getMetrics().updateCreateMultipartKeyFailureStats(startNanos); if (ex.getResult() == ResultCodes.NO_SUCH_MULTIPART_UPLOAD_ERROR) { throw newError(NO_SUCH_UPLOAD, uploadID, ex); } else if (isAccessDenied(ex)) { @@ -843,6 +847,7 @@ private Response createMultipartKey(OzoneVolume volume, String bucket, */ private Response listParts(String bucket, String key, String uploadID, int partNumberMarker, int maxParts) throws IOException, OS3Exception { + long startNanos = Time.monotonicNowNanos(); ListPartsResponse listPartsResponse = new ListPartsResponse(); try { OzoneBucket ozoneBucket = getBucket(bucket); @@ -874,9 +879,8 @@ private Response listParts(String bucket, String key, String uploadID, partInfo.getModificationTime())); listPartsResponse.addPart(part); }); - } catch (OMException ex) { - getMetrics().incListPartsFailure(); + getMetrics().updateListPartsFailureStats(startNanos); if (ex.getResult() == ResultCodes.NO_SUCH_MULTIPART_UPLOAD_ERROR) { throw newError(NO_SUCH_UPLOAD, uploadID, ex); } else if (isAccessDenied(ex)) { @@ -885,7 +889,7 @@ private Response listParts(String bucket, String key, String uploadID, } throw ex; } - getMetrics().incListPartsSuccess(); + getMetrics().updateListPartsSuccessStats(startNanos); return Response.status(Status.OK).entity(listPartsResponse).build(); } @@ -918,7 +922,7 @@ private CopyObjectResponse copyObject(OzoneVolume volume, ReplicationConfig replicationConfig, boolean storageTypeDefault) throws OS3Exception, IOException { - + long startNanos = Time.monotonicNowNanos(); Pair result = parseSourceHeader(copyHeader); String sourceBucket = result.getLeft(); @@ -964,7 +968,7 @@ private CopyObjectResponse copyObject(OzoneVolume volume, final OzoneKeyDetails destKeyDetails = getClientProtocol().getKeyDetails( volume.getName(), destBucket, destkey); - getMetrics().incCopyObjectSuccess(); + getMetrics().updateCopyObjectSuccessStats(startNanos); CopyObjectResponse copyObjectResponse = new CopyObjectResponse(); copyObjectResponse.setETag(OzoneUtils.getRequestID()); copyObjectResponse.setLastModified(destKeyDetails.getModificationTime()); diff --git a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/RootEndpoint.java b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/RootEndpoint.java index 57d0d12cfa5f..09360b6395be 100644 --- a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/RootEndpoint.java +++ b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/endpoint/RootEndpoint.java @@ -29,6 +29,7 @@ import org.apache.hadoop.ozone.s3.commontypes.BucketMetadata; import org.apache.hadoop.ozone.s3.exception.OS3Exception; +import org.apache.hadoop.util.Time; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -50,6 +51,7 @@ public class RootEndpoint extends EndpointBase { @GET public Response get() throws OS3Exception, IOException { + long startNanos = Time.monotonicNowNanos(); boolean auditSuccess = true; try { ListBucketResponse response = new ListBucketResponse(); @@ -58,7 +60,7 @@ public Response get() try { bucketIterator = listS3Buckets(null); } catch (Exception e) { - getMetrics().incListS3BucketsFailure(); + getMetrics().updateListS3BucketsFailureStats(startNanos); throw e; } @@ -70,7 +72,7 @@ public Response get() response.addBucket(bucketMetadata); } - getMetrics().incListS3BucketsSuccess(); + getMetrics().updateListS3BucketsSuccessStats(startNanos); return Response.ok(response).build(); } catch (Exception ex) { auditSuccess = false; diff --git a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/metrics/S3GatewayMetrics.java b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/metrics/S3GatewayMetrics.java index 05388d659eb3..4eb2ab2af115 100644 --- a/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/metrics/S3GatewayMetrics.java +++ b/hadoop-ozone/s3gateway/src/main/java/org/apache/hadoop/ozone/s3/metrics/S3GatewayMetrics.java @@ -27,7 +27,9 @@ import org.apache.hadoop.metrics2.lib.DefaultMetricsSystem; import org.apache.hadoop.metrics2.lib.MetricsRegistry; import org.apache.hadoop.metrics2.lib.MutableCounterLong; +import org.apache.hadoop.metrics2.lib.MutableRate; import org.apache.hadoop.ozone.OzoneConsts; +import org.apache.hadoop.util.Time; /** * This class maintains S3 Gateway related metrics. @@ -74,15 +76,155 @@ public final class S3GatewayMetrics implements MetricsSource { private @Metric MutableCounterLong getKeyFailure; private @Metric MutableCounterLong headKeySuccess; private @Metric MutableCounterLong headKeyFailure; - private @Metric MutableCounterLong initMultiPartUploadSuccess; - private @Metric MutableCounterLong initMultiPartUploadFailure; - private @Metric MutableCounterLong completeMultiPartUploadSuccess; - private @Metric MutableCounterLong completeMultiPartUploadFailure; - private @Metric MutableCounterLong abortMultiPartUploadSuccess; - private @Metric MutableCounterLong abortMultiPartUploadFailure; + private @Metric MutableCounterLong initMultipartUploadSuccess; + private @Metric MutableCounterLong initMultipartUploadFailure; + private @Metric MutableCounterLong completeMultipartUploadSuccess; + private @Metric MutableCounterLong completeMultipartUploadFailure; + private @Metric MutableCounterLong abortMultipartUploadSuccess; + private @Metric MutableCounterLong abortMultipartUploadFailure; private @Metric MutableCounterLong deleteKeySuccess; private @Metric MutableCounterLong deleteKeyFailure; + // S3 Gateway Latency Metrics + // BucketEndpoint + + @Metric(about = "Latency for successfully retrieving an S3 bucket in " + + "nanoseconds") + private MutableRate getBucketSuccessLatencyNs; + + @Metric(about = "Latency for failing to retrieve an S3 bucket in nanoseconds") + private MutableRate getBucketFailureLatencyNs; + + @Metric(about = "Latency for successfully creating an S3 bucket in " + + "nanoseconds") + private MutableRate createBucketSuccessLatencyNs; + + @Metric(about = "Latency for failing to create an S3 bucket in nanoseconds") + private MutableRate createBucketFailureLatencyNs; + + @Metric(about = "Latency for successfully checking the existence of an " + + "S3 bucket in nanoseconds") + private MutableRate headBucketSuccessLatencyNs; + + @Metric(about = "Latency for successfully deleting an S3 bucket in " + + "nanoseconds") + private MutableRate deleteBucketSuccessLatencyNs; + + @Metric(about = "Latency for failing to delete an S3 bucket in nanoseconds") + private MutableRate deleteBucketFailureLatencyNs; + + @Metric(about = "Latency for successfully retrieving an S3 bucket ACL " + + "in nanoseconds") + private MutableRate getAclSuccessLatencyNs; + + @Metric(about = "Latency for failing to retrieve an S3 bucket ACL " + + "in nanoseconds") + private MutableRate getAclFailureLatencyNs; + + @Metric(about = "Latency for successfully setting an S3 bucket ACL " + + "in nanoseconds") + private MutableRate putAclSuccessLatencyNs; + + @Metric(about = "Latency for failing to set an S3 bucket ACL " + + "in nanoseconds") + private MutableRate putAclFailureLatencyNs; + + @Metric(about = "Latency for successfully listing multipart uploads " + + "in nanoseconds") + private MutableRate listMultipartUploadsSuccessLatencyNs; + + @Metric(about = "Latency for failing to list multipart uploads " + + "in nanoseconds") + private MutableRate listMultipartUploadsFailureLatencyNs; + + // RootEndpoint + + @Metric(about = "Latency for successfully listing S3 buckets " + + "in nanoseconds") + private MutableRate listS3BucketsSuccessLatencyNs; + + @Metric(about = "Latency for failing to list S3 buckets " + + "in nanoseconds") + private MutableRate listS3BucketsFailureLatencyNs; + + // ObjectEndpoint + + @Metric(about = "Latency for successfully creating a multipart object key " + + "in nanoseconds") + private MutableRate createMultipartKeySuccessLatencyNs; + + @Metric(about = "Latency for failing to create a multipart object key in " + + "nanoseconds") + private MutableRate createMultipartKeyFailureLatencyNs; + + @Metric(about = "Latency for successfully copying an S3 object in " + + "nanoseconds") + private MutableRate copyObjectSuccessLatencyNs; + + @Metric(about = "Latency for failing to copy an S3 object in nanoseconds") + private MutableRate copyObjectFailureLatencyNs; + + @Metric(about = "Latency for successfully creating an S3 object key in " + + "nanoseconds") + private MutableRate createKeySuccessLatencyNs; + + @Metric(about = "Latency for failing to create an S3 object key in " + + "nanoseconds") + private MutableRate createKeyFailureLatencyNs; + + @Metric(about = "Latency for successfully listing parts of a multipart " + + "upload in nanoseconds") + private MutableRate listPartsSuccessLatencyNs; + + @Metric(about = "Latency for failing to list parts of a multipart upload " + + "in nanoseconds") + private MutableRate listPartsFailureLatencyNs; + + @Metric(about = "Latency for successfully retrieving an S3 object in " + + "nanoseconds") + private MutableRate getKeySuccessLatencyNs; + + @Metric(about = "Latency for failing to retrieve an S3 object in nanoseconds") + private MutableRate getKeyFailureLatencyNs; + + @Metric(about = "Latency for successfully retrieving metadata for an S3 " + + "object in nanoseconds") + private MutableRate headKeySuccessLatencyNs; + + @Metric(about = "Latency for failing to retrieve metadata for an S3 object " + + "in nanoseconds") + private MutableRate headKeyFailureLatencyNs; + + @Metric(about = "Latency for successfully initiating a multipart upload in " + + "nanoseconds") + private MutableRate initMultipartUploadSuccessLatencyNs; + + @Metric(about = "Latency for failing to initiate a multipart upload in " + + "nanoseconds") + private MutableRate initMultipartUploadFailureLatencyNs; + + @Metric(about = "Latency for successfully completing a multipart upload in " + + "nanoseconds") + private MutableRate completeMultipartUploadSuccessLatencyNs; + + @Metric(about = "Latency for failing to complete a multipart upload in " + + "nanoseconds") + private MutableRate completeMultipartUploadFailureLatencyNs; + + @Metric(about = "Latency for successfully aborting a multipart upload in " + + "nanoseconds") + private MutableRate abortMultipartUploadSuccessLatencyNs; + + @Metric(about = "Latency for failing to abort a multipart upload in " + + "nanoseconds") + private MutableRate abortMultipartUploadFailureLatencyNs; + + @Metric(about = "Latency for successfully deleting an S3 object in " + + "nanoseconds") + private MutableRate deleteKeySuccessLatencyNs; + + @Metric(about = "Latency for failing to delete an S3 object in nanoseconds") + private MutableRate deleteKeyFailureLatencyNs; /** * Private constructor. @@ -121,188 +263,271 @@ public void getMetrics(MetricsCollector collector, boolean all) { // BucketEndpoint getBucketSuccess.snapshot(recordBuilder, true); + getBucketSuccessLatencyNs.snapshot(recordBuilder, true); getBucketFailure.snapshot(recordBuilder, true); + getBucketFailureLatencyNs.snapshot(recordBuilder, true); createBucketSuccess.snapshot(recordBuilder, true); + createBucketSuccessLatencyNs.snapshot(recordBuilder, true); createBucketFailure.snapshot(recordBuilder, true); + createBucketFailureLatencyNs.snapshot(recordBuilder, true); headBucketSuccess.snapshot(recordBuilder, true); + headBucketSuccessLatencyNs.snapshot(recordBuilder, true); deleteBucketSuccess.snapshot(recordBuilder, true); + deleteBucketSuccessLatencyNs.snapshot(recordBuilder, true); deleteBucketFailure.snapshot(recordBuilder, true); + deleteBucketFailureLatencyNs.snapshot(recordBuilder, true); getAclSuccess.snapshot(recordBuilder, true); + getAclSuccessLatencyNs.snapshot(recordBuilder, true); getAclFailure.snapshot(recordBuilder, true); + getAclFailureLatencyNs.snapshot(recordBuilder, true); putAclSuccess.snapshot(recordBuilder, true); + putAclSuccessLatencyNs.snapshot(recordBuilder, true); putAclFailure.snapshot(recordBuilder, true); + putAclFailureLatencyNs.snapshot(recordBuilder, true); listMultipartUploadsSuccess.snapshot(recordBuilder, true); + listMultipartUploadsSuccessLatencyNs.snapshot(recordBuilder, true); listMultipartUploadsFailure.snapshot(recordBuilder, true); + listMultipartUploadsFailureLatencyNs.snapshot(recordBuilder, true); // RootEndpoint listS3BucketsSuccess.snapshot(recordBuilder, true); + listS3BucketsSuccessLatencyNs.snapshot(recordBuilder, true); listS3BucketsFailure.snapshot(recordBuilder, true); + listS3BucketsFailureLatencyNs.snapshot(recordBuilder, true); // ObjectEndpoint createMultipartKeySuccess.snapshot(recordBuilder, true); + createMultipartKeySuccessLatencyNs.snapshot(recordBuilder, true); createMultipartKeyFailure.snapshot(recordBuilder, true); + createMultipartKeyFailureLatencyNs.snapshot(recordBuilder, true); copyObjectSuccess.snapshot(recordBuilder, true); + copyObjectSuccessLatencyNs.snapshot(recordBuilder, true); copyObjectFailure.snapshot(recordBuilder, true); + copyObjectFailureLatencyNs.snapshot(recordBuilder, true); createKeySuccess.snapshot(recordBuilder, true); + createKeySuccessLatencyNs.snapshot(recordBuilder, true); createKeyFailure.snapshot(recordBuilder, true); + createKeyFailureLatencyNs.snapshot(recordBuilder, true); listPartsSuccess.snapshot(recordBuilder, true); + listPartsSuccessLatencyNs.snapshot(recordBuilder, true); listPartsFailure.snapshot(recordBuilder, true); + listPartsFailureLatencyNs.snapshot(recordBuilder, true); getKeySuccess.snapshot(recordBuilder, true); + getKeySuccessLatencyNs.snapshot(recordBuilder, true); getKeyFailure.snapshot(recordBuilder, true); + getKeyFailureLatencyNs.snapshot(recordBuilder, true); headKeySuccess.snapshot(recordBuilder, true); + headKeySuccessLatencyNs.snapshot(recordBuilder, true); headKeyFailure.snapshot(recordBuilder, true); - initMultiPartUploadSuccess.snapshot(recordBuilder, true); - initMultiPartUploadFailure.snapshot(recordBuilder, true); - completeMultiPartUploadSuccess.snapshot(recordBuilder, true); - completeMultiPartUploadFailure.snapshot(recordBuilder, true); - abortMultiPartUploadSuccess.snapshot(recordBuilder, true); - abortMultiPartUploadFailure.snapshot(recordBuilder, true); + headKeyFailureLatencyNs.snapshot(recordBuilder, true); + initMultipartUploadSuccess.snapshot(recordBuilder, true); + initMultipartUploadSuccessLatencyNs.snapshot(recordBuilder, true); + initMultipartUploadFailure.snapshot(recordBuilder, true); + initMultipartUploadFailureLatencyNs.snapshot(recordBuilder, true); + completeMultipartUploadSuccess.snapshot(recordBuilder, true); + completeMultipartUploadSuccessLatencyNs.snapshot(recordBuilder, true); + completeMultipartUploadFailure.snapshot(recordBuilder, true); + completeMultipartUploadFailureLatencyNs.snapshot(recordBuilder, true); + abortMultipartUploadSuccess.snapshot(recordBuilder, true); + abortMultipartUploadSuccessLatencyNs.snapshot(recordBuilder, true); + abortMultipartUploadFailure.snapshot(recordBuilder, true); + abortMultipartUploadFailureLatencyNs.snapshot(recordBuilder, true); deleteKeySuccess.snapshot(recordBuilder, true); + deleteKeySuccessLatencyNs.snapshot(recordBuilder, true); deleteKeyFailure.snapshot(recordBuilder, true); + deleteKeyFailureLatencyNs.snapshot(recordBuilder, true); } - // INC - public void incGetBucketSuccess() { + // INC and UPDATE + // BucketEndpoint + + public void updateGetBucketSuccessStats(long startNanos) { getBucketSuccess.incr(); + getBucketSuccessLatencyNs.add(Time.monotonicNowNanos() - startNanos); } - public void incGetBucketFailure() { + public void updateGetBucketFailureStats(long startNanos) { getBucketFailure.incr(); + getBucketFailureLatencyNs.add(Time.monotonicNowNanos() - startNanos); } - public void incListS3BucketsSuccess() { - listS3BucketsSuccess.incr(); + public void updateCreateBucketSuccessStats(long startNanos) { + createBucketSuccess.incr(); + createBucketSuccessLatencyNs.add(Time.monotonicNowNanos() - startNanos); } - - public void incListS3BucketsFailure() { - listS3BucketsFailure.incr(); + public void updateCreateBucketFailureStats(long startNanos) { + createBucketFailure.incr(); + createBucketFailureLatencyNs.add(Time.monotonicNowNanos() - startNanos); } + public void updateHeadBucketSuccessStats(long startNanos) { + headBucketSuccess.incr(); + headBucketSuccessLatencyNs.add(Time.monotonicNowNanos() - startNanos); + } - public void incCreateBucketSuccess() { - createBucketSuccess.incr(); + public void updateDeleteBucketSuccessStats(long startNanos) { + deleteBucketSuccess.incr(); + deleteBucketSuccessLatencyNs.add(Time.monotonicNowNanos() - startNanos); } - public void incCreateBucketFailure() { - createBucketFailure.incr(); + public void updateDeleteBucketFailureStats(long startNanos) { + deleteBucketFailure.incr(); + deleteBucketFailureLatencyNs.add(Time.monotonicNowNanos() - startNanos); } - public void incPutAclSuccess() { - putAclSuccess.incr(); + public void updateGetAclSuccessStats(long startNanos) { + getAclSuccess.incr(); + getAclSuccessLatencyNs.add(Time.monotonicNowNanos() - startNanos); } - public void incPutAclFailure() { - putAclFailure.incr(); + public void updateGetAclFailureStats(long startNanos) { + getAclFailure.incr(); + getAclFailureLatencyNs.add(Time.monotonicNowNanos() - startNanos); } - public void incGetAclSuccess() { - getAclSuccess.incr(); + public void updatePutAclSuccessStats(long startNanos) { + putAclSuccess.incr(); + putAclSuccessLatencyNs.add(Time.monotonicNowNanos() - startNanos); } - public void incGetAclFailure() { - getAclFailure.incr(); + public void updatePutAclFailureStats(long startNanos) { + putAclFailure.incr(); + putAclFailureLatencyNs.add(Time.monotonicNowNanos() - startNanos); } - public void incListMultipartUploadsSuccess() { + public void updateListMultipartUploadsSuccessStats(long startNanos) { listMultipartUploadsSuccess.incr(); + listMultipartUploadsSuccessLatencyNs.add( + Time.monotonicNowNanos() - startNanos); } - public void incListMultipartUploadsFailure() { + public void updateListMultipartUploadsFailureStats(long startNanos) { listMultipartUploadsFailure.incr(); + listMultipartUploadsFailureLatencyNs.add( + Time.monotonicNowNanos() - startNanos); } - public void incHeadBucketSuccess() { - headBucketSuccess.incr(); - } - + // RootEndpoint - public void incDeleteBucketSuccess() { - deleteBucketSuccess.incr(); + public void updateListS3BucketsSuccessStats(long startNanos) { + listS3BucketsSuccess.incr(); + listS3BucketsSuccessLatencyNs.add(Time.monotonicNowNanos() - startNanos); } - public void incDeleteBucketFailure() { - deleteBucketFailure.incr(); + public void updateListS3BucketsFailureStats(long startNanos) { + listS3BucketsFailure.incr(); + listS3BucketsFailureLatencyNs.add(Time.monotonicNowNanos() - startNanos); } - public void incCreateMultipartKeySuccess() { + // ObjectEndpoint + + public void updateCreateMultipartKeySuccessStats(long startNanos) { createMultipartKeySuccess.incr(); + createMultipartKeySuccessLatencyNs.add( + Time.monotonicNowNanos() - startNanos); } - public void incCreateMultipartKeyFailure() { + public void updateCreateMultipartKeyFailureStats(long startNanos) { createMultipartKeyFailure.incr(); + createMultipartKeyFailureLatencyNs.add( + Time.monotonicNowNanos() - startNanos); } - public void incCopyObjectSuccess() { + public void updateCopyObjectSuccessStats(long startNanos) { copyObjectSuccess.incr(); + copyObjectSuccessLatencyNs.add(Time.monotonicNowNanos() - startNanos); } - public void incCopyObjectFailure() { + public void updateCopyObjectFailureStats(long startNanos) { copyObjectFailure.incr(); + copyObjectFailureLatencyNs.add(Time.monotonicNowNanos() - startNanos); } - public void incCreateKeySuccess() { + public void updateCreateKeySuccessStats(long startNanos) { createKeySuccess.incr(); + createKeySuccessLatencyNs.add(Time.monotonicNowNanos() - startNanos); } - public void incCreateKeyFailure() { + public void updateCreateKeyFailureStats(long startNanos) { createKeyFailure.incr(); + createKeyFailureLatencyNs.add(Time.monotonicNowNanos() - startNanos); } - public void incListPartsSuccess() { + public void updateListPartsSuccessStats(long startNanos) { listPartsSuccess.incr(); + listPartsSuccessLatencyNs.add(Time.monotonicNowNanos() - startNanos); } - public void incListPartsFailure() { + public void updateListPartsFailureStats(long startNanos) { listPartsFailure.incr(); + listPartsFailureLatencyNs.add(Time.monotonicNowNanos() - startNanos); } - public void incGetKeySuccess() { + public void updateGetKeySuccessStats(long startNanos) { getKeySuccess.incr(); + getKeySuccessLatencyNs.add(Time.monotonicNowNanos() - startNanos); } - public void incGetKeyFailure() { + public void updateGetKeyFailureStats(long startNanos) { getKeyFailure.incr(); + getKeyFailureLatencyNs.add(Time.monotonicNowNanos() - startNanos); } - public void incHeadKeySuccess() { + public void updateHeadKeySuccessStats(long startNanos) { headKeySuccess.incr(); + headKeySuccessLatencyNs.add(Time.monotonicNowNanos() - startNanos); } - public void incHeadKeyFailure() { + public void updateHeadKeyFailureStats(long startNanos) { headKeyFailure.incr(); + headKeyFailureLatencyNs.add(Time.monotonicNowNanos() - startNanos); } - public void incAbortMultiPartUploadSuccess() { - abortMultiPartUploadSuccess.incr(); + public void updateInitMultipartUploadSuccessStats(long startNanos) { + initMultipartUploadSuccess.incr(); + initMultipartUploadSuccessLatencyNs.add( + Time.monotonicNowNanos() - startNanos); } - public void incAbortMultiPartUploadFailure() { - abortMultiPartUploadFailure.incr(); + public void updateInitMultipartUploadFailureStats(long startNanos) { + initMultipartUploadFailure.incr(); + initMultipartUploadFailureLatencyNs.add( + Time.monotonicNowNanos() - startNanos); } - public void incDeleteKeySuccess() { - deleteKeySuccess.incr(); + public void updateCompleteMultipartUploadSuccessStats(long startNanos) { + completeMultipartUploadSuccess.incr(); + completeMultipartUploadSuccessLatencyNs.add( + Time.monotonicNowNanos() - startNanos); } - public void incDeleteKeyFailure() { - deleteKeyFailure.incr(); + public void updateCompleteMultipartUploadFailureStats(long startNanos) { + completeMultipartUploadFailure.incr(); + completeMultipartUploadFailureLatencyNs.add( + Time.monotonicNowNanos() - startNanos); } - public void incInitMultiPartUploadSuccess() { - initMultiPartUploadSuccess.incr(); + public void updateAbortMultipartUploadSuccessStats(long startNanos) { + abortMultipartUploadSuccess.incr(); + abortMultipartUploadSuccessLatencyNs.add( + Time.monotonicNowNanos() - startNanos); } - public void incInitMultiPartUploadFailure() { - initMultiPartUploadFailure.incr(); + public void updateAbortMultipartUploadFailureStats(long startNanos) { + abortMultipartUploadFailure.incr(); + abortMultipartUploadFailureLatencyNs.add( + Time.monotonicNowNanos() - startNanos); } - public void incCompleteMultiPartUploadSuccess() { - completeMultiPartUploadSuccess.incr(); + public void updateDeleteKeySuccessStats(long startNanos) { + deleteKeySuccess.incr(); + deleteKeySuccessLatencyNs.add(Time.monotonicNowNanos() - startNanos); } - public void incCompleteMultiPartUploadFailure() { - completeMultiPartUploadFailure.incr(); + public void updateDeleteKeyFailureStats(long startNanos) { + deleteKeyFailure.incr(); + deleteKeyFailureLatencyNs.add(Time.monotonicNowNanos() - startNanos); } // GET @@ -375,11 +600,11 @@ public long getCreateMultipartKeyFailure() { } public long getCompleteMultiPartUploadSuccess() { - return completeMultiPartUploadSuccess.value(); + return completeMultipartUploadSuccess.value(); } public long getCompleteMultiPartUploadFailure() { - return completeMultiPartUploadFailure.value(); + return completeMultipartUploadFailure.value(); } public long getListPartsSuccess() { @@ -407,11 +632,11 @@ public long getCreateKeySuccess() { } public long getInitMultiPartUploadSuccess() { - return initMultiPartUploadSuccess.value(); + return initMultipartUploadSuccess.value(); } public long getInitMultiPartUploadFailure() { - return initMultiPartUploadFailure.value(); + return initMultipartUploadFailure.value(); } public long getDeleteKeySuccess() { @@ -431,11 +656,11 @@ public long getGetKeySuccess() { } public long getAbortMultiPartUploadSuccess() { - return abortMultiPartUploadSuccess.value(); + return abortMultipartUploadSuccess.value(); } public long getAbortMultiPartUploadFailure() { - return abortMultiPartUploadFailure.value(); + return abortMultipartUploadFailure.value(); } public long getHeadKeyFailure() {