fix: improve ClickHouse admin page, fix AgentHealth type error
Rewrite ClickHouse admin to show useful storage metrics instead of often-empty system.events data. Add active queries section. - Replace performance endpoint: query system.parts for disk size, uncompressed size, compression ratio, total rows, part count - Add /queries endpoint querying system.processes for active queries - Frontend: storage overview strip, tables with total size, active queries DataTable - Fix AgentHealth.tsx type: agentId → instanceId in inline type cast Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package com.cameleer3.server.app.controller;
|
||||
|
||||
import com.cameleer3.server.app.dto.ClickHousePerformanceResponse;
|
||||
import com.cameleer3.server.app.dto.ClickHouseQueryInfo;
|
||||
import com.cameleer3.server.app.dto.ClickHouseStatusResponse;
|
||||
import com.cameleer3.server.app.dto.ClickHouseTableInfo;
|
||||
import com.cameleer3.server.app.dto.IndexerPipelineResponse;
|
||||
@@ -80,20 +81,72 @@ public class ClickHouseAdminController {
|
||||
}
|
||||
|
||||
@GetMapping("/performance")
|
||||
@Operation(summary = "ClickHouse performance metrics")
|
||||
@Operation(summary = "ClickHouse storage and performance metrics")
|
||||
public ClickHousePerformanceResponse getPerformance() {
|
||||
try {
|
||||
long selectQueries = queryEvent("SelectQuery");
|
||||
long insertQueries = queryEvent("InsertQuery");
|
||||
long insertedRows = queryEvent("InsertedRows");
|
||||
long readRows = queryEvent("SelectedRows");
|
||||
String memoryUsage = clickHouseJdbc.queryForObject(
|
||||
"SELECT formatReadableSize(value) FROM system.metrics WHERE metric = 'MemoryTracking'",
|
||||
String.class);
|
||||
return new ClickHousePerformanceResponse(selectQueries, insertQueries,
|
||||
memoryUsage != null ? memoryUsage : "0 B", insertedRows, readRows);
|
||||
var row = clickHouseJdbc.queryForMap("""
|
||||
SELECT
|
||||
formatReadableSize(sum(bytes_on_disk)) AS disk_size,
|
||||
formatReadableSize(sum(data_uncompressed_bytes)) AS uncompressed_size,
|
||||
if(sum(data_uncompressed_bytes) > 0,
|
||||
round(sum(bytes_on_disk) / sum(data_uncompressed_bytes), 3), 0) AS compression_ratio,
|
||||
sum(rows) AS total_rows,
|
||||
count() AS part_count
|
||||
FROM system.parts
|
||||
WHERE database = currentDatabase() AND active
|
||||
""");
|
||||
|
||||
String memory = "N/A";
|
||||
try {
|
||||
memory = clickHouseJdbc.queryForObject(
|
||||
"SELECT formatReadableSize(value) FROM system.metrics WHERE metric = 'MemoryTracking'",
|
||||
String.class);
|
||||
} catch (Exception ignored) {}
|
||||
|
||||
int currentQueries = 0;
|
||||
try {
|
||||
Integer q = clickHouseJdbc.queryForObject(
|
||||
"SELECT toInt32(value) FROM system.metrics WHERE metric = 'Query'",
|
||||
Integer.class);
|
||||
if (q != null) currentQueries = q;
|
||||
} catch (Exception ignored) {}
|
||||
|
||||
return new ClickHousePerformanceResponse(
|
||||
(String) row.get("disk_size"),
|
||||
(String) row.get("uncompressed_size"),
|
||||
((Number) row.get("compression_ratio")).doubleValue(),
|
||||
((Number) row.get("total_rows")).longValue(),
|
||||
((Number) row.get("part_count")).intValue(),
|
||||
memory != null ? memory : "N/A",
|
||||
currentQueries);
|
||||
} catch (Exception e) {
|
||||
return new ClickHousePerformanceResponse(0, 0, "N/A", 0, 0);
|
||||
return new ClickHousePerformanceResponse("N/A", "N/A", 0, 0, 0, "N/A", 0);
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping("/queries")
|
||||
@Operation(summary = "Active ClickHouse queries")
|
||||
public List<ClickHouseQueryInfo> getQueries() {
|
||||
try {
|
||||
return clickHouseJdbc.query("""
|
||||
SELECT
|
||||
query_id,
|
||||
round(elapsed, 2) AS elapsed_seconds,
|
||||
formatReadableSize(memory_usage) AS memory,
|
||||
read_rows,
|
||||
substring(query, 1, 200) AS query
|
||||
FROM system.processes
|
||||
WHERE is_initial_query = 1
|
||||
ORDER BY elapsed DESC
|
||||
""",
|
||||
(rs, rowNum) -> new ClickHouseQueryInfo(
|
||||
rs.getString("query_id"),
|
||||
rs.getDouble("elapsed_seconds"),
|
||||
rs.getString("memory"),
|
||||
rs.getLong("read_rows"),
|
||||
rs.getString("query")));
|
||||
} catch (Exception e) {
|
||||
return List.of();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,11 +162,4 @@ public class ClickHouseAdminController {
|
||||
indexerStats.getIndexingRate(),
|
||||
indexerStats.getLastIndexedAt());
|
||||
}
|
||||
|
||||
private long queryEvent(String eventName) {
|
||||
Long val = clickHouseJdbc.queryForObject(
|
||||
"SELECT value FROM system.events WHERE event = ?",
|
||||
Long.class, eventName);
|
||||
return val != null ? val : 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,11 +2,13 @@ package com.cameleer3.server.app.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
@Schema(description = "ClickHouse performance metrics")
|
||||
@Schema(description = "ClickHouse storage and performance metrics")
|
||||
public record ClickHousePerformanceResponse(
|
||||
long queryCount,
|
||||
long insertQueryCount,
|
||||
String diskSize,
|
||||
String uncompressedSize,
|
||||
double compressionRatio,
|
||||
long totalRows,
|
||||
int partCount,
|
||||
String memoryUsage,
|
||||
long insertedRows,
|
||||
long readRows
|
||||
int currentQueries
|
||||
) {}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.cameleer3.server.app.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
|
||||
@Schema(description = "Active ClickHouse query information")
|
||||
public record ClickHouseQueryInfo(
|
||||
String queryId,
|
||||
double elapsedSeconds,
|
||||
String memory,
|
||||
long readRows,
|
||||
String query
|
||||
) {}
|
||||
Reference in New Issue
Block a user