Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/en/changes/changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
* Sync the Envoy access log proto, `envoy/data/accesslog/v3/accesslog.proto`, with Envoy v1.40.0, adding the `envoy/annotations/deprecation.proto` it imports. With it, the Envoy ALS sidecar internal latencies leave out what the access log cannot measure instead of counting it: the internal request latency of an HTTP request Envoy retried or hedged, or of a TCP connection that took more than one connect attempt (`upstream_request_attempt_count` above 1), as Envoy measures the upstream timings from the start of the downstream request or connection, so the time to the first upstream byte can include the earlier attempts and the delays between them; and the internal response latency when the response details are set to anything but `via_upstream`, as for Envoy's own 504 of a timeout during a retry backoff, which can carry an earlier attempt's upstream timing, and, conservatively, for an upstream response that a later reset or timeout ended. The adapters report such a latency as `-1`, and the `*_sidecar_internal_req_latency_nanos` and `*_sidecar_internal_resp_latency_nanos` metrics in `mesh.oal` filter it out with `filter(... >= 0)`. A customized `mesh.oal` needs the same filters, or the `-1` values are averaged in.
* Fix OAL `>`, `>=`, `<` and `<=` filters on a `long` or `double` source field, and `==` on a `long` one, failing to compile when they compare it with a number, such as `filter(sideCar.internalRequestLatencyNanos >= 0)`. The generated code passed the number as an `int`, and the comparison matchers have no `match(long, int)` or `match(double, int)` overload, as Javassist does not widen an argument. The number is now written in the field's type, `0L` or `0.0`; filters on `int` fields, which already worked, generate the same code.
* Add `ZIPKIN` to the GenAI evaluation record's `traceRef.type`, for spans received by `receiver-zipkin` and OTLP spans converted with `otlpTraceStorage: zipkin`, so the type names the store holding the judged span: `SKYWALKING_NATIVE`, `OTLP` for OTLP spans stored natively, or `ZIPKIN`. Zipkin and OTLP spans are both addressed by span ID, and one OAP can hold both, so an `OTLP` reference alone could not tell a client which store to read the trace from. The type is decided when the span is received, so records written under different `otlpTraceStorage` settings each name their own store.
* Fix the Zabbix receiver dropping the sub-second part of agent sample times. Each `agent data` item carries `clock` (Unix seconds) and `ns` (nanoseconds within that second), but the sample time used only `clock * 1000`; it is now `clock * 1000 + ns / 1_000_000`. The sub-second precision can affect values produced by custom Zabbix rules using MAL `rate`, `irate` or `increase`; results from the bundled Zabbix rules and the assignment of samples to minute buckets are unchanged.

#### 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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,15 @@ private void initConfigs(MeterSystem meterSystem) {
}).appendMetrics(c)));
}

/**
* Sample time in milliseconds. {@code clockSeconds} is the Unix second and {@code nanos} is the
* nanoseconds within that second. Meter samples are milliseconds, so the sub-millisecond part of
* {@code nanos} is dropped.
*/
static long sampleTimeMillis(final long clockSeconds, final long nanos) {
return TimeUnit.SECONDS.toMillis(clockSeconds) + TimeUnit.NANOSECONDS.toMillis(nanos);
}

/**
* Metrics convert to meter system statics
*/
Expand Down Expand Up @@ -272,7 +281,7 @@ private SampleBuilder parseAgentData(ZabbixRequest.AgentData data) {
}

return builder.hostName(data.getHost())
.timestamp(TimeUnit.SECONDS.toMillis(data.getClock()))
.timestamp(sampleTimeMillis(data.getClock(), data.getNs()))
.value(Double.parseDouble(data.getValue()))
.build();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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.zabbix.provider;

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class ZabbixMetricsTimestampTest {

@Test
public void sampleTimeKeepsMillisecondsFromNs() {
assertEquals(1_609_588_563_087L, ZabbixMetrics.sampleTimeMillis(1_609_588_563L, 87_682_907L));
assertEquals(1_609_588_563_000L, ZabbixMetrics.sampleTimeMillis(1_609_588_563L, 0L));
assertEquals(1_609_588_563_000L, ZabbixMetrics.sampleTimeMillis(1_609_588_563L, 999_999L));
assertEquals(1_609_588_563_001L, ZabbixMetrics.sampleTimeMillis(1_609_588_563L, 1_000_000L));
assertEquals(1_609_588_563_999L, ZabbixMetrics.sampleTimeMillis(1_609_588_563L, 999_999_999L));
}
}
Loading