[fix] make the Windows native collector start, and smoke test the packages in CI (#4379)

This commit is contained in:
Duansg
2026-09-13 19:18:08 +08:00
committed by GitHub
parent ec061f87db
commit a85bd46c18
2 changed files with 78 additions and 6 deletions
@@ -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:
@@ -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) {