You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by ke...@apache.org on 2021/03/16 12:37:28 UTC
[skywalking] 01/01: Collect and report agent starting / shutdown
events
This is an automated email from the ASF dual-hosted git repository.
kezhenxu94 pushed a commit to branch event/jvm
in repository https://gitbox.apache.org/repos/asf/skywalking.git
commit dc5c2dabd6381d2c06684b08bc20742b9ff8ab03
Author: kezhenxu94 <ke...@apache.org>
AuthorDate: Tue Mar 16 20:36:25 2021 +0800
Collect and report agent starting / shutdown events
---
...tService.java => ServiceInstanceGenerator.java} | 31 ++--
.../apm/agent/core/boot/BootService.java | 9 +
.../apm/agent/core/boot/ServiceManager.java | 4 +-
.../core/remote/EventReportServiceClient.java | 190 +++++++++++++++++++++
.../apm/agent/core/remote/GRPCChannelManager.java | 5 +
.../agent/core/remote/ServiceManagementClient.java | 8 +-
...ache.skywalking.apm.agent.core.boot.BootService | 3 +-
.../skywalking/oap/server/core/event/Event.java | 2 +-
8 files changed, 233 insertions(+), 19 deletions(-)
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/boot/BootService.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/ServiceInstanceGenerator.java
similarity index 52%
copy from apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/boot/BootService.java
copy to apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/ServiceInstanceGenerator.java
index eae8a5c..eff46e7 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/boot/BootService.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/ServiceInstanceGenerator.java
@@ -16,18 +16,29 @@
*
*/
-package org.apache.skywalking.apm.agent.core.boot;
+package org.apache.skywalking.apm.agent.core;
-/**
- * The <code>BootService</code> is an interface to all remote, which need to boot when plugin mechanism begins to work.
- * {@link #boot()} will be called when <code>BootService</code> start up.
- */
-public interface BootService {
- void prepare() throws Throwable;
+import java.util.UUID;
+import lombok.Getter;
+import lombok.experimental.Accessors;
+import org.apache.skywalking.apm.agent.core.conf.Config;
+import org.apache.skywalking.apm.agent.core.os.OSUtil;
+
+import static org.apache.skywalking.apm.util.StringUtil.isEmpty;
+
+@Getter
+@Accessors(fluent = true)
+public enum ServiceInstanceGenerator {
+ SINGLETON;
- void boot() throws Throwable;
+ private boolean isGenerated = false;
- void onComplete() throws Throwable;
+ public synchronized void generateIfNotSpecified() {
+ if (!isEmpty(Config.Agent.INSTANCE_NAME)) {
+ return;
+ }
- void shutdown() throws Throwable;
+ Config.Agent.INSTANCE_NAME = UUID.randomUUID().toString().replaceAll("-", "") + "@" + OSUtil.getIPV4();
+ isGenerated = true;
+ }
}
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/boot/BootService.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/boot/BootService.java
index eae8a5c..4907866 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/boot/BootService.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/boot/BootService.java
@@ -18,6 +18,8 @@
package org.apache.skywalking.apm.agent.core.boot;
+import org.apache.skywalking.apm.agent.core.remote.GRPCChannelManager;
+
/**
* The <code>BootService</code> is an interface to all remote, which need to boot when plugin mechanism begins to work.
* {@link #boot()} will be called when <code>BootService</code> start up.
@@ -30,4 +32,11 @@ public interface BootService {
void onComplete() throws Throwable;
void shutdown() throws Throwable;
+
+ /**
+ * @return the shutdown order that {@link ServiceManager} should respect to when shutting down the services, e.g. services depending on {@link GRPCChannelManager} should be shut down after it.
+ */
+ default int shutdownOrder() {
+ return 0;
+ }
}
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/boot/ServiceManager.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/boot/ServiceManager.java
index 46158cd..b2e9bdc 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/boot/ServiceManager.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/boot/ServiceManager.java
@@ -19,11 +19,13 @@
package org.apache.skywalking.apm.agent.core.boot;
import java.util.Collections;
+import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.ServiceLoader;
+import java.util.stream.Collectors;
import org.apache.skywalking.apm.agent.core.logging.api.ILog;
import org.apache.skywalking.apm.agent.core.logging.api.LogManager;
import org.apache.skywalking.apm.agent.core.plugin.loader.AgentClassLoader;
@@ -46,7 +48,7 @@ public enum ServiceManager {
}
public void shutdown() {
- for (BootService service : bootedServices.values()) {
+ for (BootService service : bootedServices.values().stream().sorted(Comparator.comparing(BootService::shutdownOrder)).collect(Collectors.toList())) {
try {
service.shutdown();
} catch (Throwable e) {
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/remote/EventReportServiceClient.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/remote/EventReportServiceClient.java
new file mode 100644
index 0000000..cad9ad3
--- /dev/null
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/remote/EventReportServiceClient.java
@@ -0,0 +1,190 @@
+/*
+ * 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.apm.agent.core.remote;
+
+import io.grpc.stub.StreamObserver;
+import java.lang.management.ManagementFactory;
+import java.lang.management.RuntimeMXBean;
+import java.util.UUID;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.stream.Collectors;
+import org.apache.skywalking.apm.agent.core.ServiceInstanceGenerator;
+import org.apache.skywalking.apm.agent.core.boot.BootService;
+import org.apache.skywalking.apm.agent.core.boot.DefaultImplementor;
+import org.apache.skywalking.apm.agent.core.boot.ServiceManager;
+import org.apache.skywalking.apm.agent.core.commands.CommandService;
+import org.apache.skywalking.apm.agent.core.conf.Config;
+import org.apache.skywalking.apm.agent.core.logging.api.ILog;
+import org.apache.skywalking.apm.agent.core.logging.api.LogManager;
+import org.apache.skywalking.apm.network.common.v3.Commands;
+import org.apache.skywalking.apm.network.event.v3.Event;
+import org.apache.skywalking.apm.network.event.v3.EventServiceGrpc;
+import org.apache.skywalking.apm.network.event.v3.Source;
+import org.apache.skywalking.apm.network.event.v3.Type;
+
+import static org.apache.skywalking.apm.agent.core.remote.GRPCChannelStatus.CONNECTED;
+
+@DefaultImplementor
+public class EventReportServiceClient implements BootService, GRPCChannelListener {
+ private static final ILog LOGGER = LogManager.getLogger(EventReportServiceClient.class);
+
+ private final AtomicBoolean reported = new AtomicBoolean();
+
+ private Event.Builder startingEvent;
+
+ private EventServiceGrpc.EventServiceStub eventServiceStub;
+
+ private GRPCChannelStatus status;
+
+ @Override
+ public void prepare() throws Throwable {
+ ServiceManager.INSTANCE.findService(GRPCChannelManager.class).addChannelListener(this);
+ ServiceInstanceGenerator.SINGLETON.generateIfNotSpecified();
+
+ if (ServiceInstanceGenerator.SINGLETON.isGenerated()) {
+ LOGGER.debug("The service instance is generated, no starting event will be reported");
+ return;
+ }
+
+ final RuntimeMXBean runtimeMxBean = ManagementFactory.getRuntimeMXBean();
+ startingEvent = Event.newBuilder()
+ .setUuid(UUID.randomUUID().toString())
+ .setName("Start")
+ .setStartTime(runtimeMxBean.getStartTime())
+ .setMessage("Start Java Application")
+ .setType(Type.Normal)
+ .setSource(
+ Source.newBuilder()
+ .setService(Config.Agent.SERVICE_NAME)
+ .setServiceInstance(Config.Agent.INSTANCE_NAME)
+ .build()
+ )
+ .putParameters(
+ "OPTS",
+ runtimeMxBean.getInputArguments()
+ .stream()
+ .sorted()
+ .collect(Collectors.joining(" "))
+ );
+ }
+
+ @Override
+ public void boot() throws Throwable {
+
+ }
+
+ @Override
+ public void onComplete() throws Throwable {
+ reportStartingEvent();
+ }
+
+ @Override
+ public void shutdown() throws Throwable {
+ if (ServiceInstanceGenerator.SINGLETON.isGenerated()) {
+ // If the agent service instance name is randomly generated, ignore the shutdown signal.
+ return;
+ }
+
+ if (!CONNECTED.equals(status)) {
+ return;
+ }
+
+ final CountDownLatch latch = new CountDownLatch(1);
+ final Event.Builder shutdownEvent = Event.newBuilder()
+ .setUuid(UUID.randomUUID().toString())
+ .setName("Shutdown")
+ .setStartTime(System.currentTimeMillis())
+ .setEndTime(System.currentTimeMillis())
+ .setMessage("Shutting down Java Application")
+ .setType(Type.Normal)
+ .setSource(
+ Source.newBuilder()
+ .setService(Config.Agent.SERVICE_NAME)
+ .setServiceInstance(Config.Agent.INSTANCE_NAME)
+ .build()
+ );
+
+ final StreamObserver<Event> collector = eventServiceStub.collect(new StreamObserver<Commands>() {
+ @Override
+ public void onNext(final Commands commands) {
+ ServiceManager.INSTANCE.findService(CommandService.class).receiveCommand(commands);
+ }
+
+ @Override
+ public void onError(final Throwable t) {
+ LOGGER.error("Failed to report shutdown event.", t);
+ // Ignore status change at shutting down stage.
+ latch.countDown();
+ }
+
+ @Override
+ public void onCompleted() {
+ latch.countDown();
+ }
+ });
+
+ collector.onNext(shutdownEvent.build());
+ collector.onCompleted();
+ latch.await();
+ }
+
+ @Override
+ public void statusChanged(final GRPCChannelStatus status) {
+ this.status = status;
+
+ if (!CONNECTED.equals(status)) {
+ return;
+ }
+
+ eventServiceStub = EventServiceGrpc.newStub(ServiceManager.INSTANCE.findService(GRPCChannelManager.class).getChannel());
+
+ reportStartingEvent();
+ }
+
+ private void reportStartingEvent() {
+ if (ServiceInstanceGenerator.SINGLETON.isGenerated() || reported.compareAndSet(false, true)) {
+ return;
+ }
+
+ startingEvent.setEndTime(System.currentTimeMillis());
+
+ final StreamObserver<Event> collector = eventServiceStub.collect(new StreamObserver<Commands>() {
+ @Override
+ public void onNext(final Commands commands) {
+ ServiceManager.INSTANCE.findService(CommandService.class).receiveCommand(commands);
+ }
+
+ @Override
+ public void onError(final Throwable t) {
+ LOGGER.error("Failed to report starting event.", t);
+ ServiceManager.INSTANCE.findService(GRPCChannelManager.class).reportError(t);
+ reported.set(false);
+
+ }
+
+ @Override
+ public void onCompleted() {
+ }
+ });
+
+ collector.onNext(startingEvent.build());
+ collector.onCompleted();
+ }
+}
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/remote/GRPCChannelManager.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/remote/GRPCChannelManager.java
index 4822c75..5a2ffb0 100755
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/remote/GRPCChannelManager.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/remote/GRPCChannelManager.java
@@ -208,4 +208,9 @@ public class GRPCChannelManager implements BootService, Runnable {
}
return false;
}
+
+ @Override
+ public int shutdownOrder() {
+ return Integer.MAX_VALUE;
+ }
}
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/remote/ServiceManagementClient.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/remote/ServiceManagementClient.java
index f271856..3d5437f 100755
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/remote/ServiceManagementClient.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/remote/ServiceManagementClient.java
@@ -21,11 +21,11 @@ package org.apache.skywalking.apm.agent.core.remote;
import io.grpc.Channel;
import java.util.ArrayList;
import java.util.List;
-import java.util.UUID;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
+import org.apache.skywalking.apm.agent.core.ServiceInstanceGenerator;
import org.apache.skywalking.apm.agent.core.boot.BootService;
import org.apache.skywalking.apm.agent.core.boot.DefaultImplementor;
import org.apache.skywalking.apm.agent.core.boot.DefaultNamedThreadFactory;
@@ -41,7 +41,6 @@ import org.apache.skywalking.apm.network.management.v3.InstancePingPkg;
import org.apache.skywalking.apm.network.management.v3.InstanceProperties;
import org.apache.skywalking.apm.network.management.v3.ManagementServiceGrpc;
import org.apache.skywalking.apm.util.RunnableWithExceptionProtection;
-import org.apache.skywalking.apm.util.StringUtil;
import static org.apache.skywalking.apm.agent.core.conf.Config.Collector.GRPC_UPSTREAM_TIMEOUT;
@@ -69,6 +68,7 @@ public class ServiceManagementClient implements BootService, Runnable, GRPCChann
@Override
public void prepare() {
ServiceManager.INSTANCE.findService(GRPCChannelManager.class).addChannelListener(this);
+ ServiceInstanceGenerator.SINGLETON.generateIfNotSpecified();
SERVICE_INSTANCE_PROPERTIES = new ArrayList<>();
@@ -78,10 +78,6 @@ public class ServiceManagementClient implements BootService, Runnable, GRPCChann
.setValue(Config.Agent.INSTANCE_PROPERTIES.get(key))
.build());
}
-
- Config.Agent.INSTANCE_NAME = StringUtil.isEmpty(Config.Agent.INSTANCE_NAME)
- ? UUID.randomUUID().toString().replaceAll("-", "") + "@" + OSUtil.getIPV4()
- : Config.Agent.INSTANCE_NAME;
}
@Override
diff --git a/apm-sniffer/apm-agent-core/src/main/resources/META-INF/services/org.apache.skywalking.apm.agent.core.boot.BootService b/apm-sniffer/apm-agent-core/src/main/resources/META-INF/services/org.apache.skywalking.apm.agent.core.boot.BootService
index bfa58a8..5b9d995 100644
--- a/apm-sniffer/apm-agent-core/src/main/resources/META-INF/services/org.apache.skywalking.apm.agent.core.boot.BootService
+++ b/apm-sniffer/apm-agent-core/src/main/resources/META-INF/services/org.apache.skywalking.apm.agent.core.boot.BootService
@@ -33,4 +33,5 @@ org.apache.skywalking.apm.agent.core.meter.MeterService
org.apache.skywalking.apm.agent.core.meter.MeterSender
org.apache.skywalking.apm.agent.core.context.status.StatusCheckService
org.apache.skywalking.apm.agent.core.remote.LogReportServiceClient
-org.apache.skywalking.apm.agent.core.conf.dynamic.ConfigurationDiscoveryService
\ No newline at end of file
+org.apache.skywalking.apm.agent.core.conf.dynamic.ConfigurationDiscoveryService
+org.apache.skywalking.apm.agent.core.remote.EventReportServiceClient
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/event/Event.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/event/Event.java
index 8fb26d0..7065589 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/event/Event.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/event/Event.java
@@ -95,7 +95,7 @@ public class Event extends Metrics {
@Column(columnName = MESSAGE)
private String message;
- @Column(columnName = PARAMETERS, storageOnly = true)
+ @Column(columnName = PARAMETERS, storageOnly = true, length = 1024)
private String parameters;
@Column(columnName = START_TIME)