diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/ServiceInstanceCLRGC.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/ServiceInstanceCLRGC.java index 904f2f9268..f72127d794 100644 --- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/ServiceInstanceCLRGC.java +++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/source/ServiceInstanceCLRGC.java @@ -40,8 +40,8 @@ public class ServiceInstanceCLRGC extends Source { @Getter @Setter private String name; @Getter @Setter private String serviceName; @Getter @Setter private int serviceId; - @Getter @Setter private int gen0CollectCount; - @Getter @Setter private int gen1CollectCount; - @Getter @Setter private int gen2CollectCount; + @Getter @Setter private long gen0CollectCount; + @Getter @Setter private long gen1CollectCount; + @Getter @Setter private long gen2CollectCount; @Getter @Setter private long heapMemory; } \ No newline at end of file diff --git a/oap-server/server-receiver-plugin/pom.xml b/oap-server/server-receiver-plugin/pom.xml index e276a5a9d3..8c32601c66 100644 --- a/oap-server/server-receiver-plugin/pom.xml +++ b/oap-server/server-receiver-plugin/pom.xml @@ -36,6 +36,7 @@ skywalking-jvm-receiver-plugin envoy-metrics-receiver-plugin skywalking-sharing-server-plugin + skywalking-clr-receiver-plugin diff --git a/oap-server/server-receiver-plugin/skywalking-clr-receiver-plugin/pom.xml b/oap-server/server-receiver-plugin/skywalking-clr-receiver-plugin/pom.xml new file mode 100644 index 0000000000..b32d1d240a --- /dev/null +++ b/oap-server/server-receiver-plugin/skywalking-clr-receiver-plugin/pom.xml @@ -0,0 +1,40 @@ + + + + + + server-receiver-plugin + org.apache.skywalking + 6.1.0-SNAPSHOT + + 4.0.0 + + skywalking-clr-receiver-plugin + jar + + + + org.apache.skywalking + skywalking-sharing-server-plugin + ${project.version} + + + \ No newline at end of file diff --git a/oap-server/server-receiver-plugin/skywalking-clr-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/clr/module/CLRModule.java b/oap-server/server-receiver-plugin/skywalking-clr-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/clr/module/CLRModule.java new file mode 100644 index 0000000000..dacc436c27 --- /dev/null +++ b/oap-server/server-receiver-plugin/skywalking-clr-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/clr/module/CLRModule.java @@ -0,0 +1,35 @@ +/* + * 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 org.apache.skywalking.oap.server.receiver.clr.module; + +import org.apache.skywalking.oap.server.library.module.ModuleDefine; + +/** + * @author liuhaoyang + **/ +public class CLRModule extends ModuleDefine { + + public CLRModule() { + super("receiver-clr"); + } + + @Override public Class[] services() { + return new Class[0]; + } +} diff --git a/oap-server/server-receiver-plugin/skywalking-clr-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/clr/provider/CLRModuleProvider.java b/oap-server/server-receiver-plugin/skywalking-clr-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/clr/provider/CLRModuleProvider.java new file mode 100644 index 0000000000..505cb0ddcb --- /dev/null +++ b/oap-server/server-receiver-plugin/skywalking-clr-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/clr/provider/CLRModuleProvider.java @@ -0,0 +1,65 @@ +/* + * 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 org.apache.skywalking.oap.server.receiver.clr.provider; + +import org.apache.skywalking.oap.server.core.CoreModule; +import org.apache.skywalking.oap.server.core.server.GRPCHandlerRegister; +import org.apache.skywalking.oap.server.library.module.ModuleConfig; +import org.apache.skywalking.oap.server.library.module.ModuleDefine; +import org.apache.skywalking.oap.server.library.module.ModuleProvider; +import org.apache.skywalking.oap.server.library.module.ModuleStartException; +import org.apache.skywalking.oap.server.library.module.ServiceNotProvidedException; +import org.apache.skywalking.oap.server.receiver.clr.module.CLRModule; +import org.apache.skywalking.oap.server.receiver.clr.provider.handler.CLRMetricReportServiceHandler; +import org.apache.skywalking.oap.server.receiver.sharing.server.SharingServerModule; + +/** + * @author liuhaoyang + **/ +public class CLRModuleProvider extends ModuleProvider { + + @Override public String name() { + return "default"; + } + + @Override public Class module() { + return CLRModule.class; + } + + @Override public ModuleConfig createConfigBeanIfAbsent() { + return null; + } + + @Override public void prepare() throws ServiceNotProvidedException, ModuleStartException { + + } + + @Override public void start() throws ServiceNotProvidedException, ModuleStartException { + GRPCHandlerRegister grpcHandlerRegister = getManager().find(SharingServerModule.NAME).provider().getService(GRPCHandlerRegister.class); + grpcHandlerRegister.addHandler(new CLRMetricReportServiceHandler(getManager())); + } + + @Override public void notifyAfterCompleted() throws ServiceNotProvidedException, ModuleStartException { + + } + + @Override public String[] requiredModules() { + return new String[] {CoreModule.NAME, SharingServerModule.NAME}; + } +} diff --git a/oap-server/server-receiver-plugin/skywalking-clr-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/clr/provider/handler/CLRMetricReportServiceHandler.java b/oap-server/server-receiver-plugin/skywalking-clr-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/clr/provider/handler/CLRMetricReportServiceHandler.java new file mode 100644 index 0000000000..da7f66d0ba --- /dev/null +++ b/oap-server/server-receiver-plugin/skywalking-clr-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/clr/provider/handler/CLRMetricReportServiceHandler.java @@ -0,0 +1,59 @@ +/* + * 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 org.apache.skywalking.oap.server.receiver.clr.provider.handler; + +import io.grpc.stub.StreamObserver; +import org.apache.skywalking.apm.network.common.Commands; +import org.apache.skywalking.apm.network.language.agent.v2.CLRMetricCollection; +import org.apache.skywalking.apm.network.language.agent.v2.CLRMetricReportServiceGrpc; +import org.apache.skywalking.oap.server.library.module.ModuleManager; +import org.apache.skywalking.oap.server.library.server.grpc.GRPCHandler; +import org.apache.skywalking.oap.server.library.util.TimeBucketUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author liuhaoyang + **/ +public class CLRMetricReportServiceHandler extends CLRMetricReportServiceGrpc.CLRMetricReportServiceImplBase implements GRPCHandler { + + private static final Logger logger = LoggerFactory.getLogger(CLRMetricReportServiceHandler.class); + + private final CLRSourceDispatcher clrSourceDispatcher; + + public CLRMetricReportServiceHandler(ModuleManager moduleManager) { + clrSourceDispatcher = new CLRSourceDispatcher(moduleManager); + } + + @Override public void collect(CLRMetricCollection request, StreamObserver responseObserver) { + int serviceInstanceId = request.getServiceInstanceId(); + + if (logger.isDebugEnabled()) { + logger.debug("receive the clr metric from service instance, id: {}", serviceInstanceId); + } + + request.getMetricsList().forEach(metric -> { + long minuteTimeBucket = TimeBucketUtils.INSTANCE.getMinuteTimeBucket(metric.getTime()); + clrSourceDispatcher.sendMetric(serviceInstanceId, minuteTimeBucket, metric); + }); + + responseObserver.onNext(Commands.newBuilder().build()); + responseObserver.onCompleted(); + } +} diff --git a/oap-server/server-receiver-plugin/skywalking-clr-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/clr/provider/handler/CLRSourceDispatcher.java b/oap-server/server-receiver-plugin/skywalking-clr-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/clr/provider/handler/CLRSourceDispatcher.java new file mode 100644 index 0000000000..62f46200e1 --- /dev/null +++ b/oap-server/server-receiver-plugin/skywalking-clr-receiver-plugin/src/main/java/org/apache/skywalking/oap/server/receiver/clr/provider/handler/CLRSourceDispatcher.java @@ -0,0 +1,97 @@ +/* + * 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 org.apache.skywalking.oap.server.receiver.clr.provider.handler; + +import org.apache.skywalking.apm.network.common.CPU; +import org.apache.skywalking.apm.network.language.agent.CLRMetric; +import org.apache.skywalking.apm.network.language.agent.ClrGC; +import org.apache.skywalking.apm.network.language.agent.ClrThread; +import org.apache.skywalking.oap.server.core.Const; +import org.apache.skywalking.oap.server.core.CoreModule; +import org.apache.skywalking.oap.server.core.cache.ServiceInstanceInventoryCache; +import org.apache.skywalking.oap.server.core.register.ServiceInstanceInventory; +import org.apache.skywalking.oap.server.core.source.ServiceInstanceCLRCPU; +import org.apache.skywalking.oap.server.core.source.ServiceInstanceCLRGC; +import org.apache.skywalking.oap.server.core.source.ServiceInstanceCLRThread; +import org.apache.skywalking.oap.server.core.source.SourceReceiver; +import org.apache.skywalking.oap.server.library.module.ModuleManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author liuhaoyang + **/ +public class CLRSourceDispatcher { + + private static final Logger logger = LoggerFactory.getLogger(CLRSourceDispatcher.class); + private final SourceReceiver sourceReceiver; + private final ServiceInstanceInventoryCache instanceInventoryCache; + + public CLRSourceDispatcher(ModuleManager moduleManager) { + sourceReceiver = moduleManager.find(CoreModule.NAME).provider().getService(SourceReceiver.class); + instanceInventoryCache = moduleManager.find(CoreModule.NAME).provider().getService(ServiceInstanceInventoryCache.class); + } + + void sendMetric(int serviceInstanceId, long minuteTimeBucket, CLRMetric metric) { + ServiceInstanceInventory serviceInstanceInventory = instanceInventoryCache.get(serviceInstanceId); + int serviceId; + if (serviceInstanceInventory == null) { + serviceId = serviceInstanceInventory.getServiceId(); + } else { + logger.warn("Can't found service by service instance id from cache, service instance id is: {}", serviceInstanceId); + return; + } + + CPU cpu = metric.getCpu(); + ServiceInstanceCLRCPU serviceInstanceCLRCPU = new ServiceInstanceCLRCPU(); + serviceInstanceCLRCPU.setUsePercent(cpu.getUsagePercent()); + serviceInstanceCLRCPU.setTimeBucket(minuteTimeBucket); + serviceInstanceCLRCPU.setId(serviceInstanceId); + serviceInstanceCLRCPU.setName(Const.EMPTY_STRING); + serviceInstanceCLRCPU.setServiceId(serviceId); + serviceInstanceCLRCPU.setServiceName(Const.EMPTY_STRING); + sourceReceiver.receive(serviceInstanceCLRCPU); + + ClrGC gc = metric.getGc(); + ServiceInstanceCLRGC serviceInstanceCLRGC = new ServiceInstanceCLRGC(); + serviceInstanceCLRGC.setGen0CollectCount(gc.getGen0CollectCount()); + serviceInstanceCLRGC.setGen1CollectCount(gc.getGen1CollectCount()); + serviceInstanceCLRGC.setGen2CollectCount(gc.getGen2CollectCount()); + serviceInstanceCLRGC.setHeapMemory(gc.getHeapMemory()); + serviceInstanceCLRGC.setTimeBucket(minuteTimeBucket); + serviceInstanceCLRGC.setId(serviceInstanceId); + serviceInstanceCLRGC.setName(Const.EMPTY_STRING); + serviceInstanceCLRGC.setServiceId(serviceId); + serviceInstanceCLRGC.setServiceName(Const.EMPTY_STRING); + sourceReceiver.receive(serviceInstanceCLRGC); + + ClrThread thread = metric.getThread(); + ServiceInstanceCLRThread serviceInstanceCLRThread = new ServiceInstanceCLRThread(); + serviceInstanceCLRThread.setAvailableCompletionPortThreads(thread.getAvailableCompletionPortThreads()); + serviceInstanceCLRThread.setAvailableWorkerThreads(thread.getAvailableWorkerThreads()); + serviceInstanceCLRThread.setMaxCompletionPortThreads(thread.getMaxCompletionPortThreads()); + serviceInstanceCLRThread.setMaxWorkerThreads(thread.getMaxWorkerThreads()); + serviceInstanceCLRThread.setTimeBucket(minuteTimeBucket); + serviceInstanceCLRThread.setId(serviceInstanceId); + serviceInstanceCLRThread.setName(Const.EMPTY_STRING); + serviceInstanceCLRThread.setServiceId(serviceId); + serviceInstanceCLRThread.setServiceName(Const.EMPTY_STRING); + sourceReceiver.receive(serviceInstanceCLRThread); + } +} diff --git a/oap-server/server-receiver-plugin/skywalking-clr-receiver-plugin/src/main/resources/META-INF/services/org.apache.skywalking.oap.server.library.module.ModuleDefine b/oap-server/server-receiver-plugin/skywalking-clr-receiver-plugin/src/main/resources/META-INF/services/org.apache.skywalking.oap.server.library.module.ModuleDefine new file mode 100644 index 0000000000..340e0442c1 --- /dev/null +++ b/oap-server/server-receiver-plugin/skywalking-clr-receiver-plugin/src/main/resources/META-INF/services/org.apache.skywalking.oap.server.library.module.ModuleDefine @@ -0,0 +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. +# +# + +org.apache.skywalking.oap.server.receiver.clr.module.CLRModule \ No newline at end of file diff --git a/oap-server/server-receiver-plugin/skywalking-clr-receiver-plugin/src/main/resources/META-INF/services/org.apache.skywalking.oap.server.library.module.ModuleProvider b/oap-server/server-receiver-plugin/skywalking-clr-receiver-plugin/src/main/resources/META-INF/services/org.apache.skywalking.oap.server.library.module.ModuleProvider new file mode 100644 index 0000000000..1d6ef7a292 --- /dev/null +++ b/oap-server/server-receiver-plugin/skywalking-clr-receiver-plugin/src/main/resources/META-INF/services/org.apache.skywalking.oap.server.library.module.ModuleProvider @@ -0,0 +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. +# +# + +org.apache.skywalking.oap.server.receiver.clr.provider.CLRModuleProvider \ No newline at end of file diff --git a/oap-server/server-starter/src/main/assembly/application.yml b/oap-server/server-starter/src/main/assembly/application.yml index 758d8490e0..a7326757ad 100644 --- a/oap-server/server-starter/src/main/assembly/application.yml +++ b/oap-server/server-starter/src/main/assembly/application.yml @@ -84,6 +84,8 @@ receiver-trace: slowDBAccessThreshold: ${SW_SLOW_DB_THRESHOLD:default:200,mongodb:100} # The slow database access thresholds. Unit ms. receiver-jvm: default: +receiver-clr: + default: service-mesh: default: bufferPath: ${SW_SERVICE_MESH_BUFFER_PATH:../mesh-buffer/} # Path to trace buffer files, suggest to use absolute path diff --git a/oap-server/server-starter/src/main/resources/application.yml b/oap-server/server-starter/src/main/resources/application.yml index bf0d748cae..0fdfe45f44 100644 --- a/oap-server/server-starter/src/main/resources/application.yml +++ b/oap-server/server-starter/src/main/resources/application.yml @@ -84,6 +84,8 @@ receiver-trace: slowDBAccessThreshold: ${SW_SLOW_DB_THRESHOLD:default:200,mongodb:100} # The slow database access thresholds. Unit ms. receiver-jvm: default: +receiver-clr: + default: service-mesh: default: bufferPath: ${SW_SERVICE_MESH_BUFFER_PATH:../mesh-buffer/} # Path to trace buffer files, suggest to use absolute path