Skip to content
Open
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
6 changes: 3 additions & 3 deletions .github/workflows/publish-docker-e2e-service.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,14 @@ jobs:
restore-keys: |
${{ runner.os }}-maven-
- name: Log in to the Container registry
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
with:
registry: ${{ env.HUB }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Set up QEMU
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392
uses: docker/setup-qemu-action@06116385d9baf250c9f4dcb4858b16962ea869c3 # v4.1.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0
- name: Build and push images
run: make -C test build.e2e-service docker.push-e2e-service
6 changes: 3 additions & 3 deletions .github/workflows/publish-docker.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,15 @@ jobs:
echo "TAG=${{ github.sha }}" >> $GITHUB_ENV
fi
- name: Log in to the Container registry
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
with:
registry: ${{ env.DOCKER_REGISTRY }}
username: ${{ env.DOCKER_USERNAME }}
password: ${{ env.DOCKER_PASSWORD }}
- name: Set up QEMU
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392
uses: docker/setup-qemu-action@06116385d9baf250c9f4dcb4858b16962ea869c3 # v4.1.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0
- name: Build and push docker images based on Java 11
env:
SW_OAP_BASE_IMAGE: eclipse-temurin:11-jre
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/skywalking.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ jobs:
persist-credentials: false
- name: Filter
id: filter
uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36
uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # v4.0.1
with:
list-files: 'shell'
predicate-quantifier: 'every'
Expand Down Expand Up @@ -765,7 +765,7 @@ jobs:
name: dist
path: dist
- name: Login to ghcr
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
Expand Down Expand Up @@ -854,7 +854,7 @@ jobs:
find docker-images -name "*.tar" -exec docker load -i {} \;
find docker-images -name "*.tar" -exec rm {} \;
- name: Login to ghcr
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
Expand Down Expand Up @@ -926,7 +926,7 @@ jobs:
find docker-images -name "*.tar" -exec docker load -i {} \;
find docker-images -name "*.tar" -exec rm {} \;
- name: Login to ghcr
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
Expand Down Expand Up @@ -1042,7 +1042,7 @@ jobs:
name: dist
path: dist
- name: Login to ghcr
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9
uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v4.2.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
Expand Down
3 changes: 3 additions & 0 deletions docs/en/changes/changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,9 @@
admin-host only" entry above for the public REST retirement.

#### OAP Server
* Fix BanyanDB peer nodes permanently flooding `<metric> is not registered` when a node holds a live persist worker but its local `MetadataRegistry` schema cache was never populated for that model — e.g. a `withoutSchemaChange` peer apply or a runtime-rule bundled fall-over rebuilt the dispatch worker but skipped the populate, and nothing (the registry never evicts, the 30s reconcile only covers runtime-rule rows) ever re-derived it. The persist DAOs now self-heal a missing entry once with an RPC-free local re-derivation before failing, and the no-init defer poll loop retries a transient backend probe error instead of escaping and crash-looping the pod.
* Fix a v2 MAL `CounterWindow` key collision: `rate()` / `increase()` / `irate()` keyed each counter's sliding window on the rule's output metric name (the same for every input metric of a rule) instead of the counter's own name, so two or more counters that reduce to the same label set after `.sum(...)` shared one window and computed rates against each other's values — fabricating non-zero rates from unchanged counters (e.g. the BanyanDB liaison gRPC error rate read a steady non-zero off three frozen error counters). The window is now keyed by the counter's own metric name.
* Fix the v2 MAL Elvis operator `?:` to honor Groovy-falsy semantics. It compiled to `Optional.ofNullable(primary).orElse(fallback)`, applying the fallback only when the primary is `null`, so an empty-string primary kept `""` instead — e.g. a BanyanDB liaison `ServiceInstance` stored `node_type=""` rather than `n/a`, because `.sum([...,'node_type'])` fills an absent group-by label with `""`. The fallback now applies for falsy primaries such as null, false, numeric zero, and empty strings/containers.
* SWIP-15: rebuild BanyanDB self-observability around the cluster / container / group model (requires BanyanDB 0.11+). A BanyanDB cluster is modeled as one `Service`, each container as a `ServiceInstance` (role/tier as attributes), and each storage group as an `Endpoint`. The `otel-rules/banyandb/` rules are category-separated by role (`node_*` / `liaison_*` / `data_*` / `lifecycle_*`) and by data type (`measure_*` / `stream_*` / `trace_*` / `property_*`), mirroring the upstream FODC-proxy Grafana boards, and include queue batch/message granularity (apache/skywalking-banyandb#1169). Adds a `SERVICE_INSTANCE_RELATION` MAL scope and `serviceInstanceRelation(...)` builder powering a new intra-cluster pod-to-pod deployment topology (`banyandb-instance-relation.yaml`). The stale single-node `host_name` model is removed.
* Runtime MAL/LAL hot-update rules can declare `layerDefinitions:` to introduce new
layers. Ordinals are operator-pinned in the `100_000+` tier; the layer is
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -198,33 +198,27 @@ private void executeWithInput(
final Map<String, Object> inputSection,
final Map<String, Object> expectedSection) {
final String metricName = rule.getName();
// Unique per file+rule to isolate CounterWindow entries across files
final String cwMetricName = rule.getSourceFile().getName() + "/" + metricName;
final String expression = rule.getFullExpression();
final boolean hasIncrease = expression.contains(".increase(")
|| expression.contains(".rate(");

// v2 prime + v2 real (also consecutive, same delta)
// rate()/increase() resolve their lower bound from the process-wide
// CounterWindow.INSTANCE, keyed by each counter's own (name, labels) — not
// the rule-level metric name. Input counter names recur across rules and
// files, so without a reset one rule's prime/real pair would rate against
// another rule's leftover window samples. Clear it so each rule is isolated
// to its own prime (t0) + real (t0+2s) pair.
org.apache.skywalking.oap.meter.analyzer.v2.dsl.counter.CounterWindow.INSTANCE.reset();

// v2 prime + v2 real (consecutive scrapes 2 s apart, same delta)
final Map<String, org.apache.skywalking.oap.meter.analyzer.v2.dsl.SampleFamily> v2Data;
if (hasIncrease) {
try {
final Map<String, org.apache.skywalking.oap.meter.analyzer.v2.dsl.SampleFamily> primeData =
buildV2MockDataFromInput(inputSection, 0.5);
for (final org.apache.skywalking.oap.meter.analyzer.v2.dsl.SampleFamily s : primeData.values()) {
if (s != org.apache.skywalking.oap.meter.analyzer.v2.dsl.SampleFamily.EMPTY) {
s.context.setMetricName(cwMetricName);
}
}
v2MalExpr.run(primeData);
v2MalExpr.run(buildV2MockDataFromInput(inputSection, 0.5));
} catch (Exception ignored) {
}
}
v2Data = buildV2MockDataFromInput(inputSection, 1.0);
for (final org.apache.skywalking.oap.meter.analyzer.v2.dsl.SampleFamily s : v2Data.values()) {
if (s != org.apache.skywalking.oap.meter.analyzer.v2.dsl.SampleFamily.EMPTY) {
s.context.setMetricName(cwMetricName);
}
}

// V2 run
org.apache.skywalking.oap.meter.analyzer.v2.dsl.SampleFamily v2Sf;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -300,9 +300,13 @@ void generateClosureExpr(final StringBuilder sb,
} else if (expr instanceof MALExpressionModel.ClosureElvisExpr) {
final MALExpressionModel.ClosureElvisExpr elvis =
(MALExpressionModel.ClosureElvisExpr) expr;
sb.append("java.util.Optional.ofNullable(");
// Groovy `?:` applies the fallback when the primary is falsy (null,
// empty string/container, numeric zero, false), not only when null.
// Keep the primary single-evaluated so expressions such as tags.remove(...)
// do not observe different values between the truth check and result.
sb.append(MALCodegenHelper.RUNTIME_HELPER_FQCN).append(".elvis(");
generateClosureExpr(sb, elvis.getPrimary(), paramName, beanMode);
sb.append(").orElse(");
sb.append(", ");
generateClosureExpr(sb, elvis.getFallback(), paramName, beanMode);
sb.append(")");
} else if (expr instanceof MALExpressionModel.ClosureRegexMatchExpr) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@

package org.apache.skywalking.oap.meter.analyzer.v2.compiler.rt;

import java.lang.reflect.Array;
import java.util.Collection;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.skywalking.oap.meter.analyzer.v2.dsl.Sample;
Expand Down Expand Up @@ -55,12 +58,9 @@ public static String[][] regexMatch(final String input, final String regex) {
return new String[][] {row};
}

/**
* Reverse division: computes {@code numerator / v} for each sample value {@code v}.
* Used by generated code for {@code Number / SampleFamily} expressions.
*/
/**
* Groovy truth check: {@code null → false}, empty string → {@code false},
* numeric zero → {@code false}, empty collection/map/array → {@code false},
* {@code Boolean.FALSE → false}, everything else → {@code true}.
* Used by generated filter code for standalone expressions in boolean context
* (e.g., {@code tags.ApiId || tags.ApiName}).
Expand All @@ -75,9 +75,29 @@ public static boolean isTruthy(final Object value) {
if (value instanceof CharSequence) {
return ((CharSequence) value).length() > 0;
}
if (value instanceof Number) {
return ((Number) value).doubleValue() != 0.0D;
}
if (value instanceof Collection) {
return !((Collection<?>) value).isEmpty();
}
if (value instanceof Map) {
return !((Map<?, ?>) value).isEmpty();
}
if (value.getClass().isArray()) {
return Array.getLength(value) > 0;
}
return true;
}

public static <T> T elvis(final T primary, final T fallback) {
return isTruthy(primary) ? primary : fallback;
}

/**
* Reverse division: computes {@code numerator / v} for each sample value {@code v}.
* Used by generated code for {@code Number / SampleFamily} expressions.
*/
public static SampleFamily divReverse(final double numerator,
final SampleFamily sf) {
if (sf == SampleFamily.EMPTY) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,7 @@ public SampleFamily increase(String range) {
Arrays.stream(samples)
.map(sample -> sample.increase(
range,
context.metricName,
sample.getName(),
(lowerBoundValue, unused) -> sample.value - lowerBoundValue
))
.toArray(Sample[]::new)
Expand All @@ -448,7 +448,7 @@ public SampleFamily rate(String range) {
Arrays.stream(samples)
.map(sample -> sample.increase(
range,
context.metricName,
sample.getName(),
(lowerBoundValue, lowerBoundTime) -> {
final long timeDiff = (sample.timestamp - lowerBoundTime) / 1000;
return timeDiff < 1L ? 0.0 : (sample.value - lowerBoundValue) / timeDiff;
Expand All @@ -466,7 +466,7 @@ public SampleFamily irate() {
this.context,
Arrays.stream(samples)
.map(sample -> sample.increase(
context.metricName,
sample.getName(),
(lowerBoundValue, lowerBoundTime) -> {
final long timeDiff = (sample.timestamp - lowerBoundTime) / 1000;
return timeDiff < 1L ? 0.0 : (sample.value - lowerBoundValue) / timeDiff;
Expand Down
Loading
Loading