Merge branch 'develop' into feat/logs
@ -215,7 +215,7 @@ Please ping us in the [`#contributing`](https://signoz-community.slack.com/archi
|
||||
|
||||
# 4. Contribute to Backend (Query-Service) 🌑
|
||||
|
||||
**Need to Update:** [**https://github.com/SigNoz/signoz/tree/develop/pkg/query-service**](https://github.com/SigNoz/signoz/tree/develop/pkg/query-service)
|
||||
[**https://github.com/SigNoz/signoz/tree/develop/pkg/query-service**](https://github.com/SigNoz/signoz/tree/develop/pkg/query-service)
|
||||
|
||||
## 4.1 To run ClickHouse setup (recommended for local development)
|
||||
|
||||
|
@ -204,9 +204,14 @@ start_docker() {
|
||||
echo "Starting docker service"
|
||||
$sudo_cmd systemctl start docker.service
|
||||
fi
|
||||
# if [[ -z $sudo_cmd ]]; then
|
||||
# docker ps > /dev/null && true
|
||||
# if [[ $? -ne 0 ]]; then
|
||||
# request_sudo
|
||||
# fi
|
||||
# fi
|
||||
if [[ -z $sudo_cmd ]]; then
|
||||
docker ps > /dev/null && true
|
||||
if [[ $? -ne 0 ]]; then
|
||||
if ! docker ps > /dev/null && true; then
|
||||
request_sudo
|
||||
fi
|
||||
fi
|
||||
@ -268,8 +273,12 @@ request_sudo() {
|
||||
if (( $EUID != 0 )); then
|
||||
sudo_cmd="sudo"
|
||||
echo -e "Please enter your sudo password, if prompt."
|
||||
$sudo_cmd -l | grep -e "NOPASSWD: ALL" > /dev/null
|
||||
if [[ $? -ne 0 ]] && ! $sudo_cmd -v; then
|
||||
# $sudo_cmd -l | grep -e "NOPASSWD: ALL" > /dev/null
|
||||
# if [[ $? -ne 0 ]] && ! $sudo_cmd -v; then
|
||||
# echo "Need sudo privileges to proceed with the installation."
|
||||
# exit 1;
|
||||
# fi
|
||||
if ! $sudo_cmd -l | grep -e "NOPASSWD: ALL" > /dev/null && ! $sudo_cmd -v; then
|
||||
echo "Need sudo privileges to proceed with the installation."
|
||||
exit 1;
|
||||
fi
|
||||
@ -303,8 +312,13 @@ echo -e "🌏 Detecting your OS ...\n"
|
||||
check_os
|
||||
|
||||
# Obtain unique installation id
|
||||
sysinfo="$(uname -a)"
|
||||
if [[ $? -ne 0 ]]; then
|
||||
# sysinfo="$(uname -a)"
|
||||
# if [[ $? -ne 0 ]]; then
|
||||
# uuid="$(uuidgen)"
|
||||
# uuid="${uuid:-$(cat /proc/sys/kernel/random/uuid)}"
|
||||
# sysinfo="${uuid:-$(cat /proc/sys/kernel/random/uuid)}"
|
||||
# fi
|
||||
if ! sysinfo="$(uname -a)"; then
|
||||
uuid="$(uuidgen)"
|
||||
uuid="${uuid:-$(cat /proc/sys/kernel/random/uuid)}"
|
||||
sysinfo="${uuid:-$(cat /proc/sys/kernel/random/uuid)}"
|
||||
|
@ -16,6 +16,7 @@
|
||||
"playwright": "NODE_ENV=testing playwright test --config=./playwright.config.ts",
|
||||
"playwright:local:debug": "PWDEBUG=console yarn playwright --headed --browser=chromium",
|
||||
"playwright:codegen:local":"playwright codegen http://localhost:3301",
|
||||
"playwright:codegen:local:auth":"yarn playwright:codegen:local --load-storage=tests/auth.json",
|
||||
"husky:configure": "cd .. && husky install frontend/.husky && cd frontend && chmod ug+x .husky/*",
|
||||
"commitlint": "commitlint --edit $1"
|
||||
},
|
||||
|
@ -14,8 +14,8 @@ const config: PlaywrightTestConfig = {
|
||||
baseURL: process.env.PLAYWRIGHT_TEST_BASE_URL || 'http://localhost:3301',
|
||||
},
|
||||
updateSnapshots: 'all',
|
||||
fullyParallel: false,
|
||||
quiet: true,
|
||||
fullyParallel: !!process.env.CI,
|
||||
quiet: false,
|
||||
testMatch: ['**/*.spec.ts'],
|
||||
reporter: process.env.CI ? 'github' : 'list',
|
||||
};
|
||||
|
@ -66,8 +66,12 @@ function ChartPreview({
|
||||
}),
|
||||
enabled:
|
||||
query != null &&
|
||||
(query.queryType !== EQueryType.PROM ||
|
||||
(query.promQL?.length > 0 && query.promQL[0].query !== '')),
|
||||
((query.queryType === EQueryType.PROM &&
|
||||
query.promQL?.length > 0 &&
|
||||
query.promQL[0].query !== '') ||
|
||||
(query.queryType === EQueryType.QUERY_BUILDER &&
|
||||
query.metricsBuilder?.queryBuilder?.length > 0 &&
|
||||
query.metricsBuilder?.queryBuilder[0].metricName !== '')),
|
||||
});
|
||||
|
||||
const chartDataSet = queryResponse.isError
|
||||
|
@ -83,7 +83,7 @@ function FormAlertRules({
|
||||
|
||||
// staged query is used to display chart preview
|
||||
const [stagedQuery, setStagedQuery] = useState<StagedQuery>();
|
||||
const debouncedStagedQuery = useDebounce(stagedQuery, 500);
|
||||
const debouncedStagedQuery = useDebounce(stagedQuery, 1000);
|
||||
|
||||
// this use effect initiates staged query and
|
||||
// other queries based on server data.
|
||||
@ -177,25 +177,26 @@ function FormAlertRules({
|
||||
return false;
|
||||
}
|
||||
|
||||
Object.keys(metricQueries).forEach((key) => {
|
||||
if (metricQueries[key].metricName === '') {
|
||||
retval = false;
|
||||
notification.error({
|
||||
message: 'Error',
|
||||
description: t('metricname_missing', { where: metricQueries[key].name }),
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
Object.keys(formulaQueries).forEach((key) => {
|
||||
if (formulaQueries[key].expression === '') {
|
||||
retval = false;
|
||||
notification.error({
|
||||
message: 'Error',
|
||||
description: t('expression_missing', formulaQueries[key].name),
|
||||
});
|
||||
}
|
||||
});
|
||||
if (queryCategory === EQueryType.QUERY_BUILDER) {
|
||||
Object.keys(metricQueries).forEach((key) => {
|
||||
if (metricQueries[key].metricName === '') {
|
||||
retval = false;
|
||||
notification.error({
|
||||
message: 'Error',
|
||||
description: t('metricname_missing', { where: metricQueries[key].name }),
|
||||
});
|
||||
}
|
||||
});
|
||||
Object.keys(formulaQueries).forEach((key) => {
|
||||
if (formulaQueries[key].expression === '') {
|
||||
retval = false;
|
||||
notification.error({
|
||||
message: 'Error',
|
||||
description: t('expression_missing', formulaQueries[key].name),
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return retval;
|
||||
}, [t, alertDef, queryCategory, metricQueries, formulaQueries, promQueries]);
|
||||
@ -235,7 +236,7 @@ function FormAlertRules({
|
||||
description:
|
||||
!ruleId || ruleId === 0 ? t('rule_created') : t('rule_edited'),
|
||||
});
|
||||
console.log('invalidting cache');
|
||||
|
||||
// invalidate rule in cache
|
||||
ruleCache.invalidateQueries(['ruleId', ruleId]);
|
||||
|
||||
|
@ -18,4 +18,8 @@ const store = createStore(
|
||||
),
|
||||
);
|
||||
|
||||
if (window !== undefined) {
|
||||
window.store = store;
|
||||
}
|
||||
|
||||
export default store;
|
||||
|
@ -10,7 +10,9 @@ const intitalState: GlobalReducer = {
|
||||
maxTime: Date.now() * 1000000,
|
||||
minTime: (Date.now() - 15 * 60 * 1000) * 1000000,
|
||||
loading: true,
|
||||
selectedTime: getDefaultOption(window.location.pathname),
|
||||
selectedTime: getDefaultOption(
|
||||
typeof window !== 'undefined' ? window?.location?.pathname : '',
|
||||
),
|
||||
};
|
||||
|
||||
const globalTimeReducer = (
|
||||
|
101
frontend/tests/expectionDetails/index.spec.ts
Normal file
@ -0,0 +1,101 @@
|
||||
import { expect, Page, test } from '@playwright/test';
|
||||
import ROUTES from 'constants/routes';
|
||||
|
||||
import allErrorList from '../fixtures/api/allErrors/200.json';
|
||||
import errorDetailSuccess from '../fixtures/api/errorDetails/200.json';
|
||||
import errorDetailNotFound from '../fixtures/api/errorDetails/404.json';
|
||||
import nextPreviousSuccess from '../fixtures/api/getNextPrev/200.json';
|
||||
import { loginApi } from '../fixtures/common';
|
||||
import { JsonApplicationType } from '../fixtures/constant';
|
||||
|
||||
let page: Page;
|
||||
const timestamp = '1657794588955274000';
|
||||
|
||||
test.describe('Expections Details', async () => {
|
||||
test.beforeEach(async ({ baseURL, browser }) => {
|
||||
const context = await browser.newContext({ storageState: 'tests/auth.json' });
|
||||
const newPage = await context.newPage();
|
||||
|
||||
await loginApi(newPage);
|
||||
|
||||
await newPage.goto(`${baseURL}${ROUTES.APPLICATION}`);
|
||||
|
||||
page = newPage;
|
||||
});
|
||||
|
||||
test('Should have not found when api return 404', async () => {
|
||||
await Promise.all([
|
||||
page.route('**/errorFromGroupID**', (route) =>
|
||||
route.fulfill({
|
||||
status: 404,
|
||||
contentType: JsonApplicationType,
|
||||
body: JSON.stringify(errorDetailNotFound),
|
||||
}),
|
||||
),
|
||||
page.route('**/nextPrevErrorIDs**', (route) =>
|
||||
route.fulfill({
|
||||
status: 404,
|
||||
contentType: JsonApplicationType,
|
||||
body: JSON.stringify([]),
|
||||
}),
|
||||
),
|
||||
]);
|
||||
|
||||
await page.goto(
|
||||
`${ROUTES.ERROR_DETAIL}?groupId=${allErrorList[0].groupID}×tamp=${timestamp}`,
|
||||
{
|
||||
waitUntil: 'networkidle',
|
||||
},
|
||||
);
|
||||
|
||||
const NoDataLocator = page.locator('text=Not Found');
|
||||
const isVisible = await NoDataLocator.isVisible();
|
||||
const text = await NoDataLocator.textContent();
|
||||
|
||||
expect(isVisible).toBe(true);
|
||||
expect(text).toBe('Not Found');
|
||||
expect(await page.screenshot()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('Render Success Data when 200 from details page', async () => {
|
||||
await Promise.all([
|
||||
page.route('**/errorFromGroupID**', (route) =>
|
||||
route.fulfill({
|
||||
status: 200,
|
||||
contentType: JsonApplicationType,
|
||||
body: JSON.stringify(errorDetailSuccess),
|
||||
}),
|
||||
),
|
||||
page.route('**/nextPrevErrorIDs**', (route) =>
|
||||
route.fulfill({
|
||||
status: 200,
|
||||
contentType: JsonApplicationType,
|
||||
body: JSON.stringify(nextPreviousSuccess),
|
||||
}),
|
||||
),
|
||||
]);
|
||||
|
||||
await page.goto(
|
||||
`${ROUTES.ERROR_DETAIL}?groupId=${allErrorList[0].groupID}×tamp=${timestamp}`,
|
||||
{
|
||||
waitUntil: 'networkidle',
|
||||
},
|
||||
);
|
||||
|
||||
const traceDetailButton = page.locator('text=See the error in trace graph');
|
||||
const olderButton = page.locator('text=Older');
|
||||
const newerButton = page.locator(`text=Newer`);
|
||||
|
||||
expect(await traceDetailButton.isVisible()).toBe(true);
|
||||
expect(await olderButton.isVisible()).toBe(true);
|
||||
expect(await newerButton.isVisible()).toBe(true);
|
||||
|
||||
expect(await traceDetailButton.textContent()).toBe(
|
||||
'See the error in trace graph',
|
||||
);
|
||||
expect(await olderButton.textContent()).toBe('Older');
|
||||
expect(await newerButton.textContent()).toBe('Newer');
|
||||
|
||||
expect(await page.screenshot()).toMatchSnapshot();
|
||||
});
|
||||
});
|
After Width: | Height: | Size: 183 KiB |
After Width: | Height: | Size: 39 KiB |
148
frontend/tests/expections/index.spec.ts
Normal file
@ -0,0 +1,148 @@
|
||||
import { expect, Page, test } from '@playwright/test';
|
||||
import ROUTES from 'constants/routes';
|
||||
|
||||
import successAllErrors from '../fixtures/api/allErrors/200.json';
|
||||
import { loginApi } from '../fixtures/common';
|
||||
import { JsonApplicationType } from '../fixtures/constant';
|
||||
|
||||
const noDataTableData = async (page: Page): Promise<void> => {
|
||||
const text = page.locator('text=No Data');
|
||||
|
||||
expect(text).toBeVisible();
|
||||
expect(text).toHaveText('No Data');
|
||||
|
||||
const textType = [
|
||||
'Exception Type',
|
||||
'Error Message',
|
||||
'Last Seen',
|
||||
'First Seen',
|
||||
'Application',
|
||||
];
|
||||
|
||||
textType.forEach(async (text) => {
|
||||
const textLocator = page.locator(`text=${text}`);
|
||||
|
||||
const textContent = await textLocator.textContent();
|
||||
|
||||
expect(textContent).toBe(text);
|
||||
expect(textLocator).not.toBeNull();
|
||||
|
||||
expect(textLocator).toBeVisible();
|
||||
await expect(textLocator).toHaveText(`${text}`);
|
||||
});
|
||||
};
|
||||
|
||||
let page: Page;
|
||||
|
||||
test.describe('Expections page', async () => {
|
||||
test.beforeEach(async ({ baseURL, browser }) => {
|
||||
const context = await browser.newContext({ storageState: 'tests/auth.json' });
|
||||
const newPage = await context.newPage();
|
||||
|
||||
await loginApi(newPage);
|
||||
|
||||
await newPage.goto(`${baseURL}${ROUTES.APPLICATION}`);
|
||||
|
||||
page = newPage;
|
||||
});
|
||||
|
||||
test('Should have a valid route', async () => {
|
||||
await page.goto(ROUTES.ALL_ERROR);
|
||||
|
||||
await expect(page).toHaveURL(ROUTES.ALL_ERROR);
|
||||
expect(await page.screenshot()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('Should have a valid Breadcrumbs', async () => {
|
||||
await page.goto(ROUTES.ALL_ERROR, {
|
||||
waitUntil: 'networkidle',
|
||||
});
|
||||
|
||||
const expectionsLocator = page.locator('a:has-text("Exceptions")');
|
||||
|
||||
await expect(expectionsLocator).toBeVisible();
|
||||
await expect(expectionsLocator).toHaveText('Exceptions');
|
||||
await expect(expectionsLocator).toHaveAttribute('href', ROUTES.ALL_ERROR);
|
||||
expect(await page.screenshot()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('Should render the page with 404 status', async () => {
|
||||
await page.route('**listErrors', (route) =>
|
||||
route.fulfill({
|
||||
status: 404,
|
||||
contentType: JsonApplicationType,
|
||||
body: JSON.stringify([]),
|
||||
}),
|
||||
);
|
||||
|
||||
await page.goto(ROUTES.ALL_ERROR, {
|
||||
waitUntil: 'networkidle',
|
||||
});
|
||||
|
||||
await noDataTableData(page);
|
||||
expect(await page.screenshot()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('Should render the page with 500 status in antd notification with no data antd table', async () => {
|
||||
await page.route(`**/listErrors**`, (route) =>
|
||||
route.fulfill({
|
||||
status: 500,
|
||||
contentType: JsonApplicationType,
|
||||
body: JSON.stringify([]),
|
||||
}),
|
||||
);
|
||||
|
||||
await page.goto(ROUTES.ALL_ERROR, {
|
||||
waitUntil: 'networkidle',
|
||||
});
|
||||
|
||||
const text = 'Something went wrong';
|
||||
|
||||
const el = page.locator(`text=${text}`);
|
||||
|
||||
expect(el).toBeVisible();
|
||||
expect(el).toHaveText(`${text}`);
|
||||
expect(await el.getAttribute('disabled')).toBe(null);
|
||||
|
||||
await noDataTableData(page);
|
||||
expect(await page.screenshot()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('Should render data in antd table', async () => {
|
||||
await Promise.all([
|
||||
page.route(`**/listErrors**`, (route) =>
|
||||
route.fulfill({
|
||||
status: 200,
|
||||
contentType: JsonApplicationType,
|
||||
body: JSON.stringify(successAllErrors),
|
||||
}),
|
||||
),
|
||||
|
||||
page.route('**/countErrors**', (route) =>
|
||||
route.fulfill({
|
||||
status: 200,
|
||||
contentType: JsonApplicationType,
|
||||
body: JSON.stringify(200),
|
||||
}),
|
||||
),
|
||||
]);
|
||||
|
||||
await page.goto(ROUTES.ALL_ERROR, {
|
||||
waitUntil: 'networkidle',
|
||||
});
|
||||
|
||||
await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight));
|
||||
|
||||
const expectionType = page.locator(
|
||||
`td:has-text("${successAllErrors[1].exceptionType}")`,
|
||||
);
|
||||
|
||||
expect(expectionType).toBeVisible();
|
||||
|
||||
const second = page.locator('li > a:has-text("2") >> nth=0');
|
||||
const isVisisble = await second.isVisible();
|
||||
|
||||
expect(isVisisble).toBe(true);
|
||||
expect(await page.screenshot()).toMatchSnapshot();
|
||||
});
|
||||
});
|
After Width: | Height: | Size: 60 KiB |
After Width: | Height: | Size: 42 KiB |
After Width: | Height: | Size: 115 KiB |
After Width: | Height: | Size: 60 KiB |
After Width: | Height: | Size: 58 KiB |
92
frontend/tests/fixtures/api/allErrors/200.json
vendored
Normal file
@ -0,0 +1,92 @@
|
||||
[
|
||||
{
|
||||
"exceptionType": "ConnectionError",
|
||||
"exceptionMessage": "HTTPSConnectionPool(host='run.mocekdy.io', port=443): Max retries exceeded with url: /v3/1cwb67153-a6ac-4aae-aca6-273ed68b5d9e (Caused by NewConnectionError('\u003curllib3.connection.HTTPSConnection object at 0x108ce9c10\u003e: Failed to establish a new connection: [Errno 8] nodename nor servname provided, or not known'))",
|
||||
"exceptionCount": 2,
|
||||
"lastSeen": "2022-07-14T10:29:48.955274Z",
|
||||
"firstSeen": "2022-07-14T10:29:48.950721Z",
|
||||
"serviceName": "1rfflaskAp",
|
||||
"groupID": "e24d35bda98c5499a5c8df3ba61b0238"
|
||||
},
|
||||
{
|
||||
"exceptionType": "NameError",
|
||||
"exceptionMessage": "name 'listf' is not defined",
|
||||
"exceptionCount": 8,
|
||||
"lastSeen": "2022-07-14T10:30:42.411035Z",
|
||||
"firstSeen": "2022-07-14T10:29:45.426784Z",
|
||||
"serviceName": "1rfflaskAp",
|
||||
"groupID": "efc46adcd5e87b65f8f244cba683b265"
|
||||
},
|
||||
{
|
||||
"exceptionType": "ZeroDivisionError",
|
||||
"exceptionMessage": "division by zero",
|
||||
"exceptionCount": 1,
|
||||
"lastSeen": "2022-07-14T10:29:54.195996Z",
|
||||
"firstSeen": "2022-07-14T10:29:54.195996Z",
|
||||
"serviceName": "1rfflaskAp",
|
||||
"groupID": "a49058b540eef9aefe159d84f1a2b6df"
|
||||
},
|
||||
{
|
||||
"exceptionType": "MaxRetryError",
|
||||
"exceptionMessage": "HTTPSConnectionPool(host='rufn.fmoceky.io', port=443): Max retries exceeded with url: /v3/b851a5c6-ab54-495a-be04-69834ae0d2a7 (Caused by NewConnectionError('\u003curllib3.connection.HTTPSConnection object at 0x108ec2640\u003e: Failed to establish a new connection: [Errno 8] nodename nor servname provided, or not known'))",
|
||||
"exceptionCount": 1,
|
||||
"lastSeen": "2022-07-14T10:29:49.471402Z",
|
||||
"firstSeen": "2022-07-14T10:29:49.471402Z",
|
||||
"serviceName": "1rfflaskAp",
|
||||
"groupID": "e59d39239f4d48842d83e3cc4cf53249"
|
||||
},
|
||||
{
|
||||
"exceptionType": "MaxRetryError",
|
||||
"exceptionMessage": "HTTPSConnectionPool(host='run.mocekdy.io', port=443): Max retries exceeded with url: /v3/1cwb67153-a6ac-4aae-aca6-273ed68b5d9e (Caused by NewConnectionError('\u003curllib3.connection.HTTPSConnection object at 0x108ce9c10\u003e: Failed to establish a new connection: [Errno 8] nodename nor servname provided, or not known'))",
|
||||
"exceptionCount": 1,
|
||||
"lastSeen": "2022-07-14T10:29:48.947579Z",
|
||||
"firstSeen": "2022-07-14T10:29:48.947579Z",
|
||||
"serviceName": "1rfflaskAp",
|
||||
"groupID": "14d18a6fb1cd3f541de1566530e75486"
|
||||
},
|
||||
{
|
||||
"exceptionType": "ConnectionError",
|
||||
"exceptionMessage": "HTTPSConnectionPool(host='rufn.fmoceky.io', port=443): Max retries exceeded with url: /v3/b851a5c6-ab54-495a-be04-69834ae0d2a7 (Caused by NewConnectionError('\u003curllib3.connection.HTTPSConnection object at 0x108ec2640\u003e: Failed to establish a new connection: [Errno 8] nodename nor servname provided, or not known'))",
|
||||
"exceptionCount": 2,
|
||||
"lastSeen": "2022-07-14T10:29:49.476718Z",
|
||||
"firstSeen": "2022-07-14T10:29:49.472271Z",
|
||||
"serviceName": "1rfflaskAp",
|
||||
"groupID": "bf6d88d10397ca3194b96a10f4719031"
|
||||
},
|
||||
{
|
||||
"exceptionType": "github.com/gin-gonic/gin.Error",
|
||||
"exceptionMessage": "Sample Error",
|
||||
"exceptionCount": 6,
|
||||
"lastSeen": "2022-07-15T18:55:32.3538096Z",
|
||||
"firstSeen": "2022-07-14T14:47:19.874387Z",
|
||||
"serviceName": "goApp",
|
||||
"groupID": "b4fd099280072d45318e1523d82aa9c1"
|
||||
},
|
||||
{
|
||||
"exceptionType": "MaxRetryError",
|
||||
"exceptionMessage": "HTTPSConnectionPool(host='rufn.fmoceky.io', port=443): Max retries exceeded with url: /v3/b851a5c6-ab54-495a-be04-69834ae0d2a7 (Caused by NewConnectionError('\u003curllib3.connection.HTTPSConnection object at 0x10801b490\u003e: Failed to establish a new connection: [Errno 8] nodename nor servname provided, or not known'))",
|
||||
"exceptionCount": 1,
|
||||
"lastSeen": "2022-07-14T11:07:06.560593Z",
|
||||
"firstSeen": "2022-07-14T11:07:06.560593Z",
|
||||
"serviceName": "samplFlaskApp",
|
||||
"groupID": "1945671c945b10641e73b0fe28c4d486"
|
||||
},
|
||||
{
|
||||
"exceptionType": "ConnectionError",
|
||||
"exceptionMessage": "HTTPSConnectionPool(host='rufn.fmoceky.io', port=443): Max retries exceeded with url: /v3/b851a5c6-ab54-495a-be04-69834ae0d2a7 (Caused by NewConnectionError('\u003curllib3.connection.HTTPSConnection object at 0x10801b490\u003e: Failed to establish a new connection: [Errno 8] nodename nor servname provided, or not known'))",
|
||||
"exceptionCount": 2,
|
||||
"lastSeen": "2022-07-14T11:07:06.56493Z",
|
||||
"firstSeen": "2022-07-14T11:07:06.561074Z",
|
||||
"serviceName": "samplFlaskApp",
|
||||
"groupID": "5bea5295cac187404005f9c96e71aa53"
|
||||
},
|
||||
{
|
||||
"exceptionType": "ConnectionError",
|
||||
"exceptionMessage": "HTTPSConnectionPool(host='rufn.fmoceky.io', port=443): Max retries exceeded with url: /v3/b851a5c6-ab54-495a-be04-69834ae0d2a7 (Caused by NewConnectionError('\u003curllib3.connection.HTTPSConnection object at 0x108031820\u003e: Failed to establish a new connection: [Errno 8] nodename nor servname provided, or not known'))",
|
||||
"exceptionCount": 2,
|
||||
"lastSeen": "2022-07-14T11:07:06.363977Z",
|
||||
"firstSeen": "2022-07-14T11:07:06.361163Z",
|
||||
"serviceName": "samplFlaskApp",
|
||||
"groupID": "52a1fbe033453d806c0f24ba39168a78"
|
||||
}
|
||||
]
|
12
frontend/tests/fixtures/api/errorDetails/200.json
vendored
Normal file
5
frontend/tests/fixtures/api/errorDetails/404.json
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"error": "Error/Exception not found",
|
||||
"errorType": "not_found",
|
||||
"status": "error"
|
||||
}
|
7
frontend/tests/fixtures/api/getNextPrev/200.json
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"nextErrorID": "",
|
||||
"nextTimestamp": "0001-01-01T00:00:00Z",
|
||||
"prevErrorID": "217133e5f7df429abd31b507859ea513",
|
||||
"prevTimestamp": "2022-07-14T10:29:48.950721Z",
|
||||
"groupID": "e24d35bda98c5499a5c8df3ba61b0238"
|
||||
}
|
2
frontend/tests/fixtures/constant.ts
vendored
@ -6,3 +6,5 @@ export const validPassword = 'SamplePassword98@@';
|
||||
|
||||
export const getStartedButtonSelector = 'button[data-attr="signup"]';
|
||||
export const confirmPasswordSelector = '#password-confirm-error';
|
||||
|
||||
export const JsonApplicationType = 'application/json';
|
||||
|
@ -24,5 +24,6 @@ test.describe('Version API fail while loading login page', async () => {
|
||||
expect(el).toBeVisible();
|
||||
expect(el).toHaveText(`${text}`);
|
||||
expect(await el.getAttribute('disabled')).toBe(null);
|
||||
expect(await page.screenshot()).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
After Width: | Height: | Size: 7.9 KiB |
@ -45,5 +45,6 @@ test.describe('Login Page', () => {
|
||||
element.isVisible();
|
||||
const text = await element.innerText();
|
||||
expect(text).toBe(`SigNoz ${version}`);
|
||||
expect(await page.screenshot()).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
After Width: | Height: | Size: 46 KiB |
@ -16,7 +16,17 @@ test.describe('Service Page', () => {
|
||||
|
||||
page = newPage;
|
||||
});
|
||||
|
||||
test('Serice Page is rendered', async ({ baseURL }) => {
|
||||
await expect(page).toHaveURL(`${baseURL}${ROUTES.APPLICATION}`);
|
||||
expect(await page.screenshot()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('Logged In must be true', async () => {
|
||||
const { app } = await page.evaluate(() => window.store.getState());
|
||||
|
||||
const { isLoggedIn } = app;
|
||||
|
||||
expect(isLoggedIn).toBe(true);
|
||||
});
|
||||
});
|
||||
|
After Width: | Height: | Size: 40 KiB |
@ -77,6 +77,7 @@ test.describe('Sign Up Page', () => {
|
||||
await buttonSignupButton.click();
|
||||
|
||||
expect(page).toHaveURL(`${baseURL}${ROUTES.SIGN_UP}`);
|
||||
expect(await page.screenshot()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('Invite link validation', async ({ baseURL, page }) => {
|
||||
@ -87,6 +88,7 @@ test.describe('Sign Up Page', () => {
|
||||
const messageText = await page.locator(`text=${message}`).innerText();
|
||||
|
||||
expect(messageText).toBe(message);
|
||||
expect(await page.screenshot()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('User Sign up with valid details', async ({ baseURL, page, context }) => {
|
||||
@ -125,6 +127,7 @@ test.describe('Sign Up Page', () => {
|
||||
await context.storageState({
|
||||
path: 'tests/auth.json',
|
||||
});
|
||||
expect(await page.screenshot()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('Empty name with valid details', async ({ baseURL, page }) => {
|
||||
@ -142,6 +145,7 @@ test.describe('Sign Up Page', () => {
|
||||
const gettingStartedButton = page.locator(getStartedButtonSelector);
|
||||
|
||||
expect(await gettingStartedButton.isDisabled()).toBe(true);
|
||||
expect(await page.screenshot()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('Empty Company name with valid details', async ({ baseURL, page }) => {
|
||||
@ -159,6 +163,7 @@ test.describe('Sign Up Page', () => {
|
||||
const gettingStartedButton = page.locator(getStartedButtonSelector);
|
||||
|
||||
expect(await gettingStartedButton.isDisabled()).toBe(true);
|
||||
expect(await page.screenshot()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('Empty Email with valid details', async ({ baseURL, page }) => {
|
||||
@ -176,6 +181,7 @@ test.describe('Sign Up Page', () => {
|
||||
const gettingStartedButton = page.locator(getStartedButtonSelector);
|
||||
|
||||
expect(await gettingStartedButton.isDisabled()).toBe(true);
|
||||
expect(await page.screenshot()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('Empty Password and confirm password with valid details', async ({
|
||||
@ -200,6 +206,7 @@ test.describe('Sign Up Page', () => {
|
||||
// password validation message is not present
|
||||
const locator = await page.locator(confirmPasswordSelector).isVisible();
|
||||
expect(locator).toBe(false);
|
||||
expect(await page.screenshot()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('Miss Match Password and confirm password with valid details', async ({
|
||||
@ -220,5 +227,6 @@ test.describe('Sign Up Page', () => {
|
||||
// password validation message is not present
|
||||
const locator = await page.locator(confirmPasswordSelector).isVisible();
|
||||
expect(locator).toBe(true);
|
||||
expect(await page.screenshot()).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
After Width: | Height: | Size: 70 KiB |
After Width: | Height: | Size: 70 KiB |
After Width: | Height: | Size: 69 KiB |
After Width: | Height: | Size: 70 KiB |
After Width: | Height: | Size: 66 KiB |
After Width: | Height: | Size: 72 KiB |
After Width: | Height: | Size: 54 KiB |
After Width: | Height: | Size: 70 KiB |
@ -6,8 +6,37 @@ Query service is the interface between frontend and databases. It is written in
|
||||
- parse response from databases and handle error if any
|
||||
- clickhouse response in the format accepted by Frontend
|
||||
|
||||
# Complete the clickhouse setup locally.
|
||||
https://github.com/SigNoz/signoz/blob/main/CONTRIBUTING.md#to-run-clickhouse-setup-recommended-for-local-development
|
||||
|
||||
- Comment out the query-service and the frontend section in `signoz/deploy/docker/clickhouse-setup/docker-compose.yaml`
|
||||
- Change the alertmanager section in `signoz/deploy/docker/clickhouse-setup/docker-compose.yaml` as follows:
|
||||
```console
|
||||
alertmanager:
|
||||
image: signoz/alertmanager:0.23.0-0.1
|
||||
volumes:
|
||||
- ./data/alertmanager:/data
|
||||
expose:
|
||||
- "9093"
|
||||
ports:
|
||||
- "8080:9093"
|
||||
# depends_on:
|
||||
# query-service:
|
||||
# condition: service_healthy
|
||||
restart: on-failure
|
||||
command:
|
||||
- --queryService.url=http://172.17.0.1:8085
|
||||
- --storage.path=/data
|
||||
```
|
||||
- Run the following:
|
||||
```console
|
||||
cd signoz/
|
||||
If you are using x86_64 processors (All Intel/AMD processors) run sudo make run-x86
|
||||
If you are on arm64 processors (Apple M1 Macs) run sudo make run-arm
|
||||
```
|
||||
|
||||
#### Backend Configuration
|
||||
|
||||
#### Configuration
|
||||
- Open ./constants/constants.go
|
||||
- Replace ```const RELATIONAL_DATASOURCE_PATH = "/var/lib/signoz/signoz.db"``` \
|
||||
with ```const RELATIONAL_DATASOURCE_PATH = "./signoz.db".```
|
||||
@ -15,8 +44,9 @@ Query service is the interface between frontend and databases. It is written in
|
||||
- Query Service needs below `env` variables to run:
|
||||
|
||||
```
|
||||
ClickHouseUrl=tcp://localhost:9001
|
||||
STORAGE=clickhouse
|
||||
export ClickHouseUrl=tcp://localhost:9001
|
||||
export STORAGE=clickhouse
|
||||
export ALERTMANAGER_API_PREFIX=http://localhost:9093/api/
|
||||
```
|
||||
|
||||
<!-- The above values are the default ones used by SigNoz and are kept at `deploy/kubernetes/platform/signoz-charts/query-service/values.yaml` -->
|
||||
@ -28,5 +58,24 @@ go build -o build/query-service main.go
|
||||
ClickHouseUrl=tcp://localhost:9001 STORAGE=clickhouse build/query-service
|
||||
```
|
||||
|
||||
# Frontend Configuration for local query-service.
|
||||
|
||||
- Set the following environment variables
|
||||
```console
|
||||
export FRONTEND_API_ENDPOINT=http://localhost:8080
|
||||
```
|
||||
|
||||
- Run the following
|
||||
```console
|
||||
cd signoz\frontend\
|
||||
yarn install
|
||||
yarn dev
|
||||
```
|
||||
|
||||
## Note:
|
||||
If you use go version 1.18 for development and contributions, then please checkout the following issue.
|
||||
https://github.com/SigNoz/signoz/issues/1371
|
||||
|
||||
|
||||
#### Docker Images
|
||||
The docker images of query-service is available at https://hub.docker.com/r/signoz/query-service
|
||||
|