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
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,41 @@ export const observability = createQueryKeys('observability', {
return response.data.metrics && (JSON.parse(response.data.metrics).data[0] as string)
},
}),
httpRouteName: ({
clusterId,
serviceId,
startDate,
endDate,
}: {
clusterId: string
serviceId: string
startDate: string
endDate: string
}) => ({
queryKey: ['httpPortName', clusterId, serviceId],
async queryFn() {
const endpoint = `api/v1/label/httproute_name/values?match[]=kube_httproute_labels{qovery_com_associated_service_id="${serviceId}"}`
const response = await clusterApi.getClusterMetrics(
clusterId,
endpoint,
endpoint,
'',
startDate,
endDate,
undefined,
undefined,
undefined,
'True',
'True',
undefined,
'prometheus',
'false',
'service_overview',
'httpRouteName'
)
return response.data.metrics && (JSON.parse(response.data.metrics).data[0] as string)
},
}),
hpaName: ({
clusterId,
serviceId,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { useQuery } from '@tanstack/react-query'
import { observability } from '@qovery/domains/observability/data-access'

export interface UseHttpRouteNameProps {
clusterId: string
serviceId: string
startDate: string
endDate: string
enabled?: boolean
}

// Retrieves the http route name associated with a specific service (http managed by envoy)
export function useHttpRouteName({ clusterId, serviceId, enabled = true, startDate, endDate }: UseHttpRouteNameProps) {
return useQuery({
...observability.httpRouteName({ clusterId, serviceId, startDate, endDate }),
enabled: enabled && Boolean(clusterId && serviceId),
})
}

export default useHttpRouteName
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ interface UseMetricsProps {
overriddenMaxPoints?: number
boardShortName: 'service_overview' | 'rds_overview'
metricShortName: string
enabled?: boolean
}

function useLiveUpdateSetting(): boolean {
Expand All @@ -42,6 +43,7 @@ export function useMetrics({
overriddenMaxPoints,
boardShortName,
metricShortName,
enabled = true,
}: UseMetricsProps) {
// Get context and live update setting, but allow override
const context = useDashboardContext()
Expand Down Expand Up @@ -87,6 +89,7 @@ export function useMetrics({
traceId: context.traceId,
alignedRange,
}),
enabled,
keepPreviousData: true,
refetchInterval: finalLiveUpdateEnabled ? 30_000 : false, // Refetch every 30 seconds only if live update is enabled
refetchIntervalInBackground: finalLiveUpdateEnabled,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,15 @@ describe('CardHTTPErrors', () => {
clusterId: 'test-cluster-id',
containerName: 'test-container-name',
ingressName: 'test-ingress-name',
httpRouteName: 'test-httproute-name',
}

beforeEach(() => {
jest.clearAllMocks()
})

it('should render successfully with loading state', () => {
// Mock all 4 calls (nginx error, nginx total, envoy error, envoy total) as loading
useInstantMetrics.mockReturnValue(createMockUseInstantMetricsReturn(undefined, true))

const { baseElement } = renderWithProviders(
Expand All @@ -52,6 +54,7 @@ describe('CardHTTPErrors', () => {

it('should render with no errors (GREEN status)', () => {
useInstantMetrics
// NGINX error requests
.mockReturnValueOnce(
createMockUseInstantMetricsReturn({
data: {
Expand All @@ -63,6 +66,31 @@ describe('CardHTTPErrors', () => {
},
})
)
// NGINX total requests
.mockReturnValueOnce(
createMockUseInstantMetricsReturn({
data: {
result: [
{
value: [1234567890, '100'],
},
],
},
})
)
// ENVOY error requests
.mockReturnValueOnce(
createMockUseInstantMetricsReturn({
data: {
result: [
{
value: [1234567890, '0'],
},
],
},
})
)
// ENVOY total requests
.mockReturnValueOnce(
createMockUseInstantMetricsReturn({
data: {
Expand All @@ -87,6 +115,7 @@ describe('CardHTTPErrors', () => {

it('should render with errors (RED status) and show modal link', () => {
useInstantMetrics
// NGINX error requests
.mockReturnValueOnce(
createMockUseInstantMetricsReturn({
data: {
Expand All @@ -98,6 +127,7 @@ describe('CardHTTPErrors', () => {
},
})
)
// NGINX total requests
.mockReturnValueOnce(
createMockUseInstantMetricsReturn({
data: {
Expand All @@ -109,6 +139,30 @@ describe('CardHTTPErrors', () => {
},
})
)
// ENVOY error requests
.mockReturnValueOnce(
createMockUseInstantMetricsReturn({
data: {
result: [
{
value: [1234567890, '0'],
},
],
},
})
)
// ENVOY total requests
.mockReturnValueOnce(
createMockUseInstantMetricsReturn({
data: {
result: [
{
value: [1234567890, '0'],
},
],
},
})
)

renderWithProviders(
<DashboardProvider>
Expand All @@ -125,13 +179,31 @@ describe('CardHTTPErrors', () => {

it('should handle empty metrics data', () => {
useInstantMetrics
// NGINX error requests
.mockReturnValueOnce(
createMockUseInstantMetricsReturn({
data: {
result: [],
},
})
)
// NGINX total requests
.mockReturnValueOnce(
createMockUseInstantMetricsReturn({
data: {
result: [],
},
})
)
// ENVOY error requests
.mockReturnValueOnce(
createMockUseInstantMetricsReturn({
data: {
result: [],
},
})
)
// ENVOY total requests
.mockReturnValueOnce(
createMockUseInstantMetricsReturn({
data: {
Expand All @@ -151,7 +223,13 @@ describe('CardHTTPErrors', () => {

it('should handle undefined metrics data', () => {
useInstantMetrics
// NGINX error requests
.mockReturnValueOnce(createMockUseInstantMetricsReturn())
// NGINX total requests
.mockReturnValueOnce(createMockUseInstantMetricsReturn())
// ENVOY error requests
.mockReturnValueOnce(createMockUseInstantMetricsReturn())
// ENVOY total requests
.mockReturnValueOnce(createMockUseInstantMetricsReturn())

renderWithProviders(
Expand All @@ -167,7 +245,9 @@ describe('CardHTTPErrors', () => {
let callCount = 0
useInstantMetrics.mockImplementation(() => {
callCount++
// Calls: 1=nginx errors, 2=nginx total, 3=envoy errors, 4=envoy total
if (callCount === 1) {
// NGINX error requests
return createMockUseInstantMetricsReturn({
data: {
result: [
Expand All @@ -177,7 +257,8 @@ describe('CardHTTPErrors', () => {
],
},
})
} else {
} else if (callCount === 2) {
// NGINX total requests
return createMockUseInstantMetricsReturn({
data: {
result: [
Expand All @@ -187,6 +268,28 @@ describe('CardHTTPErrors', () => {
],
},
})
} else if (callCount === 3) {
// ENVOY error requests
return createMockUseInstantMetricsReturn({
data: {
result: [
{
value: [1234567890, '0'],
},
],
},
})
} else {
// ENVOY total requests
return createMockUseInstantMetricsReturn({
data: {
result: [
{
value: [1234567890, '0'],
},
],
},
})
}
})

Expand All @@ -209,7 +312,13 @@ describe('CardHTTPErrors', () => {

it('should call useInstantMetrics with correct parameters', () => {
useInstantMetrics
// NGINX error requests
.mockReturnValueOnce(createMockUseInstantMetricsReturn())
// NGINX total requests
.mockReturnValueOnce(createMockUseInstantMetricsReturn())
// ENVOY error requests
.mockReturnValueOnce(createMockUseInstantMetricsReturn())
// ENVOY total requests
.mockReturnValueOnce(createMockUseInstantMetricsReturn())

renderWithProviders(
Expand All @@ -218,7 +327,10 @@ describe('CardHTTPErrors', () => {
</DashboardProvider>
)

expect(useInstantMetrics).toHaveBeenCalledTimes(2)
// Now called 4 times: nginx errors, nginx total, envoy errors, envoy total
expect(useInstantMetrics).toHaveBeenCalledTimes(4)

// Check nginx calls
expect(useInstantMetrics).toHaveBeenCalledWith({
clusterId: 'test-cluster-id',
query: expect.stringContaining('nginx:req_inc:5m'),
Expand All @@ -230,10 +342,15 @@ describe('CardHTTPErrors', () => {

const calledQuery = useInstantMetrics.mock.calls[0][0].query
expect(calledQuery).toContain('test-ingress-name')

// Check envoy calls
const envoyQuery = useInstantMetrics.mock.calls[2][0].query
expect(envoyQuery).toContain('test-httproute-name')
})

it('should not show modal link when there are no errors', () => {
useInstantMetrics
// NGINX error requests
.mockReturnValueOnce(
createMockUseInstantMetricsReturn({
data: {
Expand All @@ -245,6 +362,7 @@ describe('CardHTTPErrors', () => {
},
})
)
// NGINX total requests
.mockReturnValueOnce(
createMockUseInstantMetricsReturn({
data: {
Expand All @@ -256,6 +374,30 @@ describe('CardHTTPErrors', () => {
},
})
)
// ENVOY error requests
.mockReturnValueOnce(
createMockUseInstantMetricsReturn({
data: {
result: [
{
value: [1234567890, '0'],
},
],
},
})
)
// ENVOY total requests
.mockReturnValueOnce(
createMockUseInstantMetricsReturn({
data: {
result: [
{
value: [1234567890, '0'],
},
],
},
})
)

renderWithProviders(
<DashboardProvider>
Expand Down
Loading