diff --git a/arklet/arklet-core/src/main/java/com/alipay/sofa/serverless/arklet/core/command/CommandServiceImpl.java b/arklet/arklet-core/src/main/java/com/alipay/sofa/serverless/arklet/core/command/CommandServiceImpl.java index b566a3c75..093d36fb4 100644 --- a/arklet/arklet-core/src/main/java/com/alipay/sofa/serverless/arklet/core/command/CommandServiceImpl.java +++ b/arklet/arklet-core/src/main/java/com/alipay/sofa/serverless/arklet/core/command/CommandServiceImpl.java @@ -41,6 +41,7 @@ import com.alipay.sofa.serverless.arklet.core.command.meta.Command; import com.alipay.sofa.serverless.arklet.core.command.meta.InputMeta; import com.alipay.sofa.serverless.arklet.core.command.meta.Output; +import com.alipay.sofa.serverless.arklet.core.command.record.MetaSpaceRecord; import com.alipay.sofa.serverless.arklet.core.command.record.ProcessRecord; import com.alipay.sofa.serverless.arklet.core.command.record.ProcessRecordHolder; import com.alipay.sofa.serverless.arklet.core.common.exception.ArkletInitException; @@ -110,6 +111,7 @@ public Output process(String cmd, Map content) throws CommandValidationExcept ArkBizMeta arkBizMeta = (ArkBizMeta) input; AssertUtils.assertNotNull(arkBizMeta, "when execute bizOpsHandler, arkBizMeta should not be null"); + final MetaSpaceRecord metaSpaceRecord = new MetaSpaceRecord(); if (arkBizMeta.isAsync()) { String requestId = arkBizMeta.getRequestId(); if (ProcessRecordHolder.getProcessRecord(requestId) != null) { @@ -127,6 +129,7 @@ public Output process(String cmd, Map content) throws CommandValidationExcept processRecord.fail("command conflict, exist unfinished command for this biz"); } else { processRecord.start(); + processRecord.setStartSpace(metaSpaceRecord.getMetaSpaceMXBean().getUsage().getUsed()); Output output = handler.handle(input); if (output.success()) { processRecord.success(); @@ -138,6 +141,7 @@ public Output process(String cmd, Map content) throws CommandValidationExcept processRecord.fail(throwable.getMessage(), throwable); LOGGER.error("Error happened when handling command, requestId=" + requestId, throwable); } finally { + processRecord.setEndSpace(metaSpaceRecord.getMetaSpaceMXBean().getUsage().getUsed()); processRecord.markFinishTime(); BizOpsCommandCoordinator .unlock(arkBizMeta.getBizName(), arkBizMeta.getBizVersion()); @@ -160,7 +164,10 @@ public Output process(String cmd, Map content) throws CommandValidationExcept arkBizMeta.getBizName(), arkBizMeta.getBizVersion()).getId())); } try { - return handler.handle(input); + final long startSpace = metaSpaceRecord.getMetaSpaceMXBean().getUsage().getUsed(); + Output output = handler.handle(input); + output.setElapsedSpace(metaSpaceRecord.getMetaSpaceMXBean().getUsage().getUsed() - startSpace); + return output; } finally { BizOpsCommandCoordinator .unlock(arkBizMeta.getBizName(), arkBizMeta.getBizVersion()); diff --git a/arklet/arklet-core/src/main/java/com/alipay/sofa/serverless/arklet/core/command/meta/Output.java b/arklet/arklet-core/src/main/java/com/alipay/sofa/serverless/arklet/core/command/meta/Output.java index c997ed464..57ffe0457 100644 --- a/arklet/arklet-core/src/main/java/com/alipay/sofa/serverless/arklet/core/command/meta/Output.java +++ b/arklet/arklet-core/src/main/java/com/alipay/sofa/serverless/arklet/core/command/meta/Output.java @@ -26,6 +26,7 @@ public class Output { private ResponseCode code; private String message; + private long elapsedSpace; private T data; private Output() { @@ -84,4 +85,12 @@ public T getData() { public void setData(T data) { this.data = data; } + + public void setElapsedSpace(long elapsedSpace) { + this.elapsedSpace = elapsedSpace; + } + + public long getElapsedSpace() { + return this.elapsedSpace; + } } diff --git a/arklet/arklet-core/src/main/java/com/alipay/sofa/serverless/arklet/core/command/record/MetaSpaceRecord.java b/arklet/arklet-core/src/main/java/com/alipay/sofa/serverless/arklet/core/command/record/MetaSpaceRecord.java new file mode 100644 index 000000000..3da1e1e74 --- /dev/null +++ b/arklet/arklet-core/src/main/java/com/alipay/sofa/serverless/arklet/core/command/record/MetaSpaceRecord.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 + * + * http://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.alipay.sofa.serverless.arklet.core.command.record; + +import java.lang.management.ManagementFactory; +import java.lang.management.MemoryPoolMXBean; +import java.util.List; + +/** + * @author sususama + * @since 2023-09-21 + */ + +public class MetaSpaceRecord { + private static MemoryPoolMXBean metaSpaceMXBean; + static { + List memoryPoolMXBeans = ManagementFactory.getMemoryPoolMXBeans(); + for (MemoryPoolMXBean memoryPoolMXBean : memoryPoolMXBeans) + if (memoryPoolMXBean.getName().equals("Metaspace")) + metaSpaceMXBean = memoryPoolMXBean; + } + + public MemoryPoolMXBean getMetaSpaceMXBean() { + return metaSpaceMXBean; + } +} diff --git a/arklet/arklet-core/src/main/java/com/alipay/sofa/serverless/arklet/core/command/record/ProcessRecord.java b/arklet/arklet-core/src/main/java/com/alipay/sofa/serverless/arklet/core/command/record/ProcessRecord.java index d3e1f62ff..c7f8c561f 100644 --- a/arklet/arklet-core/src/main/java/com/alipay/sofa/serverless/arklet/core/command/record/ProcessRecord.java +++ b/arklet/arklet-core/src/main/java/com/alipay/sofa/serverless/arklet/core/command/record/ProcessRecord.java @@ -55,14 +55,20 @@ public class ProcessRecord { private Date startTime; + private long startSpace; + private long startTimestamp; private Date endTime; + private long endSpace; + private long endTimestamp; private long elapsedTime; + private long elapsedSpace; + public enum Status { INITIALIZED("INITIALIZED"), @@ -89,6 +95,7 @@ public void setName(String name) { } public void markFinishTime() { + setElapsedSpace(getEndSpace() - getStartSpace()); Date date = new Date(); setEndTime(date); setEndTimestamp(date.getTime()); diff --git a/arklet/arklet-core/src/main/java/com/alipay/sofa/serverless/arklet/core/command/record/ProcessRecordHolder.java b/arklet/arklet-core/src/main/java/com/alipay/sofa/serverless/arklet/core/command/record/ProcessRecordHolder.java index 01ccd4b75..d270209cf 100644 --- a/arklet/arklet-core/src/main/java/com/alipay/sofa/serverless/arklet/core/command/record/ProcessRecordHolder.java +++ b/arklet/arklet-core/src/main/java/com/alipay/sofa/serverless/arklet/core/command/record/ProcessRecordHolder.java @@ -16,7 +16,6 @@ */ package com.alipay.sofa.serverless.arklet.core.command.record; -import com.alipay.sofa.serverless.arklet.core.command.meta.InputMeta; import com.alipay.sofa.serverless.arklet.core.command.meta.bizops.ArkBizMeta; import org.apache.commons.lang3.StringUtils; diff --git a/arklet/arklet-core/src/main/java/com/alipay/sofa/serverless/arklet/core/health/HealthServiceImpl.java b/arklet/arklet-core/src/main/java/com/alipay/sofa/serverless/arklet/core/health/HealthServiceImpl.java index dc4fb1b7a..2c63ba77a 100644 --- a/arklet/arklet-core/src/main/java/com/alipay/sofa/serverless/arklet/core/health/HealthServiceImpl.java +++ b/arklet/arklet-core/src/main/java/com/alipay/sofa/serverless/arklet/core/health/HealthServiceImpl.java @@ -49,9 +49,8 @@ @Singleton public class HealthServiceImpl implements HealthService { - private static final ArkletLogger LOGGER = ArkletLoggerFactory - .getDefaultLogger(); - private final HealthBuilder healthBuilder = new HealthBuilder(); + private static final ArkletLogger LOGGER = ArkletLoggerFactory.getDefaultLogger(); + private final HealthBuilder healthBuilder = new HealthBuilder(); private final Map indicators = new ConcurrentHashMap<>(3); diff --git a/arklet/arklet-core/src/test/java/com/alipay/sofa/serverless/arklet/core/command/CommandTests.java b/arklet/arklet-core/src/test/java/com/alipay/sofa/serverless/arklet/core/command/CommandTests.java index 452294aea..a2147332c 100644 --- a/arklet/arklet-core/src/test/java/com/alipay/sofa/serverless/arklet/core/command/CommandTests.java +++ b/arklet/arklet-core/src/test/java/com/alipay/sofa/serverless/arklet/core/command/CommandTests.java @@ -16,11 +16,7 @@ */ package com.alipay.sofa.serverless.arklet.core.command; -import java.util.HashMap; -import java.util.Map; - import com.alibaba.fastjson.JSONObject; - import com.alipay.sofa.serverless.arklet.core.BaseTest; import com.alipay.sofa.serverless.arklet.core.command.builtin.BuiltinCommand; import com.alipay.sofa.serverless.arklet.core.command.builtin.handler.InstallBizHandler; @@ -32,6 +28,9 @@ import org.junit.Assert; import org.junit.Test; +import java.util.HashMap; +import java.util.Map; + /** * @author mingmen * @date 2023/6/26 @@ -67,12 +66,16 @@ public void testInstallHandler() throws InterruptedException { Assert.assertNotNull(output); ProcessRecord processRecord = (ProcessRecord) output.getData(); Assert.assertNotNull(processRecord); + Assert.assertNotNull(processRecord.getEndSpace()); QueryBizOpsHandler.Input input1 = new QueryBizOpsHandler.Input(); input1.setRequestId(rid); Map map1 = JSONObject.parseObject(JSONObject.toJSONString(input1), Map.class); Output output1 = commandService.process(BuiltinCommand.QUERY_BIZ_OPS.getId(), map1); Assert.assertNotNull(output1); + ProcessRecord processRecord1 = (ProcessRecord) output1.getData(); + Assert.assertNotNull(processRecord1); + Assert.assertNotNull(processRecord1.getEndSpace()); } } diff --git a/arklet/arklet-core/src/test/java/com/alipay/sofa/serverless/arklet/core/command/HealthHandlerTest.java b/arklet/arklet-core/src/test/java/com/alipay/sofa/serverless/arklet/core/command/HealthHandlerTest.java index 8c2ec0dc8..cae78df33 100644 --- a/arklet/arklet-core/src/test/java/com/alipay/sofa/serverless/arklet/core/command/HealthHandlerTest.java +++ b/arklet/arklet-core/src/test/java/com/alipay/sofa/serverless/arklet/core/command/HealthHandlerTest.java @@ -1,3 +1,19 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 + * + * http://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.alipay.sofa.serverless.arklet.core.command; import com.alipay.sofa.serverless.arklet.core.BaseTest; @@ -12,7 +28,7 @@ */ public class HealthHandlerTest extends BaseTest { - private void testValidate(Input input) throws CommandValidationException{ + private void testValidate(Input input) throws CommandValidationException { HealthHandler handler = (HealthHandler) commandService.getHandler(BuiltinCommand.HEALTH); handler.validate(input); }