Merge branch 'develop' into feat/logs

This commit is contained in:
Srikanth Chekuri 2022-07-26 11:55:18 +05:30 committed by GitHub
commit a23788852a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
38 changed files with 498 additions and 36 deletions

View File

@ -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)

View File

@ -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)}"

View File

@ -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"
},

View File

@ -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',
};

View File

@ -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

View File

@ -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]);

View File

@ -18,4 +18,8 @@ const store = createStore(
),
);
if (window !== undefined) {
window.store = store;
}
export default store;

View File

@ -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 = (

View 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}&timestamp=${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}&timestamp=${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();
});
});

View 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();
});
});

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

View 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"
}
]

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,5 @@
{
"error": "Error/Exception not found",
"errorType": "not_found",
"status": "error"
}

View File

@ -0,0 +1,7 @@
{
"nextErrorID": "",
"nextTimestamp": "0001-01-01T00:00:00Z",
"prevErrorID": "217133e5f7df429abd31b507859ea513",
"prevTimestamp": "2022-07-14T10:29:48.950721Z",
"groupID": "e24d35bda98c5499a5c8df3ba61b0238"
}

View File

@ -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';

View File

@ -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();
});
});

View File

@ -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();
});
});

View File

@ -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);
});
});

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

View File

@ -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();
});
});

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

View File

@ -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