fix: Runtime tab respects selected environment
- Add environment parameter to AgentEventsController, AgentEventService, and ClickHouseAgentEventRepository (filters agent_events by environment) - Wire selectedEnv to useAgents and useAgentEvents in both AgentHealth and AgentInstance pages - Wire selectedEnv to useStatsTimeseries in AgentInstance Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -32,6 +32,7 @@ public class AgentEventsController {
|
|||||||
public ResponseEntity<List<AgentEventResponse>> getEvents(
|
public ResponseEntity<List<AgentEventResponse>> getEvents(
|
||||||
@RequestParam(required = false) String appId,
|
@RequestParam(required = false) String appId,
|
||||||
@RequestParam(required = false) String agentId,
|
@RequestParam(required = false) String agentId,
|
||||||
|
@RequestParam(required = false) String environment,
|
||||||
@RequestParam(required = false) String from,
|
@RequestParam(required = false) String from,
|
||||||
@RequestParam(required = false) String to,
|
@RequestParam(required = false) String to,
|
||||||
@RequestParam(defaultValue = "50") int limit) {
|
@RequestParam(defaultValue = "50") int limit) {
|
||||||
@@ -39,7 +40,7 @@ public class AgentEventsController {
|
|||||||
Instant fromInstant = from != null ? Instant.parse(from) : null;
|
Instant fromInstant = from != null ? Instant.parse(from) : null;
|
||||||
Instant toInstant = to != null ? Instant.parse(to) : null;
|
Instant toInstant = to != null ? Instant.parse(to) : null;
|
||||||
|
|
||||||
var events = agentEventService.queryEvents(appId, agentId, fromInstant, toInstant, limit)
|
var events = agentEventService.queryEvents(appId, agentId, environment, fromInstant, toInstant, limit)
|
||||||
.stream()
|
.stream()
|
||||||
.map(AgentEventResponse::from)
|
.map(AgentEventResponse::from)
|
||||||
.toList();
|
.toList();
|
||||||
|
|||||||
@@ -38,6 +38,11 @@ public class ClickHouseAgentEventRepository implements AgentEventRepository {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<AgentEventRecord> query(String applicationId, String instanceId, Instant from, Instant to, int limit) {
|
public List<AgentEventRecord> query(String applicationId, String instanceId, Instant from, Instant to, int limit) {
|
||||||
|
return query(applicationId, instanceId, null, from, to, limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<AgentEventRecord> query(String applicationId, String instanceId, String environment, Instant from, Instant to, int limit) {
|
||||||
var sql = new StringBuilder(SELECT_BASE);
|
var sql = new StringBuilder(SELECT_BASE);
|
||||||
var params = new ArrayList<Object>();
|
var params = new ArrayList<Object>();
|
||||||
params.add(tenantId);
|
params.add(tenantId);
|
||||||
@@ -50,6 +55,10 @@ public class ClickHouseAgentEventRepository implements AgentEventRepository {
|
|||||||
sql.append(" AND instance_id = ?");
|
sql.append(" AND instance_id = ?");
|
||||||
params.add(instanceId);
|
params.add(instanceId);
|
||||||
}
|
}
|
||||||
|
if (environment != null) {
|
||||||
|
sql.append(" AND environment = ?");
|
||||||
|
params.add(environment);
|
||||||
|
}
|
||||||
if (from != null) {
|
if (from != null) {
|
||||||
sql.append(" AND timestamp >= ?");
|
sql.append(" AND timestamp >= ?");
|
||||||
params.add(Timestamp.from(from));
|
params.add(Timestamp.from(from));
|
||||||
|
|||||||
@@ -8,4 +8,6 @@ public interface AgentEventRepository {
|
|||||||
void insert(String instanceId, String applicationId, String eventType, String detail);
|
void insert(String instanceId, String applicationId, String eventType, String detail);
|
||||||
|
|
||||||
List<AgentEventRecord> query(String applicationId, String instanceId, Instant from, Instant to, int limit);
|
List<AgentEventRecord> query(String applicationId, String instanceId, Instant from, Instant to, int limit);
|
||||||
|
|
||||||
|
List<AgentEventRecord> query(String applicationId, String instanceId, String environment, Instant from, Instant to, int limit);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,4 +24,8 @@ public class AgentEventService {
|
|||||||
public List<AgentEventRecord> queryEvents(String applicationId, String instanceId, Instant from, Instant to, int limit) {
|
public List<AgentEventRecord> queryEvents(String applicationId, String instanceId, Instant from, Instant to, int limit) {
|
||||||
return repository.query(applicationId, instanceId, from, to, limit);
|
return repository.query(applicationId, instanceId, from, to, limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<AgentEventRecord> queryEvents(String applicationId, String instanceId, String environment, Instant from, Instant to, int limit) {
|
||||||
|
return repository.query(applicationId, instanceId, environment, from, to, limit);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,15 +27,16 @@ export function useAgents(status?: string, application?: string, environment?: s
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useAgentEvents(appId?: string, agentId?: string, limit = 50, toOverride?: string) {
|
export function useAgentEvents(appId?: string, agentId?: string, limit = 50, toOverride?: string, environment?: string) {
|
||||||
const refetchInterval = useRefreshInterval(15_000);
|
const refetchInterval = useRefreshInterval(15_000);
|
||||||
return useQuery({
|
return useQuery({
|
||||||
queryKey: ['agents', 'events', appId, agentId, limit, toOverride],
|
queryKey: ['agents', 'events', appId, agentId, limit, toOverride, environment],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const token = useAuthStore.getState().accessToken;
|
const token = useAuthStore.getState().accessToken;
|
||||||
const params = new URLSearchParams();
|
const params = new URLSearchParams();
|
||||||
if (appId) params.set('appId', appId);
|
if (appId) params.set('appId', appId);
|
||||||
if (agentId) params.set('agentId', agentId);
|
if (agentId) params.set('agentId', agentId);
|
||||||
|
if (environment) params.set('environment', environment);
|
||||||
if (toOverride) params.set('to', toOverride);
|
if (toOverride) params.set('to', toOverride);
|
||||||
params.set('limit', String(limit));
|
params.set('limit', String(limit));
|
||||||
const res = await fetch(`${config.apiBaseUrl}/agents/events-log?${params}`, {
|
const res = await fetch(`${config.apiBaseUrl}/agents/events-log?${params}`, {
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import logStyles from '../../styles/log-panel.module.css';
|
|||||||
import { useAgents, useAgentEvents } from '../../api/queries/agents';
|
import { useAgents, useAgentEvents } from '../../api/queries/agents';
|
||||||
import { useApplicationLogs } from '../../api/queries/logs';
|
import { useApplicationLogs } from '../../api/queries/logs';
|
||||||
import { useApplicationConfig, useUpdateApplicationConfig } from '../../api/queries/commands';
|
import { useApplicationConfig, useUpdateApplicationConfig } from '../../api/queries/commands';
|
||||||
|
import { useEnvironmentStore } from '../../api/environment-store';
|
||||||
import type { ConfigUpdateResponse } from '../../api/queries/commands';
|
import type { ConfigUpdateResponse } from '../../api/queries/commands';
|
||||||
import type { AgentInstance } from '../../api/types';
|
import type { AgentInstance } from '../../api/types';
|
||||||
import { timeAgo } from '../../utils/format-utils';
|
import { timeAgo } from '../../utils/format-utils';
|
||||||
@@ -91,7 +92,8 @@ export default function AgentHealth() {
|
|||||||
const { appId } = useParams();
|
const { appId } = useParams();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { toast } = useToast();
|
const { toast } = useToast();
|
||||||
const { data: agents } = useAgents(undefined, appId);
|
const selectedEnv = useEnvironmentStore((s) => s.environment);
|
||||||
|
const { data: agents } = useAgents(undefined, appId, selectedEnv);
|
||||||
const { data: appConfig } = useApplicationConfig(appId);
|
const { data: appConfig } = useApplicationConfig(appId);
|
||||||
const updateConfig = useUpdateApplicationConfig();
|
const updateConfig = useUpdateApplicationConfig();
|
||||||
|
|
||||||
@@ -131,7 +133,7 @@ export default function AgentHealth() {
|
|||||||
}, [appConfig, configDraft, updateConfig, toast, appId]);
|
}, [appConfig, configDraft, updateConfig, toast, appId]);
|
||||||
const [eventSortAsc, setEventSortAsc] = useState(false);
|
const [eventSortAsc, setEventSortAsc] = useState(false);
|
||||||
const [eventRefreshTo, setEventRefreshTo] = useState<string | undefined>();
|
const [eventRefreshTo, setEventRefreshTo] = useState<string | undefined>();
|
||||||
const { data: events } = useAgentEvents(appId, undefined, 50, eventRefreshTo);
|
const { data: events } = useAgentEvents(appId, undefined, 50, eventRefreshTo, selectedEnv);
|
||||||
|
|
||||||
const [logSearch, setLogSearch] = useState('');
|
const [logSearch, setLogSearch] = useState('');
|
||||||
const [logLevels, setLogLevels] = useState<Set<string>>(new Set());
|
const [logLevels, setLogLevels] = useState<Set<string>>(new Set());
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import { useApplicationLogs } from '../../api/queries/logs';
|
|||||||
import { useStatsTimeseries } from '../../api/queries/executions';
|
import { useStatsTimeseries } from '../../api/queries/executions';
|
||||||
import { useAgentMetrics } from '../../api/queries/agent-metrics';
|
import { useAgentMetrics } from '../../api/queries/agent-metrics';
|
||||||
import { formatUptime, mapLogLevel, eventSeverity, eventIcon } from '../../utils/agent-utils';
|
import { formatUptime, mapLogLevel, eventSeverity, eventIcon } from '../../utils/agent-utils';
|
||||||
|
import { useEnvironmentStore } from '../../api/environment-store';
|
||||||
|
|
||||||
const LOG_LEVEL_ITEMS: ButtonGroupItem[] = [
|
const LOG_LEVEL_ITEMS: ButtonGroupItem[] = [
|
||||||
{ value: 'error', label: 'Error', color: 'var(--error)' },
|
{ value: 'error', label: 'Error', color: 'var(--error)' },
|
||||||
@@ -36,9 +37,10 @@ export default function AgentInstance() {
|
|||||||
const timeFrom = timeRange.start.toISOString();
|
const timeFrom = timeRange.start.toISOString();
|
||||||
const timeTo = timeRange.end.toISOString();
|
const timeTo = timeRange.end.toISOString();
|
||||||
|
|
||||||
const { data: agents, isLoading } = useAgents(undefined, appId);
|
const selectedEnv = useEnvironmentStore((s) => s.environment);
|
||||||
const { data: events } = useAgentEvents(appId, instanceId, 50, eventRefreshTo);
|
const { data: agents, isLoading } = useAgents(undefined, appId, selectedEnv);
|
||||||
const { data: timeseries } = useStatsTimeseries(timeFrom, timeTo, undefined, appId);
|
const { data: events } = useAgentEvents(appId, instanceId, 50, eventRefreshTo, selectedEnv);
|
||||||
|
const { data: timeseries } = useStatsTimeseries(timeFrom, timeTo, undefined, appId, selectedEnv);
|
||||||
|
|
||||||
const agent = useMemo(
|
const agent = useMemo(
|
||||||
() => (agents || []).find((a: any) => a.instanceId === instanceId) as any,
|
() => (agents || []).find((a: any) => a.instanceId === instanceId) as any,
|
||||||
|
|||||||
Reference in New Issue
Block a user