This is an automated email from the ASF dual-hosted git repository.
Aias00 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hertzbeat.git
The following commit(s) were added to refs/heads/master by this push:
new a85bd46c18 [fix] make the Windows native collector start, and smoke
test the packages in CI (#4379)
a85bd46c18 is described below
commit a85bd46c18d33130298f0e223bd84ea6e29a17de
Author: Duansg <[email protected]>
AuthorDate: Sun Sep 13 19:18:08 2026 +0800
[fix] make the Windows native collector start, and smoke test the packages
in CI (#4379)
---
.github/workflows/collector-native-build.yml | 57 ++++++++++++++++++++++
.../collect/redis/RedisCommonCollectImpl.java | 27 +++++++---
2 files changed, 78 insertions(+), 6 deletions(-)
diff --git a/.github/workflows/collector-native-build.yml
b/.github/workflows/collector-native-build.yml
index 715526918a..3c8aadbf1f 100644
--- a/.github/workflows/collector-native-build.yml
+++ b/.github/workflows/collector-native-build.yml
@@ -75,6 +75,63 @@ jobs:
}
"archive=$($package.FullName)" >> $env:GITHUB_OUTPUT
+ - name: Smoke test native collector package
+ shell: pwsh
+ run: |
+ $ErrorActionPreference = "Stop"
+ $archive = "${{ steps.package.outputs.archive }}"
+ $work = Join-Path ([System.IO.Path]::GetTempPath()) "hzb-smoke"
+ Remove-Item -Recurse -Force $work -ErrorAction SilentlyContinue
+ New-Item -ItemType Directory -Path $work | Out-Null
+
+ if ($archive.EndsWith(".zip")) {
+ Expand-Archive -Path $archive -DestinationPath $work -Force
+ } else {
+ tar -xzf $archive -C $work
+ }
+
+ $binary = Get-ChildItem -Path $work -Recurse -File |
+ Where-Object { $_.Name -like "apache-hertzbeat-collector-native-*"
-and $_.Name -notlike "*.txt" } |
+ Where-Object { $_.Length -gt 10MB } | Select-Object -First 1
+ if (-not $binary) { throw "native executable not found in $archive" }
+ $conf = Join-Path $binary.DirectoryName "config"
+ Write-Host "executable: $($binary.FullName)"
+
+ $out = Join-Path $work "stdout.log"
+ $err = Join-Path $work "stderr.log"
+ $env:MANAGER_HOST = "127.0.0.1"
+ $env:IDENTITY = "ci-smoke-${{ matrix.platform }}"
+ $proc = Start-Process -FilePath $binary.FullName `
+ -ArgumentList
"--spring.config.location=$conf$([IO.Path]::DirectorySeparatorChar)" `
+ -RedirectStandardOutput $out -RedirectStandardError $err -PassThru
+
+ # The collector prints "Started Collector" before the runners
execute, and past
+ # failures crashed after that line, so wait for the ServiceLoader
registration too
+ # and then confirm the process is still alive.
+ $deadline = (Get-Date).AddSeconds(90)
+ $registered = $false
+ while ((Get-Date) -lt $deadline) {
+ Start-Sleep -Seconds 2
+ $log = (Get-Content $out, $err -ErrorAction SilentlyContinue)
-join "`n"
+ if ($log -match "collect strategies") { $registered = $true; break
}
+ if ($proc.HasExited) { break }
+ }
+
+ Start-Sleep -Seconds 10
+ $proc.Refresh()
+ $alive = -not $proc.HasExited
+ $exitCode = if ($alive) { $null } else { $proc.ExitCode }
+ if ($alive) { Stop-Process -Id $proc.Id -Force -ErrorAction
SilentlyContinue }
+
+ $log = (Get-Content $out, $err -ErrorAction SilentlyContinue) -join
"`n"
+ Write-Host "----- collector output (tail) -----"
+ Write-Host (($log -split "`n") | Select-Object -Last 40 | Out-String)
+ Write-Host "-----------------------------------"
+
+ if (-not $alive) { throw "collector process exited (exit code
$exitCode)" }
+ if (-not $registered) { throw "collector stayed up but never
registered its collect strategies" }
+ Write-Host "smoke test passed for ${{ matrix.platform }}"
+
- name: Upload native collector package
uses: actions/upload-artifact@v4
with:
diff --git
a/hertzbeat-collector/hertzbeat-collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/redis/RedisCommonCollectImpl.java
b/hertzbeat-collector/hertzbeat-collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/redis/RedisCommonCollectImpl.java
index ac520cf72b..c5b05ff148 100644
---
a/hertzbeat-collector/hertzbeat-collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/redis/RedisCommonCollectImpl.java
+++
b/hertzbeat-collector/hertzbeat-collector-basic/src/main/java/org/apache/hertzbeat/collector/collect/redis/RedisCommonCollectImpl.java
@@ -73,11 +73,26 @@ public class RedisCommonCollectImpl extends AbstractCollect
{
private static final String UNIQUE_IDENTITY = "identity";
- private final ClientResources defaultClientResources;
private final GlobalConnectionCache connectionCache =
GlobalConnectionCache.getInstance();
-
- public RedisCommonCollectImpl() {
- defaultClientResources = DefaultClientResources.create();
+
+ /**
+ * Holds the lettuce client resources, created on first use.
+ * <p>
+ * Loading {@link DefaultClientResources} runs a static initializer that
resolves netty's DNS
+ * address resolver group. That resolver is unavailable in a native image
on Windows, where it
+ * fails with a NullPointerException from
sun.net.dns.ResolverConfigurationImpl
+ * (see oracle/graal#11280 and oracle/graal#4304). Because every collector
is instantiated
+ * eagerly through the ServiceLoader at startup, doing this in the
constructor took the whole
+ * collector process down before it could serve anything. Deferring it
keeps startup working;
+ * on the platforms where the resolver is broken only Redis collection
fails, and it fails with
+ * a clear error at collect time.
+ */
+ private static final class ClientResourcesHolder {
+ private static final ClientResources INSTANCE =
DefaultClientResources.create();
+ }
+
+ private static ClientResources clientResources() {
+ return ClientResourcesHolder.INSTANCE;
}
@Override
@@ -292,7 +307,7 @@ public class RedisCommonCollectImpl extends AbstractCollect
{
* @return redis cluster client
*/
private RedisClusterClient buildClusterClient(RedisProtocol redisProtocol,
String host, String port) {
- return RedisClusterClient.create(defaultClientResources,
redisUri(redisProtocol, host, port));
+ return RedisClusterClient.create(clientResources(),
redisUri(redisProtocol, host, port));
}
/**
@@ -302,7 +317,7 @@ public class RedisCommonCollectImpl extends AbstractCollect
{
* @return redis single client
*/
private RedisClient buildSingleClient(RedisProtocol redisProtocol, String
host, String port) {
- return RedisClient.create(defaultClientResources,
redisUri(redisProtocol, host, port));
+ return RedisClient.create(clientResources(), redisUri(redisProtocol,
host, port));
}
private RedisURI redisUri(RedisProtocol redisProtocol, String host, String
port) {
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]