You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by wu...@apache.org on 2026/10/07 00:22:58 UTC
(skywalking) branch fix/endpoint-meta-last-ping created (now 737c26410f)
This is an automated email from the ASF dual-hosted git repository.
wu-sheng pushed a change to branch fix/endpoint-meta-last-ping
in repository https://gitbox.apache.org/repos/asf/skywalking.git
at 737c26410f Fix endpoints from logs missing from findEndpoint with a time range
This branch includes the following new commits:
new 737c26410f Fix endpoints from logs missing from findEndpoint with a time range
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
(skywalking) 01/01: Fix endpoints from logs missing from findEndpoint with a time range
Posted by wu...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
wu-sheng pushed a commit to branch fix/endpoint-meta-last-ping
in repository https://gitbox.apache.org/repos/asf/skywalking.git
commit 737c26410fec5e85de1e3aa244f8c1ae905b336a
Author: Wu Sheng <wu...@foxmail.com>
AuthorDate: Wed Oct 7 08:20:57 2026 +0800
Fix endpoints from logs missing from findEndpoint with a time range
findEndpoint with a duration filters on endpoint_traffic.last_ping, which
#12693 added and set only in EndpointTrafficDispatcher. EndpointMetaDispatcher
(logs, virtual MQ, cross-thread parent endpoints) and HubbleEndpointDispatcher
never set it, so those endpoints kept last_ping at 0. EndpointTraffic.combine
copied the newer record's last_ping, so an EndpointMeta write also reset a
trace endpoint's last_ping to 0.
Set last_ping in both dispatchers, and keep the larger last_ping on combine.
Closes #14121.
---
docs/en/changes/changes.md | 1 +
.../manual/endpoint/EndpointMetaDispatcher.java | 1 +
.../analysis/manual/endpoint/EndpointTraffic.java | 3 +-
.../manual/endpoint/HubbleEndpointDispatcher.java | 1 +
.../endpoint/EndpointTrafficDispatchersTest.java | 95 ++++++++++++++++++++++
.../manual/endpoint/EndpointTrafficTest.java | 23 ++++++
6 files changed, 123 insertions(+), 1 deletion(-)
diff --git a/docs/en/changes/changes.md b/docs/en/changes/changes.md
index 83c4567bfa..b103d88c0a 100644
--- a/docs/en/changes/changes.md
+++ b/docs/en/changes/changes.md
@@ -33,6 +33,7 @@
* Fix the OpenTelemetry receiver creating no Linux or Windows host service from an OpenTelemetry Collector `0.127.0` or later. The Collector's Prometheus receiver sends a scraped target's host only as `server.address` from that release, no longer as `net.host.name`, and `vm.yaml` and `windows.yaml` name a host by `node_identifier_host_name`, which the receiver took only from `net.host.name` or `host.name`. It now falls back to `server.address` when neither is present.
* AI agent conversations adopt AI Sessionizer `130601c`. Calls to MCP servers: the `execution` kind the Sessionizer's Claude Code plugin writes, `streams/<stream>/execution-<stamp>-<seq>.sd`, is stored like any other file; the document lists every `execution/1` record under `tool_executions`, joined to its step by tool-use id and kept once by its own id, a tool step names its records under `executions`, and a call to an MCP server carries `mcp_server` and `mcp_tool` in its `attrs`. The n [...]
* Fix the Elasticsearch `BulkProcessor` treating a bulk write as fully successful whenever the overall HTTP status was 200, even when Elasticsearch rejected individual items in the same response, for example a 429 `cluster_block_exception` when an index is switched to `read_only_allow_delete` by the flood-stage disk watermark. The response body's `errors` flag and per-item `status`/`error` are now decoded and checked on every 200 response; a rejected request's future now completes except [...]
+* Fix endpoints registered from logs missing from `findEndpoint` (the endpoint list) when it is queried with a time range. The query filters on an endpoint's `last_ping`, which endpoints registered from logs, from virtual MQ spans, from cross-thread segment references and from Cilium Hubble never set, so they kept `last_ping` at `0`, and an endpoint also seen in traces was reset to `0` whenever one of those sources wrote it last. Every endpoint source now sets `last_ping`, and an update [...]
#### UI
* Add a Virtual GenAI evaluation-record page and evaluation-score chart in Horizon UI, so operators can inspect evaluation result, level, reason, judge model, timestamp, trace linkage, and the `gen_ai_model_evaluation_score_ppm` trend for evaluated records.
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/endpoint/EndpointMetaDispatcher.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/endpoint/EndpointMetaDispatcher.java
index fa5fe487b6..03860d7b14 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/endpoint/EndpointMetaDispatcher.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/endpoint/EndpointMetaDispatcher.java
@@ -29,6 +29,7 @@ public class EndpointMetaDispatcher implements SourceDispatcher<EndpointMeta> {
traffic.setTimeBucket(source.getTimeBucket());
traffic.setName(source.getEndpoint());
traffic.setServiceId(source.getServiceId());
+ traffic.setLastPingTimestamp(source.getTimeBucket());
MetricsStreamProcessor.getInstance().in(traffic);
}
}
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/endpoint/EndpointTraffic.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/endpoint/EndpointTraffic.java
index b5d80b776c..4cb6a7b1dc 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/endpoint/EndpointTraffic.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/endpoint/EndpointTraffic.java
@@ -129,7 +129,8 @@ public class EndpointTraffic extends Metrics {
@Override
public boolean combine(final Metrics metrics) {
final EndpointTraffic endpointTraffic = (EndpointTraffic) metrics;
- this.lastPingTimestamp = endpointTraffic.getLastPingTimestamp();
+ // Several sources feed one endpoint, and a late one may carry an older minute.
+ this.lastPingTimestamp = Math.max(this.lastPingTimestamp, endpointTraffic.getLastPingTimestamp());
return true;
}
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/endpoint/HubbleEndpointDispatcher.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/endpoint/HubbleEndpointDispatcher.java
index d7abf0898b..29749eaf6e 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/endpoint/HubbleEndpointDispatcher.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/analysis/manual/endpoint/HubbleEndpointDispatcher.java
@@ -29,6 +29,7 @@ public class HubbleEndpointDispatcher implements SourceDispatcher<CiliumEndpoint
traffic.setTimeBucket(source.getTimeBucket());
traffic.setName(source.getEndpointName());
traffic.setServiceId(source.getServiceId());
+ traffic.setLastPingTimestamp(source.getTimeBucket());
MetricsStreamProcessor.getInstance().in(traffic);
}
}
diff --git a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/manual/endpoint/EndpointTrafficDispatchersTest.java b/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/manual/endpoint/EndpointTrafficDispatchersTest.java
new file mode 100644
index 0000000000..63b4e5e2d1
--- /dev/null
+++ b/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/manual/endpoint/EndpointTrafficDispatchersTest.java
@@ -0,0 +1,95 @@
+/*
+ * 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.core.analysis.manual.endpoint;
+
+import org.apache.skywalking.oap.server.core.analysis.Layer;
+import org.apache.skywalking.oap.server.core.analysis.metrics.Metrics;
+import org.apache.skywalking.oap.server.core.analysis.worker.MetricsStreamProcessor;
+import org.apache.skywalking.oap.server.core.source.CiliumEndpoint;
+import org.apache.skywalking.oap.server.core.source.EndpointMeta;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.MockedStatic;
+import org.mockito.Mockito;
+
+import static org.mockito.Mockito.verify;
+
+/**
+ * {@code findEndpoint} with a duration filters on {@link EndpointTraffic#LAST_PING_TIME_BUCKET}, so every
+ * dispatcher writing {@link EndpointTraffic} must set it.
+ */
+public class EndpointTrafficDispatchersTest {
+ private static final long TIME_BUCKET = 202610071230L;
+
+ private MockedStatic<MetricsStreamProcessor> mockedProcessor;
+ private MetricsStreamProcessor processorMock;
+
+ @BeforeEach
+ public void setup() {
+ processorMock = Mockito.mock(MetricsStreamProcessor.class);
+ mockedProcessor = Mockito.mockStatic(MetricsStreamProcessor.class);
+ mockedProcessor.when(MetricsStreamProcessor::getInstance).thenReturn(processorMock);
+ }
+
+ @AfterEach
+ public void tearDown() {
+ mockedProcessor.close();
+ }
+
+ @Test
+ public void testEndpointMetaSetsLastPing() {
+ final EndpointMeta source = new EndpointMeta();
+ source.setServiceName("repro-svc");
+ source.setServiceNormal(true);
+ source.setEndpoint("/repro/endpoint");
+ source.setTimeBucket(TIME_BUCKET);
+ source.prepare();
+
+ new EndpointMetaDispatcher().dispatch(source);
+
+ final EndpointTraffic traffic = captureTraffic();
+ Assertions.assertEquals("/repro/endpoint", traffic.getName());
+ Assertions.assertEquals(TIME_BUCKET, traffic.getLastPingTimestamp());
+ }
+
+ @Test
+ public void testHubbleEndpointSetsLastPing() {
+ final CiliumEndpoint source = new CiliumEndpoint();
+ source.setServiceName("cilium-svc");
+ source.setLayer(Layer.CILIUM_SERVICE);
+ source.setEndpointName("/cilium/endpoint");
+ source.setTimeBucket(TIME_BUCKET);
+ source.prepare();
+
+ new HubbleEndpointDispatcher().dispatch(source);
+
+ final EndpointTraffic traffic = captureTraffic();
+ Assertions.assertEquals("/cilium/endpoint", traffic.getName());
+ Assertions.assertEquals(TIME_BUCKET, traffic.getLastPingTimestamp());
+ }
+
+ private EndpointTraffic captureTraffic() {
+ final ArgumentCaptor<Metrics> captor = ArgumentCaptor.forClass(Metrics.class);
+ verify(processorMock).in(captor.capture());
+ return (EndpointTraffic) captor.getValue();
+ }
+}
diff --git a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/manual/endpoint/EndpointTrafficTest.java b/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/manual/endpoint/EndpointTrafficTest.java
index a6f956e582..2646566792 100644
--- a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/manual/endpoint/EndpointTrafficTest.java
+++ b/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/analysis/manual/endpoint/EndpointTrafficTest.java
@@ -59,4 +59,27 @@ public class EndpointTrafficTest {
Assertions.assertEquals(endpointTraffic, another);
}
+
+ @Test
+ public void testCombineKeepsLatestLastPing() {
+ final EndpointTraffic stored = newTraffic(202003281425L);
+
+ stored.combine(newTraffic(0L));
+ Assertions.assertEquals(202003281425L, stored.getLastPingTimestamp());
+
+ stored.combine(newTraffic(202003281421L));
+ Assertions.assertEquals(202003281425L, stored.getLastPingTimestamp());
+
+ stored.combine(newTraffic(202003281430L));
+ Assertions.assertEquals(202003281430L, stored.getLastPingTimestamp());
+ }
+
+ private static EndpointTraffic newTraffic(final long lastPing) {
+ final EndpointTraffic traffic = new EndpointTraffic();
+ traffic.setTimeBucket(202003281420L);
+ traffic.setServiceId("mock_id");
+ traffic.setName("/endpoint-123");
+ traffic.setLastPingTimestamp(lastPing);
+ return traffic;
+ }
}